From 6af99f3a099a7192c1f4864d5e9472cb69726060 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 11 Jul 2012 17:51:27 +0100 Subject: [PATCH 001/315] Development snapshot: Rewrote crtpt class as Util, Hooks, and Crypt Switched blowfish for openssl with AES Added setup() method for creating user keys and directory structure Many other changes complete and in progress --- apps/files_encryption/hooks/hooks.php | 50 ++++ apps/files_encryption/lib/crypt.php | 352 ++++++++++++++------------ apps/files_encryption/lib/proxy.php | 79 ++++-- apps/files_encryption/lib/util.php | 133 ++++++++++ 4 files changed, 433 insertions(+), 181 deletions(-) create mode 100644 apps/files_encryption/hooks/hooks.php create mode 100644 apps/files_encryption/lib/util.php diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php new file mode 100644 index 0000000000..89d526b704 --- /dev/null +++ b/apps/files_encryption/hooks/hooks.php @@ -0,0 +1,50 @@ +. + * + */ + +namespace OCA_Encryption; + +/** + * Class for hook specific logic + */ + +class Hooks { + + public static function login( $params ){ + + $view = new \OC_FilesystemView( '/' . $params['uid'] ); + + $storage = new Storage( $view ); + + if ( !$storage->ready() ) { + + return $storage->setup( $params['password'] ); + + } else { + + return true; + + } + } + +} + +?> \ No newline at end of file diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 849e88ee0b..7763f6bea5 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -2,8 +2,10 @@ /** * ownCloud * - * @author Frank Karlitschek - * @copyright 2012 Frank Karlitschek frank@owncloud.org + * @author Sam Tuke, Frank Karlitschek, Robin Appelman + * @copyright 2012 Sam Tuke samtuke@owncloud.com, + * Robin Appelman icewind@owncloud.com, Frank Karlitschek + * frank@owncloud.org * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -20,79 +22,207 @@ * */ - - -// Todo: -// - Crypt/decrypt button in the userinterface -// - Setting if crypto should be on by default -// - Add a setting "Don´t encrypt files larger than xx because of performance reasons" -// - Transparent decrypt/encrypt in filesystem.php. Autodetect if a file is encrypted (.encrypted extension) -// - Don't use a password directly as encryption key. but a key which is stored on the server and encrypted with the user password. -> password change faster -// - IMPORTANT! Check if the block lenght of the encrypted data stays the same - - -require_once('Crypt_Blowfish/Blowfish.php'); +namespace OCA_Encryption; /** - * This class is for crypting and decrypting + * Class for common cryptography functionality */ -class OC_Crypt { - static private $bf = null; - public static function loginListener($params){ - self::init($params['uid'],$params['password']); +class Crypt { + + /** + * @brief Create a new encryption keypair + * @return array publicKey, privatekey + */ + public static function createKeypair() { + + $res = openssl_pkey_new(); + + // Get private key + openssl_pkey_export( $res, $privateKey ); + + // Get public key + $publicKey = openssl_pkey_get_details( $res ); + + $publicKey = $publicKey['key']; + + return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) ); + } + + /** + * @brief Symmetrically encrypt a file + * @returns encrypted file + */ + public static function encrypt( $plainContent, $iv, $passphrase = '' ) { + + # TODO: Move these methods into a separate public class for app developers + + $iv64 = base64_encode( $iv ); + + $raw = false; // true returns raw bytes, false returns base64 + + if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-256-OFB', $passphrase, $raw, $iv ) ) { - public static function init($login,$password) { - $view=new OC_FilesystemView('/'); - if(!$view->file_exists('/'.$login)){ - $view->mkdir('/'.$login); + return $encryptedContent; + + } else { + + \OC_Log::write( 'Encrypted storage', 'Encryption (symmetric) of file failed' , \OC_Log::ERROR ); + + return false; + } + + } + + /** + * @brief Symmetrically decrypt a file + * @returns decrypted file + */ + public static function decrypt( $encryptedContent, $iv, $passphrase ) { + +// $iv64 = base64_encode( $iv ); +// +// $iv = base64_decode( $iv64 ); - OC_FileProxy::$enabled=false; - if(!$view->file_exists('/'.$login.'/encryption.key')){// does key exist? - OC_Crypt::createkey($login,$password); + $raw = false; // true returns raw bytes, false returns base64 + + if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-256-OFB', $passphrase, $raw, $iv) ) { + + return $plainContent; + + + } else { + + \OC_Log::write( 'Encrypted storage', 'Decryption (symmetric) of file failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Asymetrically encrypt a file using a public key + * @returns encrypted file + */ + public static function keyEncrypt( $plainContent, $publicKey ) { + + openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey ); + + return $encryptedContent; + + } + + /** + * @brief Asymetrically decrypt a file using a private key + * @returns decrypted file + */ + public static function keyDecrypt( $encryptedContent, $privatekey ) { + + openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); + + return $plainContent; + + } + + public static function encryptFile( $source, $target, $key='') { + $handleread = fopen($source, "rb"); + if($handleread!=FALSE) { + $handlewrite = fopen($target, "wb"); + while (!feof($handleread)) { + $content = fread($handleread, 8192); + $enccontent=OC_CRYPT::encrypt( $content, $key); + fwrite($handlewrite, $enccontent); + } + fclose($handlewrite); + fclose($handleread); } - $key=$view->file_get_contents('/'.$login.'/encryption.key'); - OC_FileProxy::$enabled=true; - $_SESSION['enckey']=OC_Crypt::decrypt($key, $password); } /** - * get the blowfish encryption handeler for a key - * @param string $key (optional) - * @return Crypt_Blowfish - * - * if the key is left out, the default handeler will be used - */ - public static function getBlowfish($key=''){ - if($key){ - return new Crypt_Blowfish($key); - }else{ - if(!isset($_SESSION['enckey'])){ - return false; + * @brief decryption of a file + * @param string $source + * @param string $target + * @param string $key the decryption key + * + * This function decrypts a file + */ + public static function decryptFile( $source, $target, $key='') { + $handleread = fopen($source, "rb"); + if($handleread!=FALSE) { + $handlewrite = fopen($target, "wb"); + while (!feof($handleread)) { + $content = fread($handleread, 8192); + $enccontent=OC_CRYPT::decrypt( $content, $key); + if(feof($handleread)){ + $enccontent=rtrim($enccontent, "\0"); + } + fwrite($handlewrite, $enccontent); } - if(!self::$bf){ - self::$bf=new Crypt_Blowfish($_SESSION['enckey']); - } - return self::$bf; + fclose($handlewrite); + fclose($handleread); } } - - public static function createkey($username,$passcode) { - // generate a random key - $key=mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999); - - // encrypt the key with the passcode of the user - $enckey=OC_Crypt::encrypt($key,$passcode); - - // Write the file - $proxyEnabled=OC_FileProxy::$enabled; - OC_FileProxy::$enabled=false; - $view=new OC_FilesystemView('/'.$username); - $view->file_put_contents('/encryption.key',$enckey); - OC_FileProxy::$enabled=$proxyEnabled; + + /** + * @brief Encrypts data in 8192 byte sized blocks + * @returns encrypted data + */ + public static function blockEncrypt( $data, $key = '' ){ + + $result = ''; + + while( strlen( $data ) ) { + + // Encrypt byte block + $result .= self::encrypt( substr( $data, 0, 8192 ), $key ); + + $data = substr( $data, 8192 ); + + } + + return $result; + } + + /** + * decrypt data in 8192b sized blocks + */ + public static function blockDecrypt( $data, $key='', $maxLength = 0 ) { + + $result = ''; + + while( strlen( $data ) ) { + + $result .= self::decrypt( substr( $data, 0, 8192 ), $key ); + + $data = substr( $data,8192 ); + + } + + if ( $maxLength > 0 ) { + + return substr( $result, 0, $maxLength ); + + } else { + + return rtrim( $result, "\0" ); + + } + } + + /** + * @brief Generate a random key for symmetric encryption + * @returns $key Generated key + */ + public static function generateKey() { + + $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); + + return $key; + } public static function changekeypasscode($oldPassword, $newPassword) { @@ -114,106 +244,6 @@ class OC_Crypt { } } - /** - * @brief encrypts an content - * @param $content the cleartext message you want to encrypt - * @param $key the encryption key (optional) - * @returns encrypted content - * - * This function encrypts an content - */ - public static function encrypt( $content, $key='') { - $bf = self::getBlowfish($key); - return $bf->encrypt($content); - } - - /** - * @brief decryption of an content - * @param $content the cleartext message you want to decrypt - * @param $key the encryption key (optional) - * @returns cleartext content - * - * This function decrypts an content - */ - public static function decrypt( $content, $key='') { - $bf = self::getBlowfish($key); - $data=$bf->decrypt($content); - return $data; - } - - /** - * @brief encryption of a file - * @param string $source - * @param string $target - * @param string $key the decryption key - * - * This function encrypts a file - */ - public static function encryptFile( $source, $target, $key='') { - $handleread = fopen($source, "rb"); - if($handleread!=FALSE) { - $handlewrite = fopen($target, "wb"); - while (!feof($handleread)) { - $content = fread($handleread, 8192); - $enccontent=OC_CRYPT::encrypt( $content, $key); - fwrite($handlewrite, $enccontent); - } - fclose($handlewrite); - fclose($handleread); - } - } - - - /** - * @brief decryption of a file - * @param string $source - * @param string $target - * @param string $key the decryption key - * - * This function decrypts a file - */ - public static function decryptFile( $source, $target, $key='') { - $handleread = fopen($source, "rb"); - if($handleread!=FALSE) { - $handlewrite = fopen($target, "wb"); - while (!feof($handleread)) { - $content = fread($handleread, 8192); - $enccontent=OC_CRYPT::decrypt( $content, $key); - if(feof($handleread)){ - $enccontent=rtrim($enccontent, "\0"); - } - fwrite($handlewrite, $enccontent); - } - fclose($handlewrite); - fclose($handleread); - } - } - - /** - * encrypt data in 8192b sized blocks - */ - public static function blockEncrypt($data, $key=''){ - $result=''; - while(strlen($data)){ - $result.=self::encrypt(substr($data,0,8192),$key); - $data=substr($data,8192); - } - return $result; - } - - /** - * decrypt data in 8192b sized blocks - */ - public static function blockDecrypt($data, $key='',$maxLength=0){ - $result=''; - while(strlen($data)){ - $result.=self::decrypt(substr($data,0,8192),$key); - $data=substr($data,8192); - } - if($maxLength>0){ - return substr($result,0,$maxLength); - }else{ - return rtrim($result, "\0"); - } - } } + +?> \ No newline at end of file diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index f25e4a662f..e06242e29d 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -21,6 +21,14 @@ * */ + +class OC_FileProxy_Encryption extends OC_FileProxy { + + + +} + + /** * transparent encryption */ @@ -30,45 +38,76 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ private static $enableEncryption=null; /** - * check if a file should be encrypted during write + * Check if a file requires encryption * @param string $path * @return bool + * + * Tests if encryption is enabled, and file is allowed by blacklists */ - private static function shouldEncrypt($path){ - if(is_null(self::$enableEncryption)){ - self::$enableEncryption=(OCP\Config::getAppValue('files_encryption','enable_encryption','true')=='true'); + private static function shouldEncrypt( $path ) { + + if ( is_null( self::$enableEncryption ) ) { + + self::$enableEncryption = ( OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' ); + } - if(!self::$enableEncryption){ + + if( !self::$enableEncryption ) { + return false; + } - if(is_null(self::$blackList)){ - self::$blackList=explode(',',OCP\Config::getAppValue('files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg')); + + if( is_null(self::$blackList ) ) { + + self::$blackList = explode(',',OCP\Config::getAppValue( 'files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) ); + } - if(self::isEncrypted($path)){ + + if( self::isEncrypted( $path ) ) { + return true; + } - $extension=substr($path,strrpos($path,'.')+1); - if(array_search($extension,self::$blackList)===false){ + + $extension = substr( $path, strrpos( $path,'.' ) +1 ); + + if ( array_search( $extension, self::$blackList ) === false ){ + return true; + } + + return false; } /** - * check if a file is encrypted + * Check if a file is encrypted according to database file cache * @param string $path * @return bool */ - private static function isEncrypted($path){ - $metadata=OC_FileCache_Cached::get($path,''); - return isset($metadata['encrypted']) and (bool)$metadata['encrypted']; + private static function isEncrypted( $path ){ + + // Fetch all file metadata from DB + $metadata = OC_FileCache_Cached::get( $path, '' ); + + // Return encryption status + return isset( $metadata['encrypted'] ) and ( bool )$metadata['encrypted']; + } - public function preFile_put_contents($path,&$data){ - if(self::shouldEncrypt($path)){ - if (!is_resource($data)) {//stream put contents should have been converter to fopen - $size=strlen($data); - $data=OC_Crypt::blockEncrypt($data); - OC_FileCache::put($path,array('encrypted'=>true,'size'=>$size),''); + public function preFile_put_contents( $path, &$data ) { + + if ( self::shouldEncrypt( $path ) ) { + + if ( !is_resource( $data ) ) {//stream put contents should have been converter to fopen + + $size = strlen( $data ); + + $data = Crypt::blockEncrypt( $data ); + + OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); + } } } diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php new file mode 100644 index 0000000000..d576b75294 --- /dev/null +++ b/apps/files_encryption/lib/util.php @@ -0,0 +1,133 @@ +. + * + */ + +// Todo: +// - Crypt/decrypt button in the userinterface +// - Setting if crypto should be on by default +// - Add a setting "Don´t encrypt files larger than xx because of performance reasons" +// - Transparent decrypt/encrypt in filesystem.php. Autodetect if a file is encrypted (.encrypted extension) +// - Don't use a password directly as encryption key. but a key which is stored on the server and encrypted with the user password. -> password change faster +// - IMPORTANT! Check if the block lenght of the encrypted data stays the same + +namespace OCA_Encryption; + +/** + * Class for utilities relating to encrypted file storage system + */ + +class Util { + + private $view; // OC_FilesystemView object for filesystem operations + private $pwd; // User Password + private $client; // Client side encryption mode flag + + /** + * @brief get a list of all available versions of a file in descending chronological order + * @param $filename file to find versions of, relative to the user files dir + * @param $count number of versions to return + * @returns array + */ + public function __construct( \OC_FilesystemView $view, $client = false ) { + + $this->view = $view; + $this->client = $client; + + } + + public function ready() { + + if( + !$this->view->file_exists( '/' . 'keyfiles' ) + or !$this->view->file_exists( '/' . 'keypair' ) + or !$this->view->file_exists( '/' . 'keypair' . '/'. 'encryption.public.key' ) + or !$this->view->file_exists( '/' . 'keypair' . '/'. 'encryption.private.key' ) + ) { + + return false; + + } else { + + return true; + + } + + } + + public function setup( $passphrase = null ) { + + $publicKeyFileName = 'encryption.public.key'; + $privateKeyFileName = 'encryption.private.key'; + + // Log changes to user's filesystem + $this->appInfo = \OC_APP::getAppInfo( 'files_encryption' ); + + \OC_Log::write( $this->appInfo['name'], 'File encryption for user will be set up' , \OC_Log::INFO ); + + // Create mirrored keyfile directory + if( !$this->view->file_exists( '/' . 'keyfiles' ) ) { + + $this->view->mkdir( '/'. 'keyfiles' ); + + } + + // Create keypair directory + if( !$this->view->file_exists( '/'. 'keypair' ) ) { + + $this->view->mkdir( '/'. 'keypair' ); + + } + + // Create user keypair + if ( + !$this->view->file_exists( '/'. 'keypair'. '/' . $publicKeyFileName ) + or !$this->view->file_exists( '/'. 'keypair'. '/' . $privateKeyFileName ) + ) { + + // Generate keypair + $keypair = Crypt::createKeypair(); + + // Save public key + $this->view->file_put_contents( '/'. 'keypair'. '/' . $publicKeyFileName, $keypair['publicKey'] ); + + if ( $this->client == false ) { + + # TODO: Use proper IV in encryption + + // Encrypt private key with user pwd as passphrase + $encryptedPrivateKey = Crypt::encrypt( $keypair['privateKey'], 1234567890123456, $passphrase ); + + // $iv = openssl_random_pseudo_bytes(16); + $this->view->file_put_contents( '/'. 'keypair'. '/' . $privateKeyFileName, $encryptedPrivateKey ); + + } else { + + # TODO PHASE2: add public key to keyserver for client-side + # TODO PHASE2: encrypt private key using password / new client side specified key, instead of existing user pwd + + } + + } + + } + +} From 283561823febbfb668ca33e234a01b5342e16e60 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 17 Jul 2012 19:15:59 +0100 Subject: [PATCH 002/315] Added methods for handling encrypted file + iv content Improved IV generation --- apps/files_encryption/lib/crypt.php | 176 ++++++++++++---------------- apps/files_encryption/lib/util.php | 2 +- 2 files changed, 75 insertions(+), 103 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 7763f6bea5..e5bc3adcbc 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -55,20 +55,14 @@ class Crypt { * @returns encrypted file */ public static function encrypt( $plainContent, $iv, $passphrase = '' ) { - - # TODO: Move these methods into a separate public class for app developers - - $iv64 = base64_encode( $iv ); - $raw = false; // true returns raw bytes, false returns base64 - - if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-256-OFB', $passphrase, $raw, $iv ) ) { + if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { return $encryptedContent; } else { - \OC_Log::write( 'Encrypted storage', 'Encryption (symmetric) of file failed' , \OC_Log::ERROR ); + \OC_Log::write( 'Encrypted storage', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); return false; @@ -81,21 +75,85 @@ class Crypt { * @returns decrypted file */ public static function decrypt( $encryptedContent, $iv, $passphrase ) { - -// $iv64 = base64_encode( $iv ); -// -// $iv = base64_decode( $iv64 ); - $raw = false; // true returns raw bytes, false returns base64 - - if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-256-OFB', $passphrase, $raw, $iv) ) { + if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { return $plainContent; } else { - \OC_Log::write( 'Encrypted storage', 'Decryption (symmetric) of file failed' , \OC_Log::ERROR ); + \OC_Log::write( 'Encrypted storage', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Creates symmetric keyfile content + * @param $plainContent content to be encrypted in keyfile + * @returns encrypted content combined with IV + * @note IV need not be specified, as it will be stored in the returned keyfile + * and remain accessible therein. + */ + public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) { + + if ( !$plainContent ) { + + return false; + + } + + $random = openssl_random_pseudo_bytes( 13 ); + + $iv = substr( base64_encode( $random ), 0, -4 ); + + if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { + + $combinedKeyfile = $encryptedContent .= $iv; + + return $combinedKeyfile; + + } else { + + \OC_Log::write( 'Encrypted storage', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + + /** + * @brief Decrypts keyfile content + * @param string $source + * @param string $target + * @param string $key the decryption key + * + * This function decrypts a file + */ + public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) { + + if ( !$keyfileContent ) { + + return false; + + } + + $iv = substr( $keyfileContent, -16 ); + + $encryptedContent = substr( $keyfileContent, 0, -16 ); + + if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) { + + return $plainContent; + + } else { + + \OC_Log::write( 'Encrypted storage', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); return false; @@ -127,92 +185,6 @@ class Crypt { } - public static function encryptFile( $source, $target, $key='') { - $handleread = fopen($source, "rb"); - if($handleread!=FALSE) { - $handlewrite = fopen($target, "wb"); - while (!feof($handleread)) { - $content = fread($handleread, 8192); - $enccontent=OC_CRYPT::encrypt( $content, $key); - fwrite($handlewrite, $enccontent); - } - fclose($handlewrite); - fclose($handleread); - } - } - - - /** - * @brief decryption of a file - * @param string $source - * @param string $target - * @param string $key the decryption key - * - * This function decrypts a file - */ - public static function decryptFile( $source, $target, $key='') { - $handleread = fopen($source, "rb"); - if($handleread!=FALSE) { - $handlewrite = fopen($target, "wb"); - while (!feof($handleread)) { - $content = fread($handleread, 8192); - $enccontent=OC_CRYPT::decrypt( $content, $key); - if(feof($handleread)){ - $enccontent=rtrim($enccontent, "\0"); - } - fwrite($handlewrite, $enccontent); - } - fclose($handlewrite); - fclose($handleread); - } - } - - /** - * @brief Encrypts data in 8192 byte sized blocks - * @returns encrypted data - */ - public static function blockEncrypt( $data, $key = '' ){ - - $result = ''; - - while( strlen( $data ) ) { - - // Encrypt byte block - $result .= self::encrypt( substr( $data, 0, 8192 ), $key ); - - $data = substr( $data, 8192 ); - - } - - return $result; - } - - /** - * decrypt data in 8192b sized blocks - */ - public static function blockDecrypt( $data, $key='', $maxLength = 0 ) { - - $result = ''; - - while( strlen( $data ) ) { - - $result .= self::decrypt( substr( $data, 0, 8192 ), $key ); - - $data = substr( $data,8192 ); - - } - - if ( $maxLength > 0 ) { - - return substr( $result, 0, $maxLength ); - - } else { - - return rtrim( $result, "\0" ); - - } - } - /** * @brief Generate a random key for symmetric encryption * @returns $key Generated key diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index d576b75294..9c0f71fe39 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -114,7 +114,7 @@ class Util { # TODO: Use proper IV in encryption // Encrypt private key with user pwd as passphrase - $encryptedPrivateKey = Crypt::encrypt( $keypair['privateKey'], 1234567890123456, $passphrase ); + $encryptedPrivateKey = Crypt::createSymmetricKeyfile( $keypair['privateKey'], $passphrase ); // $iv = openssl_random_pseudo_bytes(16); $this->view->file_put_contents( '/'. 'keypair'. '/' . $privateKeyFileName, $encryptedPrivateKey ); From d294e7772156dc27b6d69df405f7dcf7d7f4326f Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 18 Jul 2012 18:52:00 +0100 Subject: [PATCH 003/315] Development snapshot: - Added methods for sealing data with multiple keys - Added method for encrypting data, generating iv and keyfile, and returning both - Added 6 unit test cases (containing 12 tests) for Crypt class - Commented out old unit tests for now --- apps/files_encryption/lib/crypt.php | 124 ++++++++++-- apps/files_encryption/lib/proxy.php | 7 - apps/files_encryption/lib/util.php | 2 +- apps/files_encryption/tests/encryption.php | 220 +++++++++++++++------ apps/files_encryption/tests/proxy.php | 218 ++++++++++---------- apps/files_encryption/tests/stream.php | 154 +++++++-------- 6 files changed, 461 insertions(+), 264 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index e5bc3adcbc..098074c228 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -51,7 +51,7 @@ class Crypt { } /** - * @brief Symmetrically encrypt a file + * @brief Symmetrically encrypt a string * @returns encrypted file */ public static function encrypt( $plainContent, $iv, $passphrase = '' ) { @@ -62,7 +62,7 @@ class Crypt { } else { - \OC_Log::write( 'Encrypted storage', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); return false; @@ -71,7 +71,7 @@ class Crypt { } /** - * @brief Symmetrically decrypt a file + * @brief Symmetrically decrypt a string * @returns decrypted file */ public static function decrypt( $encryptedContent, $iv, $passphrase ) { @@ -83,7 +83,7 @@ class Crypt { } else { - \OC_Log::write( 'Encrypted storage', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); + \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); return false; @@ -92,7 +92,7 @@ class Crypt { } /** - * @brief Creates symmetric keyfile content + * @brief Symmetrically encrypts a string and returns keyfile content * @param $plainContent content to be encrypted in keyfile * @returns encrypted content combined with IV * @note IV need not be specified, as it will be stored in the returned keyfile @@ -118,7 +118,7 @@ class Crypt { } else { - \OC_Log::write( 'Encrypted storage', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); return false; @@ -128,7 +128,7 @@ class Crypt { /** - * @brief Decrypts keyfile content + * @brief Symmetrically decrypts keyfile content * @param string $source * @param string $target * @param string $key the decryption key @@ -153,7 +153,91 @@ class Crypt { } else { - \OC_Log::write( 'Encrypted storage', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Creates symmetric keyfile content using a generated key + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function symmetricEncryptFileContentKeyfile( $plainContent ) { + + $key = self::generateKey(); + + if( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) { + + return array( + 'key' => $key + , 'encrypted' => $encryptedContent + ); + + } else { + + return false; + + } + + } + + /** + * @brief Create asymmetrically encrypted keyfile content using a generated key + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { + + $envKeys = array(); + + if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) { + + return array( + 'keys' => $envKeys + , 'encrypted' => $sealed + ); + + } else { + + return false; + + } + + } + + /** + * @brief Asymmetrically encrypt a file using multiple public keys + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function multiKeyDecrypt( $encryptedContent, $envKey, $privateKey ) { + + if ( !$encryptedContent ) { + + return false; + + } + + if ( openssl_open( $encryptedContent, $plainContent, $envKey, $privateKey ) ) { + + return $plainContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed' , \OC_Log::ERROR ); return false; @@ -162,7 +246,7 @@ class Crypt { } /** - * @brief Asymetrically encrypt a file using a public key + * @brief Asymetrically encrypt a string using a public key * @returns encrypted file */ public static function keyEncrypt( $plainContent, $publicKey ) { @@ -186,14 +270,30 @@ class Crypt { } /** - * @brief Generate a random key for symmetric encryption + * @brief Generate a pseudo random 1024kb ASCII key * @returns $key Generated key */ public static function generateKey() { - $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); + // $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); - return $key; + // Generate key + if ( $key = base64_encode( openssl_random_pseudo_bytes( 768000, $strong ) ) ) { + + if ( !$strong ) { + + // If OpenSSL indicates randomness is insecure, log error + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); + + } + + return $key; + + } else { + + return false; + + } } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index e06242e29d..3f9b86b988 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -22,13 +22,6 @@ */ -class OC_FileProxy_Encryption extends OC_FileProxy { - - - -} - - /** * transparent encryption */ diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 9c0f71fe39..62b435583e 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -114,7 +114,7 @@ class Util { # TODO: Use proper IV in encryption // Encrypt private key with user pwd as passphrase - $encryptedPrivateKey = Crypt::createSymmetricKeyfile( $keypair['privateKey'], $passphrase ); + $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], $passphrase ); // $iv = openssl_random_pseudo_bytes(16); $this->view->file_put_contents( '/'. 'keypair'. '/' . $privateKeyFileName, $encryptedPrivateKey ); diff --git a/apps/files_encryption/tests/encryption.php b/apps/files_encryption/tests/encryption.php index 286770a69f..600e00fd3e 100644 --- a/apps/files_encryption/tests/encryption.php +++ b/apps/files_encryption/tests/encryption.php @@ -6,67 +6,171 @@ * See the COPYING-README file. */ +require realpath( dirname(__FILE__).'/../lib/crypt.php' ); + class Test_Encryption extends UnitTestCase { - function testEncryption(){ - $key=uniqid(); - $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; - $source=file_get_contents($file); //nice large text file - $encrypted=OC_Crypt::encrypt($source,$key); - $decrypted=OC_Crypt::decrypt($encrypted,$key); - $decrypted=rtrim($decrypted, "\0"); - $this->assertNotEqual($encrypted,$source); - $this->assertEqual($decrypted,$source); - $chunk=substr($source,0,8192); - $encrypted=OC_Crypt::encrypt($chunk,$key); - $this->assertEqual(strlen($chunk),strlen($encrypted)); - $decrypted=OC_Crypt::decrypt($encrypted,$key); - $decrypted=rtrim($decrypted, "\0"); - $this->assertEqual($decrypted,$chunk); + function setUp() { - $encrypted=OC_Crypt::blockEncrypt($source,$key); - $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); - $this->assertNotEqual($encrypted,$source); - $this->assertEqual($decrypted,$source); - - $tmpFileEncrypted=OCP\Files::tmpFile(); - OC_Crypt::encryptfile($file,$tmpFileEncrypted,$key); - $encrypted=file_get_contents($tmpFileEncrypted); - $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); - $this->assertNotEqual($encrypted,$source); - $this->assertEqual($decrypted,$source); - - $tmpFileDecrypted=OCP\Files::tmpFile(); - OC_Crypt::decryptfile($tmpFileEncrypted,$tmpFileDecrypted,$key); - $decrypted=file_get_contents($tmpFileDecrypted); - $this->assertEqual($decrypted,$source); - - $file=OC::$SERVERROOT.'/core/img/weather-clear.png'; - $source=file_get_contents($file); //binary file - $encrypted=OC_Crypt::encrypt($source,$key); - $decrypted=OC_Crypt::decrypt($encrypted,$key); - $decrypted=rtrim($decrypted, "\0"); - $this->assertEqual($decrypted,$source); - - $encrypted=OC_Crypt::blockEncrypt($source,$key); - $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); - $this->assertEqual($decrypted,$source); - - } - - function testBinary(){ - $key=uniqid(); + // set content for encrypting / decrypting in tests + $this->data = realpath( dirname(__FILE__).'/../lib/crypt.php' ); - $file=__DIR__.'/binary'; - $source=file_get_contents($file); //binary file - $encrypted=OC_Crypt::encrypt($source,$key); - $decrypted=OC_Crypt::decrypt($encrypted,$key); - - $decrypted=rtrim($decrypted, "\0"); - $this->assertEqual($decrypted,$source); - - $encrypted=OC_Crypt::blockEncrypt($source,$key); - $decrypted=OC_Crypt::blockDecrypt($encrypted,$key,strlen($source)); - $this->assertEqual($decrypted,$source); } + + function tearDown(){} + + function testGenerateKey() { + + # TODO: use more accurate (larger) string length for test confirmation + + $key = OCA_Encryption\Crypt::generateKey(); + + $this->assertTrue( strlen( $key ) > 1000 ); + + } + + function testEncrypt() { + + $random = openssl_random_pseudo_bytes( 13 ); + + $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht + + $crypted = OCA_Encryption\Crypt::encrypt( $this->data, $iv, 'hat' ); + + $this->assertNotEqual( $this->data, $crypted ); + + } + + function testDecrypt() { + + $random = openssl_random_pseudo_bytes( 13 ); + + $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht + + $crypted = OCA_Encryption\Crypt::encrypt( $this->data, $iv, 'hat' ); + + $decrypt = OCA_Encryption\Crypt::decrypt( $crypted, $iv, 'hat' ); + + $this->assertEqual( $this->data, $decrypt ); + + } + + function testSymmetricEncryptFileContent() { + + # TODO: search in keyfile for actual content as IV will ensure this test always passes + + $keyfileContent = OCA_Encryption\Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); + + $this->assertNotEqual( $this->data, $keyfileContent ); + + + $decrypt = OCA_Encryption\Crypt::symmetricDecryptFileContent( $keyfileContent, 'hat' ); + + $this->assertEqual( $this->data, $decrypt ); + + } + + function testSymmetricEncryptFileContentKeyfile() { + + # TODO: search in keyfile for actual content as IV will ensure this test always passes + + $crypted = OCA_Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->data ); + + $this->assertNotEqual( $this->data, $crypted['encrypted'] ); + + + $decrypt = OCA_Encryption\Crypt::symmetricDecryptFileContent( $crypted['encrypted'], $crypted['key'] ); + + $this->assertEqual( $this->data, $decrypt ); + + } + + function testMultiKeyEncrypt() { + + # TODO: search in keyfile for actual content as IV will ensure this test always passes + + $pair1 = OCA_Encryption\Crypt::createKeypair(); + + $this->assertEqual( 2, count( $pair1 ) ); + + $this->assertTrue( strlen( $pair1['publicKey'] ) > 1 ); + + $this->assertTrue( strlen( $pair1['privateKey'] ) > 1 ); + + + $crypted = OCA_Encryption\Crypt::multiKeyEncrypt( $this->data, array( $pair1['publicKey'] ) ); + + $this->assertNotEqual( $this->data, $crypted['encrypted'] ); + + + $decrypt = OCA_Encryption\Crypt::multiKeyDecrypt( $crypted['encrypted'], $crypted['keys'][0], $pair1['privateKey'] ); + + $this->assertEqual( $this->data, $decrypt ); + + } + +// function testEncryption(){ +// +// $key=uniqid(); +// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; +// $source=file_get_contents($file); //nice large text file +// $encrypted=OC_Crypt::encrypt($source,$key); +// $decrypted=OC_Crypt::decrypt($encrypted,$key); +// $decrypted=rtrim($decrypted, "\0"); +// $this->assertNotEqual($encrypted,$source); +// $this->assertEqual($decrypted,$source); +// +// $chunk=substr($source,0,8192); +// $encrypted=OC_Crypt::encrypt($chunk,$key); +// $this->assertEqual(strlen($chunk),strlen($encrypted)); +// $decrypted=OC_Crypt::decrypt($encrypted,$key); +// $decrypted=rtrim($decrypted, "\0"); +// $this->assertEqual($decrypted,$chunk); +// +// $encrypted=OC_Crypt::blockEncrypt($source,$key); +// $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); +// $this->assertNotEqual($encrypted,$source); +// $this->assertEqual($decrypted,$source); +// +// $tmpFileEncrypted=OCP\Files::tmpFile(); +// OC_Crypt::encryptfile($file,$tmpFileEncrypted,$key); +// $encrypted=file_get_contents($tmpFileEncrypted); +// $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); +// $this->assertNotEqual($encrypted,$source); +// $this->assertEqual($decrypted,$source); +// +// $tmpFileDecrypted=OCP\Files::tmpFile(); +// OC_Crypt::decryptfile($tmpFileEncrypted,$tmpFileDecrypted,$key); +// $decrypted=file_get_contents($tmpFileDecrypted); +// $this->assertEqual($decrypted,$source); +// +// $file=OC::$SERVERROOT.'/core/img/weather-clear.png'; +// $source=file_get_contents($file); //binary file +// $encrypted=OC_Crypt::encrypt($source,$key); +// $decrypted=OC_Crypt::decrypt($encrypted,$key); +// $decrypted=rtrim($decrypted, "\0"); +// $this->assertEqual($decrypted,$source); +// +// $encrypted=OC_Crypt::blockEncrypt($source,$key); +// $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); +// $this->assertEqual($decrypted,$source); +// +// } +// +// function testBinary(){ +// $key=uniqid(); +// +// $file=__DIR__.'/binary'; +// $source=file_get_contents($file); //binary file +// $encrypted=OC_Crypt::encrypt($source,$key); +// $decrypted=OC_Crypt::decrypt($encrypted,$key); +// +// $decrypted=rtrim($decrypted, "\0"); +// $this->assertEqual($decrypted,$source); +// +// $encrypted=OC_Crypt::blockEncrypt($source,$key); +// $decrypted=OC_Crypt::blockDecrypt($encrypted,$key,strlen($source)); +// $this->assertEqual($decrypted,$source); +// } + } diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index 5463836a20..253a32164e 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -6,112 +6,112 @@ * See the COPYING-README file. */ -class Test_CryptProxy extends UnitTestCase { - private $oldConfig; - private $oldKey; - - public function setUp(){ - $user=OC_User::getUser(); - - $this->oldConfig=OCP\Config::getAppValue('files_encryption','enable_encryption','true'); - OCP\Config::setAppValue('files_encryption','enable_encryption','true'); - $this->oldKey=isset($_SESSION['enckey'])?$_SESSION['enckey']:null; - - - //set testing key - $_SESSION['enckey']=md5(time()); - - //clear all proxies and hooks so we can do clean testing - OC_FileProxy::clearProxies(); - OC_Hook::clear('OC_Filesystem'); - - //enable only the encryption hook - OC_FileProxy::register(new OC_FileProxy_Encryption()); - - //set up temporary storage - OC_Filesystem::clearMounts(); - OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); - - OC_Filesystem::init('/'.$user.'/files'); - - //set up the users home folder in the temp storage - $rootView=new OC_FilesystemView(''); - $rootView->mkdir('/'.$user); - $rootView->mkdir('/'.$user.'/files'); - } - - public function tearDown(){ - OCP\Config::setAppValue('files_encryption','enable_encryption',$this->oldConfig); - if(!is_null($this->oldKey)){ - $_SESSION['enckey']=$this->oldKey; - } - } - - public function testSimple(){ - $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; - $original=file_get_contents($file); - - OC_Filesystem::file_put_contents('/file',$original); - - OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); - OC_FileProxy::$enabled=true; - - $fromFile=OC_Filesystem::file_get_contents('/file'); - $this->assertNotEqual($original,$stored); - $this->assertEqual(strlen($original),strlen($fromFile)); - $this->assertEqual($original,$fromFile); - - } - - public function testView(){ - $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; - $original=file_get_contents($file); - - $rootView=new OC_FilesystemView(''); - $view=new OC_FilesystemView('/'.OC_User::getUser()); - $userDir='/'.OC_User::getUser().'/files'; - - $rootView->file_put_contents($userDir.'/file',$original); - - OC_FileProxy::$enabled=false; - $stored=$rootView->file_get_contents($userDir.'/file'); - OC_FileProxy::$enabled=true; - - $this->assertNotEqual($original,$stored); - $fromFile=$rootView->file_get_contents($userDir.'/file'); - $this->assertEqual($original,$fromFile); - - $fromFile=$view->file_get_contents('files/file'); - $this->assertEqual($original,$fromFile); - } - - public function testBinary(){ - $file=__DIR__.'/binary'; - $original=file_get_contents($file); - - OC_Filesystem::file_put_contents('/file',$original); - - OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); - OC_FileProxy::$enabled=true; - - $fromFile=OC_Filesystem::file_get_contents('/file'); - $this->assertNotEqual($original,$stored); - $this->assertEqual(strlen($original),strlen($fromFile)); - $this->assertEqual($original,$fromFile); - - $file=__DIR__.'/zeros'; - $original=file_get_contents($file); - - OC_Filesystem::file_put_contents('/file',$original); - - OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); - OC_FileProxy::$enabled=true; - - $fromFile=OC_Filesystem::file_get_contents('/file'); - $this->assertNotEqual($original,$stored); - $this->assertEqual(strlen($original),strlen($fromFile)); - } -} +// class Test_CryptProxy extends UnitTestCase { +// private $oldConfig; +// private $oldKey; +// +// public function setUp(){ +// $user=OC_User::getUser(); +// +// $this->oldConfig=OCP\Config::getAppValue('files_encryption','enable_encryption','true'); +// OCP\Config::setAppValue('files_encryption','enable_encryption','true'); +// $this->oldKey=isset($_SESSION['enckey'])?$_SESSION['enckey']:null; +// +// +// //set testing key +// $_SESSION['enckey']=md5(time()); +// +// //clear all proxies and hooks so we can do clean testing +// OC_FileProxy::clearProxies(); +// OC_Hook::clear('OC_Filesystem'); +// +// //enable only the encryption hook +// OC_FileProxy::register(new OC_FileProxy_Encryption()); +// +// //set up temporary storage +// OC_Filesystem::clearMounts(); +// OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); +// +// OC_Filesystem::init('/'.$user.'/files'); +// +// //set up the users home folder in the temp storage +// $rootView=new OC_FilesystemView(''); +// $rootView->mkdir('/'.$user); +// $rootView->mkdir('/'.$user.'/files'); +// } +// +// public function tearDown(){ +// OCP\Config::setAppValue('files_encryption','enable_encryption',$this->oldConfig); +// if(!is_null($this->oldKey)){ +// $_SESSION['enckey']=$this->oldKey; +// } +// } +// +// public function testSimple(){ +// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; +// $original=file_get_contents($file); +// +// OC_Filesystem::file_put_contents('/file',$original); +// +// OC_FileProxy::$enabled=false; +// $stored=OC_Filesystem::file_get_contents('/file'); +// OC_FileProxy::$enabled=true; +// +// $fromFile=OC_Filesystem::file_get_contents('/file'); +// $this->assertNotEqual($original,$stored); +// $this->assertEqual(strlen($original),strlen($fromFile)); +// $this->assertEqual($original,$fromFile); +// +// } +// +// public function testView(){ +// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; +// $original=file_get_contents($file); +// +// $rootView=new OC_FilesystemView(''); +// $view=new OC_FilesystemView('/'.OC_User::getUser()); +// $userDir='/'.OC_User::getUser().'/files'; +// +// $rootView->file_put_contents($userDir.'/file',$original); +// +// OC_FileProxy::$enabled=false; +// $stored=$rootView->file_get_contents($userDir.'/file'); +// OC_FileProxy::$enabled=true; +// +// $this->assertNotEqual($original,$stored); +// $fromFile=$rootView->file_get_contents($userDir.'/file'); +// $this->assertEqual($original,$fromFile); +// +// $fromFile=$view->file_get_contents('files/file'); +// $this->assertEqual($original,$fromFile); +// } +// +// public function testBinary(){ +// $file=__DIR__.'/binary'; +// $original=file_get_contents($file); +// +// OC_Filesystem::file_put_contents('/file',$original); +// +// OC_FileProxy::$enabled=false; +// $stored=OC_Filesystem::file_get_contents('/file'); +// OC_FileProxy::$enabled=true; +// +// $fromFile=OC_Filesystem::file_get_contents('/file'); +// $this->assertNotEqual($original,$stored); +// $this->assertEqual(strlen($original),strlen($fromFile)); +// $this->assertEqual($original,$fromFile); +// +// $file=__DIR__.'/zeros'; +// $original=file_get_contents($file); +// +// OC_Filesystem::file_put_contents('/file',$original); +// +// OC_FileProxy::$enabled=false; +// $stored=OC_Filesystem::file_get_contents('/file'); +// OC_FileProxy::$enabled=true; +// +// $fromFile=OC_Filesystem::file_get_contents('/file'); +// $this->assertNotEqual($original,$stored); +// $this->assertEqual(strlen($original),strlen($fromFile)); +// } +// } diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php index d95ea792f7..4c78b2d7b0 100644 --- a/apps/files_encryption/tests/stream.php +++ b/apps/files_encryption/tests/stream.php @@ -6,80 +6,80 @@ * See the COPYING-README file. */ -class Test_CryptStream extends UnitTestCase { - private $tmpFiles=array(); - - function testStream(){ - $stream=$this->getStream('test1','w',strlen('foobar')); - fwrite($stream,'foobar'); - fclose($stream); - - $stream=$this->getStream('test1','r',strlen('foobar')); - $data=fread($stream,6); - fclose($stream); - $this->assertEqual('foobar',$data); - - $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; - $source=fopen($file,'r'); - $target=$this->getStream('test2','w',0); - OCP\Files::streamCopy($source,$target); - fclose($target); - fclose($source); - - $stream=$this->getStream('test2','r',filesize($file)); - $data=stream_get_contents($stream); - $original=file_get_contents($file); - $this->assertEqual(strlen($original),strlen($data)); - $this->assertEqual($original,$data); - } - - /** - * get a cryptstream to a temporary file - * @param string $id - * @param string $mode - * @param int size - * @return resource - */ - function getStream($id,$mode,$size){ - if($id===''){ - $id=uniqid(); - } - if(!isset($this->tmpFiles[$id])){ - $file=OCP\Files::tmpFile(); - $this->tmpFiles[$id]=$file; - }else{ - $file=$this->tmpFiles[$id]; - } - $stream=fopen($file,$mode); - OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy'.$id,'stream'=>$stream,'size'=>$size); - return fopen('crypt://streams/'.$id,$mode); - } - - function testBinary(){ - $file=__DIR__.'/binary'; - $source=file_get_contents($file); - - $stream=$this->getStream('test','w',strlen($source)); - fwrite($stream,$source); - fclose($stream); - - $stream=$this->getStream('test','r',strlen($source)); - $data=stream_get_contents($stream); - fclose($stream); - $this->assertEqual(strlen($data),strlen($source)); - $this->assertEqual($source,$data); - - $file=__DIR__.'/zeros'; - $source=file_get_contents($file); - - $stream=$this->getStream('test2','w',strlen($source)); - fwrite($stream,$source); - fclose($stream); - - $stream=$this->getStream('test2','r',strlen($source)); - $data=stream_get_contents($stream); - fclose($stream); - $this->assertEqual(strlen($data),strlen($source)); - $this->assertEqual($source,$data); - } -} +// class Test_CryptStream extends UnitTestCase { +// private $tmpFiles=array(); +// +// function testStream(){ +// $stream=$this->getStream('test1','w',strlen('foobar')); +// fwrite($stream,'foobar'); +// fclose($stream); +// +// $stream=$this->getStream('test1','r',strlen('foobar')); +// $data=fread($stream,6); +// fclose($stream); +// $this->assertEqual('foobar',$data); +// +// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; +// $source=fopen($file,'r'); +// $target=$this->getStream('test2','w',0); +// OCP\Files::streamCopy($source,$target); +// fclose($target); +// fclose($source); +// +// $stream=$this->getStream('test2','r',filesize($file)); +// $data=stream_get_contents($stream); +// $original=file_get_contents($file); +// $this->assertEqual(strlen($original),strlen($data)); +// $this->assertEqual($original,$data); +// } +// +// /** +// * get a cryptstream to a temporary file +// * @param string $id +// * @param string $mode +// * @param int size +// * @return resource +// */ +// function getStream($id,$mode,$size){ +// if($id===''){ +// $id=uniqid(); +// } +// if(!isset($this->tmpFiles[$id])){ +// $file=OCP\Files::tmpFile(); +// $this->tmpFiles[$id]=$file; +// }else{ +// $file=$this->tmpFiles[$id]; +// } +// $stream=fopen($file,$mode); +// OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy'.$id,'stream'=>$stream,'size'=>$size); +// return fopen('crypt://streams/'.$id,$mode); +// } +// +// function testBinary(){ +// $file=__DIR__.'/binary'; +// $source=file_get_contents($file); +// +// $stream=$this->getStream('test','w',strlen($source)); +// fwrite($stream,$source); +// fclose($stream); +// +// $stream=$this->getStream('test','r',strlen($source)); +// $data=stream_get_contents($stream); +// fclose($stream); +// $this->assertEqual(strlen($data),strlen($source)); +// $this->assertEqual($source,$data); +// +// $file=__DIR__.'/zeros'; +// $source=file_get_contents($file); +// +// $stream=$this->getStream('test2','w',strlen($source)); +// fwrite($stream,$source); +// fclose($stream); +// +// $stream=$this->getStream('test2','r',strlen($source)); +// $data=stream_get_contents($stream); +// fclose($stream); +// $this->assertEqual(strlen($data),strlen($source)); +// $this->assertEqual($source,$data); +// } +// } From 2cf64daec434e741f26c704bec476e4e795da8dc Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 24 Jul 2012 18:08:55 +0200 Subject: [PATCH 004/315] moved to ocs.php from master and added dummy functions for the keyserver --- lib/ocs.php | 914 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 535 insertions(+), 379 deletions(-) diff --git a/lib/ocs.php b/lib/ocs.php index 1be41202d7..3157aae99e 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -4,7 +4,9 @@ * ownCloud * * @author Frank Karlitschek +* @author Michael Gapczynski * @copyright 2012 Frank Karlitschek frank@owncloud.org +* @copyright 2012 Michael Gapczynski mtgap@owncloud.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -29,429 +31,453 @@ */ class OC_OCS { - /** - * reads input date from get/post/cookies and converts the date to a special data-type - * - * @param variable $key - * @param variable-type $type - * @param priority $getpriority - * @param default $default - * @return data - */ - public static function readData($key,$type='raw',$getpriority=false,$default='') { - if($getpriority) { - if(isset($_GET[$key])) { - $data=$_GET[$key]; - } elseif(isset($_POST[$key])) { - $data=$_POST[$key]; - } else { - if($default=='') { - if(($type=='int') or ($type=='float')) $data=0; else $data=''; - } else { - $data=$default; - } - } - } else { - if(isset($_POST[$key])) { - $data=$_POST[$key]; - } elseif(isset($_GET[$key])) { - $data=$_GET[$key]; - } elseif(isset($_COOKIE[$key])) { - $data=$_COOKIE[$key]; - } else { - if($default=='') { - if(($type=='int') or ($type=='float')) $data=0; else $data=''; - } else { - $data=$default; - } - } - } + /** + * reads input date from get/post/cookies and converts the date to a special data-type + * + * @param string HTTP method to read the key from + * @param string Parameter to read + * @param string Variable type to format data + * @param mixed Default value to return if the key is not found + * @return mixed Data or if the key is not found and no default is set it will exit with a 400 Bad request + */ + public static function readData($method, $key, $type = 'raw', $default = null) { + if ($method == 'get') { + if (isset($_GET[$key])) { + $data = $_GET[$key]; + } else if (isset($default)) { + return $default; + } else { + $data = false; + } + } else if ($method == 'post') { + if (isset($_POST[$key])) { + $data = $_POST[$key]; + } else if (isset($default)) { + return $default; + } else { + $data = false; + } + } + if ($data === false) { + echo self::generateXml('', 'fail', 400, 'Bad request. Please provide a valid '.$key); + exit(); + } else { + // NOTE: Is the raw type necessary? It might be a little risky without sanitization + if ($type == 'raw') return $data; + elseif ($type == 'text') return OC_Util::sanitizeHTML($data); + elseif ($type == 'int') return (int) $data; + elseif ($type == 'float') return (float) $data; + elseif ($type == 'array') return OC_Util::sanitizeHTML($data); + else return OC_Util::sanitizeHTML($data); + } + } - if($type=='raw') return($data); - elseif($type=='text') return(addslashes(strip_tags($data))); - elseif($type=='int') { $data = (int) $data; return($data); } - elseif($type=='float') { $data = (float) $data; return($data); } - elseif($type=='array') { $data = $data; return($data); } - } + /** + main function to handle the REST request + **/ + public static function handle() { + // overwrite the 404 error page returncode + header("HTTP/1.0 200 OK"); - /** - main function to handle the REST request - **/ - public static function handle() { + if($_SERVER['REQUEST_METHOD'] == 'GET') { + $method='get'; + }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') { + $method='put'; + parse_str(file_get_contents("php://input"),$put_vars); + }elseif($_SERVER['REQUEST_METHOD'] == 'POST') { + $method='post'; + }else{ + echo('internal server error: method not supported'); + exit(); + } - // overwrite the 404 error page returncode - header("HTTP/1.0 200 OK"); + // preprocess url + $url = strtolower($_SERVER['REQUEST_URI']); + if(substr($url,(strlen($url)-1))<>'/') $url.='/'; + $ex=explode('/',$url); + $paracount=count($ex); + $format = self::readData($method, 'format', 'text', ''); + + // eventhandler + // CONFIG + // apiconfig - GET - CONFIG + if(($method=='get') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'config')){ + OC_OCS::apiconfig($format); + + // PERSON + // personcheck - POST - PERSON/CHECK + }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='person') and ($ex[$paracount-2] == 'check')){ + $login = self::readData($method, 'login', 'text'); + $passwd = self::readData($method, 'password', 'text'); + OC_OCS::personcheck($format,$login,$passwd); + + // ACTIVITY + // activityget - GET ACTIVITY page,pagesize als urlparameter + }elseif(($method=='get') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'activity')){ + $page = self::readData($method, 'page', 'int', 0); + $pagesize = self::readData($method, 'pagesize','int', 10); + if($pagesize<1 or $pagesize>100) $pagesize=10; + OC_OCS::activityget($format,$page,$pagesize); + + // activityput - POST ACTIVITY + }elseif(($method=='post') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'activity')){ + $message = self::readData($method, 'message', 'text'); + OC_OCS::activityput($format,$message); - if($_SERVER['REQUEST_METHOD'] == 'GET') { - $method='get'; - }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') { - $method='put'; - parse_str(file_get_contents("php://input"),$put_vars); - }elseif($_SERVER['REQUEST_METHOD'] == 'POST') { - $method='post'; - }else{ - echo('internal server error: method not supported'); - exit(); - } + // PRIVATEDATA + // get - GET DATA + }elseif(($method=='get') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-2] == 'getattribute')){ + OC_OCS::privateDataGet($format); - // preprocess url - $url=$_SERVER['REQUEST_URI']; - if(substr($url,(strlen($url)-1))<>'/') $url.='/'; - $ex=explode('/',$url); - $paracount=count($ex); + }elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-3] == 'getattribute')){ + $app=$ex[$paracount-2]; + OC_OCS::privateDataGet($format, $app); + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-4] == 'getattribute')){ - // eventhandler - // CONFIG - // apiconfig - GET - CONFIG - if(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php') and (strtolower($ex[$paracount-2])=='config')){ - $format=OC_OCS::readdata('format','text'); - OC_OCS::apiconfig($format); + $key=$ex[$paracount-2]; + $app=$ex[$paracount-3]; + OC_OCS::privateDataGet($format, $app,$key); - // PERSON - // personcheck - POST - PERSON/CHECK - }elseif(($method=='post') and (strtolower($ex[$paracount-4])=='v1.php') and (strtolower($ex[$paracount-3])=='person') and (strtolower($ex[$paracount-2])=='check')){ - $format=OC_OCS::readdata('format','text'); - $login=OC_OCS::readdata('login','text'); - $passwd=OC_OCS::readdata('password','text'); - OC_OCS::personcheck($format,$login,$passwd); + // set - POST DATA + }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-4] == 'setattribute')){ + $key=$ex[$paracount-2]; + $app=$ex[$paracount-3]; + $value = self::readData($method, 'value', 'text'); + OC_OCS::privatedataset($format, $app, $key, $value); + // delete - POST DATA + }elseif(($method=='post') and ($ex[$paracount-6] =='v1.php') and ($ex[$paracount-4] == 'deleteattribute')){ + $key=$ex[$paracount-2]; + $app=$ex[$paracount-3]; + OC_OCS::privatedatadelete($format, $app, $key); - // ACTIVITY - // activityget - GET ACTIVITY page,pagesize als urlparameter - }elseif(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){ - $format=OC_OCS::readdata('format','text'); - $page=OC_OCS::readdata('page','int'); - $pagesize=OC_OCS::readdata('pagesize','int'); - if($pagesize<1 or $pagesize>100) $pagesize=10; - OC_OCS::activityget($format,$page,$pagesize); + // CLOUD + // systemWebApps + }elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-4]=='cloud') and ($ex[$paracount-3] == 'system') and ($ex[$paracount-2] == 'webapps')){ + OC_OCS::systemwebapps($format); - // activityput - POST ACTIVITY - }elseif(($method=='post') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){ - $format=OC_OCS::readdata('format','text'); - $message=OC_OCS::readdata('message','text'); - OC_OCS::activityput($format,$message); + // quotaget + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'quota')){ + $user=$ex[$paracount-3]; + OC_OCS::quotaget($format,$user); - // PRIVATEDATA - // get - GET DATA - }elseif(($method=='get') and (strtolower($ex[$paracount-4])=='v1.php')and (strtolower($ex[$paracount-2])=='getattribute')){ - $format=OC_OCS::readdata('format','text'); - OC_OCS::privateDataGet($format); + // quotaset + }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'quota')){ + $user=$ex[$paracount-3]; + $quota = self::readData('post', 'quota', 'int'); + OC_OCS::quotaset($format,$user,$quota); - }elseif(($method=='get') and (strtolower($ex[$paracount-5])=='v1.php')and (strtolower($ex[$paracount-3])=='getattribute')){ - $format=OC_OCS::readdata('format','text'); - $app=$ex[$paracount-2]; - OC_OCS::privateDataGet($format, $app); - }elseif(($method=='get') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='getattribute')){ - $format=OC_OCS::readdata('format','text'); - $key=$ex[$paracount-2]; - $app=$ex[$paracount-3]; - OC_OCS::privateDataGet($format, $app,$key); + // keygetpublic + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){ + $user=$ex[$paracount-3]; + OC_OCS::publicKeyGet($format,$user); - // set - POST DATA - }elseif(($method=='post') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='setattribute')){ - $format=OC_OCS::readdata('format','text'); - $key=$ex[$paracount-2]; - $app=$ex[$paracount-3]; - $value=OC_OCS::readdata('value','text'); - OC_OCS::privatedataset($format, $app, $key, $value); - // delete - POST DATA - }elseif(($method=='post') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='deleteattribute')){ - $format=OC_OCS::readdata('format','text'); - $key=$ex[$paracount-2]; - $app=$ex[$paracount-3]; - OC_OCS::privatedatadelete($format, $app, $key); - - }else{ - $format=OC_OCS::readdata('format','text'); - $txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n"; - $txt.=OC_OCS::getdebugoutput(); - echo(OC_OCS::generatexml($format,'failed',999,$txt)); - } - exit(); - } - - /** - * generated some debug information to make it easier to find faild API calls - * @return debug data string - */ - private static function getDebugOutput() { - $txt=''; - $txt.="debug output:\n"; - if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n"; - if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n"; - if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n"; - if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n"; - return($txt); - } - - /** - * checks if the user is authenticated - * checks the IP whitlist, apikeys and login/password combination - * if $forceuser is true and the authentication failed it returns an 401 http response. - * if $forceuser is false and authentification fails it returns an empty username string - * @param bool $forceuser - * @return username string - */ - private static function checkPassword($forceuser=true) { - //valid user account ? - if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser=''; - if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw=''; - - if(empty($authuser)) { - if($forceuser){ - header('WWW-Authenticate: Basic realm="your valid user account or api key"'); - header('HTTP/1.0 401 Unauthorized'); - exit; - }else{ - $identifieduser=''; - } - }else{ - if(!OC_User::login($authuser,$authpw)){ - if($forceuser){ - header('WWW-Authenticate: Basic realm="your valid user account or api key"'); - header('HTTP/1.0 401 Unauthorized'); - exit; - }else{ - $identifieduser=''; - } - }else{ - $identifieduser=$authuser; - } - } - - return($identifieduser); - } + // keygetprivate + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ + $user=$ex[$paracount-3]; + OC_OCS::privateKeyGet($format,$user); - /** - * generates the xml or json response for the API call from an multidimenional data array. - * @param string $format - * @param string $status - * @param string $statuscode - * @param string $message - * @param array $data - * @param string $tag - * @param string $tagattribute - * @param int $dimension - * @param int $itemscount - * @param int $itemsperpage - * @return string xml/json - */ - private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') { - if($format=='json') { +// add more calls here +// please document all the call in the draft spec +// http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-1.7#CLOUD - $json=array(); - $json['status']=$status; - $json['statuscode']=$statuscode; - $json['message']=$message; - $json['totalitems']=$itemscount; - $json['itemsperpage']=$itemsperpage; - $json['data']=$data; - return(json_encode($json)); +// TODO: +// users +// groups +// bookmarks +// sharing +// versioning +// news (rss) - }else{ - $txt=''; - $writer = xmlwriter_open_memory(); - xmlwriter_set_indent( $writer, 2 ); - xmlwriter_start_document($writer ); - xmlwriter_start_element($writer,'ocs'); - xmlwriter_start_element($writer,'meta'); - xmlwriter_write_element($writer,'status',$status); - xmlwriter_write_element($writer,'statuscode',$statuscode); - xmlwriter_write_element($writer,'message',$message); - if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount); - if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage); - xmlwriter_end_element($writer); - if($dimension=='0') { - // 0 dimensions - xmlwriter_write_element($writer,'data',$data); - }elseif($dimension=='1') { - xmlwriter_start_element($writer,'data'); - foreach($data as $key=>$entry) { - xmlwriter_write_element($writer,$key,$entry); - } - xmlwriter_end_element($writer); + }else{ + $txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n"; + $txt.=OC_OCS::getdebugoutput(); + echo(OC_OCS::generatexml($format,'failed',999,$txt)); + } + exit(); + } - }elseif($dimension=='2') { - xmlwriter_start_element($writer,'data'); - foreach($data as $entry) { - xmlwriter_start_element($writer,$tag); - if(!empty($tagattribute)) { - xmlwriter_write_attribute($writer,'details',$tagattribute); - } - foreach($entry as $key=>$value) { - if(is_array($value)){ - foreach($value as $k=>$v) { - xmlwriter_write_element($writer,$k,$v); - } - } else { - xmlwriter_write_element($writer,$key,$value); - } - } - xmlwriter_end_element($writer); - } - xmlwriter_end_element($writer); + /** + * generated some debug information to make it easier to find faild API calls + * @return debug data string + */ + private static function getDebugOutput() { + $txt=''; + $txt.="debug output:\n"; + if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n"; + if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n"; + if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n"; + if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n"; + return($txt); + } - }elseif($dimension=='3') { - xmlwriter_start_element($writer,'data'); - foreach($data as $entrykey=>$entry) { - xmlwriter_start_element($writer,$tag); - if(!empty($tagattribute)) { - xmlwriter_write_attribute($writer,'details',$tagattribute); - } - foreach($entry as $key=>$value) { - if(is_array($value)){ - xmlwriter_start_element($writer,$entrykey); - foreach($value as $k=>$v) { - xmlwriter_write_element($writer,$k,$v); - } - xmlwriter_end_element($writer); - } else { - xmlwriter_write_element($writer,$key,$value); - } - } - xmlwriter_end_element($writer); - } - xmlwriter_end_element($writer); - }elseif($dimension=='dynamic') { - xmlwriter_start_element($writer,'data'); - OC_OCS::toxml($writer,$data,'comment'); - xmlwriter_end_element($writer); - } + /** + * checks if the user is authenticated + * checks the IP whitlist, apikeys and login/password combination + * if $forceuser is true and the authentication failed it returns an 401 http response. + * if $forceuser is false and authentification fails it returns an empty username string + * @param bool $forceuser + * @return username string + */ + private static function checkPassword($forceuser=true) { + //valid user account ? + if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser=''; + if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw=''; - xmlwriter_end_element($writer); + if(empty($authuser)) { + if($forceuser){ + header('WWW-Authenticate: Basic realm="your valid user account or api key"'); + header('HTTP/1.0 401 Unauthorized'); + exit; + }else{ + $identifieduser=''; + } + }else{ + if(!OC_User::login($authuser,$authpw)){ + if($forceuser){ + header('WWW-Authenticate: Basic realm="your valid user account or api key"'); + header('HTTP/1.0 401 Unauthorized'); + exit; + }else{ + $identifieduser=''; + } + }else{ + $identifieduser=$authuser; + } + } - xmlwriter_end_document( $writer ); - $txt.=xmlwriter_output_memory( $writer ); - unset($writer); - return($txt); - } - } + return($identifieduser); + } - public static function toXml($writer,$data,$node) { - foreach($data as $key => $value) { - if (is_numeric($key)) { - $key = $node; - } - if (is_array($value)){ - xmlwriter_start_element($writer,$key); - OC_OCS::toxml($writer,$value,$node); - xmlwriter_end_element($writer); - }else{ - xmlwriter_write_element($writer,$key,$value); - } - } - } + /** + * generates the xml or json response for the API call from an multidimenional data array. + * @param string $format + * @param string $status + * @param string $statuscode + * @param string $message + * @param array $data + * @param string $tag + * @param string $tagattribute + * @param int $dimension + * @param int $itemscount + * @param int $itemsperpage + * @return string xml/json + */ + private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') { + if($format=='json') { + $json=array(); + $json['status']=$status; + $json['statuscode']=$statuscode; + $json['message']=$message; + $json['totalitems']=$itemscount; + $json['itemsperpage']=$itemsperpage; + $json['data']=$data; + return(json_encode($json)); + }else{ + $txt=''; + $writer = xmlwriter_open_memory(); + xmlwriter_set_indent( $writer, 2 ); + xmlwriter_start_document($writer ); + xmlwriter_start_element($writer,'ocs'); + xmlwriter_start_element($writer,'meta'); + xmlwriter_write_element($writer,'status',$status); + xmlwriter_write_element($writer,'statuscode',$statuscode); + xmlwriter_write_element($writer,'message',$message); + if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount); + if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage); + xmlwriter_end_element($writer); + if($dimension=='0') { + // 0 dimensions + xmlwriter_write_element($writer,'data',$data); + + }elseif($dimension=='1') { + xmlwriter_start_element($writer,'data'); + foreach($data as $key=>$entry) { + xmlwriter_write_element($writer,$key,$entry); + } + xmlwriter_end_element($writer); + + }elseif($dimension=='2') { + xmlwriter_start_element($writer,'data'); + foreach($data as $entry) { + xmlwriter_start_element($writer,$tag); + if(!empty($tagattribute)) { + xmlwriter_write_attribute($writer,'details',$tagattribute); + } + foreach($entry as $key=>$value) { + if(is_array($value)){ + foreach($value as $k=>$v) { + xmlwriter_write_element($writer,$k,$v); + } + } else { + xmlwriter_write_element($writer,$key,$value); + } + } + xmlwriter_end_element($writer); + } + xmlwriter_end_element($writer); + + }elseif($dimension=='3') { + xmlwriter_start_element($writer,'data'); + foreach($data as $entrykey=>$entry) { + xmlwriter_start_element($writer,$tag); + if(!empty($tagattribute)) { + xmlwriter_write_attribute($writer,'details',$tagattribute); + } + foreach($entry as $key=>$value) { + if(is_array($value)){ + xmlwriter_start_element($writer,$entrykey); + foreach($value as $k=>$v) { + xmlwriter_write_element($writer,$k,$v); + } + xmlwriter_end_element($writer); + } else { + xmlwriter_write_element($writer,$key,$value); + } + } + xmlwriter_end_element($writer); + } + xmlwriter_end_element($writer); + }elseif($dimension=='dynamic') { + xmlwriter_start_element($writer,'data'); + OC_OCS::toxml($writer,$data,'comment'); + xmlwriter_end_element($writer); + } + + xmlwriter_end_element($writer); + + xmlwriter_end_document( $writer ); + $txt.=xmlwriter_output_memory( $writer ); + unset($writer); + return($txt); + } + } + + public static function toXml($writer,$data,$node) { + foreach($data as $key => $value) { + if (is_numeric($key)) { + $key = $node; + } + if (is_array($value)){ + xmlwriter_start_element($writer,$key); + OC_OCS::toxml($writer,$value,$node); + xmlwriter_end_element($writer); + }else{ + xmlwriter_write_element($writer,$key,$value); + } + } + } - /** - * return the config data of this server - * @param string $format - * @return string xml/json - */ - private static function apiConfig($format) { - $user=OC_OCS::checkpassword(false); - $url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'],0,-11).''; + /** + * return the config data of this server + * @param string $format + * @return string xml/json + */ + private static function apiConfig($format) { + $user=OC_OCS::checkpassword(false); + $url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'],0,-11).''; - $xml['version']='1.5'; - $xml['website']='ownCloud'; - $xml['host']=OCP\Util::getServerHost(); - $xml['contact']=''; - $xml['ssl']='false'; - echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1)); - } + $xml['version']='1.7'; + $xml['website']='ownCloud'; + $xml['host']=OCP\Util::getServerHost(); + $xml['contact']=''; + $xml['ssl']='false'; + echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1)); + } - /** - * check if the provided login/apikey/password is valid - * @param string $format - * @param string $login - * @param string $passwd - * @return string xml/json - */ - private static function personCheck($format,$login,$passwd) { - if($login<>''){ - if(OC_User::login($login,$passwd)){ - $xml['person']['personid']=$login; - echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2)); - }else{ - echo(OC_OCS::generatexml($format,'failed',102,'login not valid')); - } - }else{ - echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields')); - } - } + /** + * check if the provided login/apikey/password is valid + * @param string $format + * @param string $login + * @param string $passwd + * @return string xml/json + */ + private static function personCheck($format,$login,$passwd) { + if($login<>''){ + if(OC_User::login($login,$passwd)){ + $xml['person']['personid']=$login; + echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2)); + }else{ + echo(OC_OCS::generatexml($format,'failed',102,'login not valid')); + } + }else{ + echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields')); + } + } - // ACTIVITY API ############################################# + // ACTIVITY API ############################################# - /** - * get my activities - * @param string $format - * @param string $page - * @param string $pagesize - * @return string xml/json - */ - private static function activityGet($format,$page,$pagesize) { - $user=OC_OCS::checkpassword(); - - //TODO + /** + * get my activities + * @param string $format + * @param string $page + * @param string $pagesize + * @return string xml/json + */ + private static function activityGet($format,$page,$pagesize) { + $user=OC_OCS::checkpassword(); - $txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize); - echo($txt); - } + //TODO - /** - * submit a activity - * @param string $format - * @param string $message - * @return string xml/json - */ - private static function activityPut($format,$message) { - // not implemented in ownCloud - $user=OC_OCS::checkpassword(); - echo(OC_OCS::generatexml($format,'ok',100,'')); - } + $txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize); + echo($txt); + } - // PRIVATEDATA API ############################################# + /** + * submit a activity + * @param string $format + * @param string $message + * @return string xml/json + */ + private static function activityPut($format,$message) { + // not implemented in ownCloud + $user=OC_OCS::checkpassword(); + echo(OC_OCS::generatexml($format,'ok',100,'')); + } - /** - * get private data and create the xml for ocs - * @param string $format - * @param string $app - * @param string $key - * @return string xml/json - */ - private static function privateDataGet($format,$app="",$key="") { - $user=OC_OCS::checkpassword(); - $result=OC_OCS::getData($user,$app,$key); - $xml=array(); - foreach($result as $i=>$log) { - $xml[$i]['key']=$log['key']; - $xml[$i]['app']=$log['app']; - $xml[$i]['value']=$log['value']; - } + // PRIVATEDATA API ############################################# + + /** + * get private data and create the xml for ocs + * @param string $format + * @param string $app + * @param string $key + * @return string xml/json + */ + private static function privateDataGet($format,$app="",$key="") { + $user=OC_OCS::checkpassword(); + $result=OC_OCS::getData($user,$app,$key); + $xml=array(); + foreach($result as $i=>$log) { + $xml[$i]['key']=$log['key']; + $xml[$i]['app']=$log['app']; + $xml[$i]['value']=$log['value']; + } - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it - echo($txt); - } + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it + echo($txt); + } - /** - * set private data referenced by $key to $value and generate the xml for ocs - * @param string $format - * @param string $app - * @param string $key - * @param string $value - * @return string xml/json - */ + /** + * set private data referenced by $key to $value and generate the xml for ocs + * @param string $format + * @param string $app + * @param string $key + * @param string $value + * @return string xml/json + */ private static function privateDataSet($format, $app, $key, $value) { $user=OC_OCS::checkpassword(); if(OC_OCS::setData($user,$app,$key,$value)){ @@ -529,4 +555,134 @@ class OC_OCS { public static function deleteData($user, $app, $key) { return OC_Preferences::deleteKey($user,$app,$key); } + + + // CLOUD API ############################################# + + /** + * get a list of installed web apps + * @param string $format + * @return string xml/json + */ + private static function systemWebApps($format) { + $login=OC_OCS::checkpassword(); + $apps=OC_App::getEnabledApps(); + $values=array(); + foreach($apps as $app) { + $info=OC_App::getAppInfo($app); + if(isset($info['standalone'])) { + $newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>''); + $values[]=$newvalue; + } + + } + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $values, 'cloud', '', 2, 0, 0); + echo($txt); + + } + + + /** + * get the quota of a user + * @param string $format + * @param string $user + * @return string xml/json + */ + private static function quotaGet($format,$user) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { + + if(OC_User::userExists($user)){ + // calculate the disc space + $user_dir = '/'.$user.'/files'; + OC_Filesystem::init($user_dir); + $rootInfo=OC_FileCache::get(''); + $sharedInfo=OC_FileCache::get('/Shared'); + $used=$rootInfo['size']-$sharedInfo['size']; + $free=OC_Filesystem::free_space(); + $total=$free+$used; + if($total==0) $total=1; // prevent division by zero + $relative=round(($used/$total)*10000)/100; + + $xml=array(); + $xml['quota']=$total; + $xml['free']=$free; + $xml['used']=$used; + $xml['relative']=$relative; + + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + + /** + * set the quota of a user + * @param string $format + * @param string $user + * @param string $quota + * @return string xml/json + */ + private static function quotaSet($format,$user,$quota) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin')) { + + // todo + // not yet implemented + // add logic here + error_log('OCS call: user:'.$user.' quota:'.$quota); + + $xml=array(); + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + + /** + * get the public key of a user + * @param string $format + * @param string $user + * @return string xml/json + */ + private static function publicKeyGet($format,$user) { + $login=OC_OCS::checkpassword(); + + if(OC_User::userExists($user)){ + // calculate the disc space + $txt='this is the public key of '.$user; + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + } + + /** + * get the private key of a user + * @param string $format + * @param string $user + * @return string xml/json + */ + private static function privateKeyGet($format,$user) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { + + if(OC_User::userExists($user)){ + // calculate the disc space + $txt='this is the private key of '.$user; + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + + } From e32b2c8121c4da6df156bdf1ea7f6683e5692aa6 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 24 Jul 2012 18:22:57 +0200 Subject: [PATCH 005/315] moved to ocs.php from master and added dummy functions for the keyserver --- lib/ocs.php | 141 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 115 insertions(+), 26 deletions(-) diff --git a/lib/ocs.php b/lib/ocs.php index 3157aae99e..218f7a9312 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -650,17 +650,39 @@ class OC_OCS { * @param string $user * @return string xml/json */ - private static function publicKeyGet($format,$user) { - $login=OC_OCS::checkpassword(); - - if(OC_User::userExists($user)){ - // calculate the disc space - $txt='this is the public key of '.$user; - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); - } - } + private static function publicKeyGet($format, $user) { + $login=OC_OCS::checkpassword(); + if(OC_User::userExists($user)){ + //TODO: GET public key + $xml=array(); + $xml['key']="this is the public key of $user"; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + } + + /** + * set the public key of a user + * @param string $format + * @param string $user + * @param string $key + * @return string xml/json + */ + private static function publicKeySet($format, $user, $key) { + $login=OC_OCS::checkpassword(); + if($login == $user) { + if(OC_User::userExists($user)){ + //TODO: SET public key + echo self::generateXml('', 'ok', 100, 'Public key uploaded'); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } /** * get the private key of a user @@ -668,21 +690,88 @@ class OC_OCS { * @param string $user * @return string xml/json */ - private static function privateKeyGet($format,$user) { - $login=OC_OCS::checkpassword(); - if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { - - if(OC_User::userExists($user)){ - // calculate the disc space - $txt='this is the private key of '.$user; - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); - } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - } + private static function privateKeyGet($format, $user) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { + if(OC_User::userExists($user)){ + //TODO: GET private key + $xml=array(); + $xml['key']="this is the private key of $user"; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + + /** + * set the private key of a user + * @param string $format + * @param string $user + * @param string $key + * @return string xml/json + */ + private static function privateKeySet($format, $user, $key) { + $login=OC_OCS::checkpassword(); + if($login == $user) { + if(OC_User::userExists($user)){ + //TODO: SET private key + echo self::generateXml('', 'ok', 100, 'Private key uploaded'); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + /** + * get the encryption key of a file + * @param string $format + * @param string $user + * @param string $file + * @return string xml/json + */ + private static function privateKeyGet($format, $user, $file) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { + if(OC_User::userExists($user)){ + //TODO: GET file key + $xml=array(); + $xml['key']="this is the key for $file"; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + + /** + * set the encryption keyn of a file + * @param string $format + * @param string $user + * @param string $file + * @param string $key + * @return string xml/json + */ + private static function privateKeySet($format, $user, $file, $key) { + $login=OC_OCS::checkpassword(); + if($login == $user) { + if(OC_User::userExists($user)){ + //TODO: SET file key + echo self::generateXml('', 'ok', 100, 'File key uploaded'); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } } From 92162898567c5b19e0119b63484e3beb228c5490 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 24 Jul 2012 17:53:12 +0100 Subject: [PATCH 006/315] Wrote new methods for testing if a file is encrypted using AES or Blowfish Added more unit tests for crypt class Added new method for generating 16 character pseudo-random initialisation vectors Started writing new methods for handling legacy keys and en/de/re cryption Added comments to lib/filecache.php explaining expected $path type --- apps/files_encryption/lib/crypt.php | 98 ++++++++++++++- apps/files_encryption/lib/util.php | 118 ++++++++++++++++++ apps/files_encryption/tests/encryption.php | 44 ++++++- .../tests/legacy-encrypted-text.txt | Bin 0 -> 3360 bytes lib/filecache.php | 10 +- 5 files changed, 261 insertions(+), 9 deletions(-) create mode 100644 apps/files_encryption/tests/legacy-encrypted-text.txt diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 098074c228..668101014a 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -50,6 +50,66 @@ class Crypt { } + /** + * @brief Check if a file's contents contains an IV and is symmetrically encrypted + * @return true / false + */ + public static function isEncryptedContent( $content ) { + + if ( !$content ) { + + return false; + + } + + // Fetch encryption metadata from end of file + $meta = substr( $content, -22 ); + + // Fetch IV from end of file + $iv = substr( $meta, -16 ); + + // Fetch identifier from start of metadata + $identifier = substr( $meta, 0, 6 ); + + if ( $identifier == '00iv00') { + + return true; + + } else { + + return false; + + } + + } + + /** + * @brief Check if a file is encrypted via legacy system + * @return true / false + */ + public static function isLegacyEncryptedContent( $content, $path ) { + + // Fetch all file metadata from DB + $metadata = \OC_FileCache_Cached::get( $content, '' ); + + // If a file is flagged with encryption in DB, but isn't a valid content + IV combination, it's probably using the legacy encryption system + if ( + $content + and isset( $metadata['encrypted'] ) + and $metadata['encrypted'] === true + and !self::isEncryptedContent( $content ) + ) { + + return true; + + } else { + + return false; + + } + + } + /** * @brief Symmetrically encrypt a string * @returns encrypted file @@ -106,13 +166,12 @@ class Crypt { } - $random = openssl_random_pseudo_bytes( 13 ); - - $iv = substr( base64_encode( $random ), 0, -4 ); + $iv = self::generateIv(); if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { - $combinedKeyfile = $encryptedContent .= $iv; + // Combine content to encrypt with IV identifier and actual IV + $combinedKeyfile = $encryptedContent . '00iv00' . $iv; return $combinedKeyfile; @@ -143,9 +202,11 @@ class Crypt { } + // Fetch IV from end of file $iv = substr( $keyfileContent, -16 ); - $encryptedContent = substr( $keyfileContent, 0, -16 ); + // Remove IV and IV identifier text to expose encrypted content + $encryptedContent = substr( $keyfileContent, 0, -22 ); if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) { @@ -269,6 +330,33 @@ class Crypt { } + /** + * @brief Generate a pseudo random 1024kb ASCII key + * @returns $key Generated key + */ + public static function generateIv() { + + if ( $random = openssl_random_pseudo_bytes( 13, $strong ) ) { + + if ( !$strong ) { + + // If OpenSSL indicates randomness is insecure, log error + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); + + } + + $iv = substr( base64_encode( $random ), 0, -4 ); + + return $iv; + + } else { + + return false; + + } + + } + /** * @brief Generate a pseudo random 1024kb ASCII key * @returns $key Generated key diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 62b435583e..5185ad351d 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -37,6 +37,23 @@ namespace OCA_Encryption; class Util { + # DONE: add method to check if file is encrypted using new system + # DONE: add method to check if file is encrypted using old system + # TODO: add method to encrypt all user files using new system + # TODO: add method to decrypt all user files using new system + # TODO: add method to encrypt all user files using old system + # TODO: add method to decrypt all user files using old system + # TODO: fix / test the crypt stream proxy class + # TODO: add support for optional recovery user in case of lost passphrase / keys + # TODO: add admin optional required long passphrase for users + # TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc. + # TODO: add UI buttons for encrypt / decrypt everything? + + # TODO: test new encryption with webdav + # TODO: test new encryption with versioning + # TODO: test new encryption with sharing + # TODO: test new encryption with proxies + private $view; // OC_FilesystemView object for filesystem operations private $pwd; // User Password private $client; // Client side encryption mode flag @@ -73,6 +90,10 @@ class Util { } + /** + * @brief Sets up encryption folders and keys for a user + * @param $passphrase passphrase to encrypt server-stored private key with + */ public function setup( $passphrase = null ) { $publicKeyFileName = 'encryption.public.key'; @@ -129,5 +150,102 @@ class Util { } } + + /** + * @brief Fetch the legacy encryption key from user files + * @param string $login used to locate the legacy key + * @param string $passphrase used to decrypt the legacy key + * @return true / false + * + * if the key is left out, the default handeler will be used + */ + public function getLegacyKey( $login, $passphrase ) { + + OC_FileProxy::$enabled = false; + + if ( + $login + and $passphrase + and $key = $this->view->file_get_contents( '/' . $login . '/encryption.key' ) + ) { + + OC_FileProxy::$enabled = true; + + return $this->legacyDecrypt( $key, $passphrase ); + + } else { + + OC_FileProxy::$enabled = true; + + return false; + + } + + } + + /** + * @brief Get the blowfish encryption handeler for a key + * @param $key string (optional) + * @return Crypt_Blowfish blowfish object + * + * if the key is left out, the default handeler will be used + */ + public function getBlowfish( $key = '' ) { + + if( $key ){ + + return new Crypt_Blowfish($key); + + } else { + + return false; + + } + + } + + /** + * @brief encrypts content using legacy blowfish system + * @param $content the cleartext message you want to encrypt + * @param $key the encryption key (optional) + * @returns encrypted content + * + * This function encrypts an content + */ + public static function legacyEncrypt( $content, $key='') { + $bf = self::getBlowfish($key); + return $bf->encrypt($content); + } + + /** + * @brief decryption of an content + * @param $content the cleartext message you want to decrypt + * @param $key the encryption key (optional) + * @returns cleartext content + * + * This function decrypts an content + */ + public static function legacyDecrypt( $content, $key = '' ) { + + $bf = $this->getBlowfish( $key ); + + $data = $bf->decrypt( $content ); + + return $data; + + } + + /** + * @brief Re-encryptes a legacy blowfish encrypted file using AES with integrated IV + * @param $legacyContent the legacy encrypted content to re-encrypt + * @returns cleartext content + * + * This function decrypts an content + */ + public function legacyRecrypt( $legacyContent ) { + + # TODO: write me + + } } diff --git a/apps/files_encryption/tests/encryption.php b/apps/files_encryption/tests/encryption.php index 600e00fd3e..9246e71526 100644 --- a/apps/files_encryption/tests/encryption.php +++ b/apps/files_encryption/tests/encryption.php @@ -1,19 +1,22 @@ + * Copyright (c) 2012 Sam Tuke , and + * Robin Appelman * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ require realpath( dirname(__FILE__).'/../lib/crypt.php' ); +//require realpath( dirname(__FILE__).'/../../../lib/filecache.php' ); class Test_Encryption extends UnitTestCase { - + function setUp() { // set content for encrypting / decrypting in tests $this->data = realpath( dirname(__FILE__).'/../lib/crypt.php' ); + $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' ); } @@ -25,10 +28,22 @@ class Test_Encryption extends UnitTestCase { $key = OCA_Encryption\Crypt::generateKey(); + $this->assertTrue( $key ); + $this->assertTrue( strlen( $key ) > 1000 ); } + function testGenerateIv() { + + $iv = OCA_Encryption\Crypt::generateIv(); + + $this->assertTrue( $iv ); + + $this->assertTrue( strlen( $iv ) == 16 ); + + } + function testEncrypt() { $random = openssl_random_pseudo_bytes( 13 ); @@ -85,6 +100,31 @@ class Test_Encryption extends UnitTestCase { } + function testIsEncryptedContent() { + + $this->assertFalse( OCA_Encryption\Crypt::isEncryptedContent( $this->data ) ); + + $this->assertFalse( OCA_Encryption\Crypt::isEncryptedContent( $this->legacyEncryptedData ) ); + + $keyfileContent = OCA_Encryption\Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); + + $this->assertTrue( OCA_Encryption\Crypt::isEncryptedContent( $keyfileContent ) ); + + } + +// // Cannot use this test for now due to hidden dependencies in OC_FileCache +// function testIsLegacyEncryptedContent() { +// +// $keyfileContent = OCA_Encryption\Crypt::symmetricEncryptFileContent( $this->legacyEncryptedData, 'hat' ); +// +// $this->assertFalse( OCA_Encryption\Crypt::isLegacyEncryptedContent( $keyfileContent, '/files/admin/test.txt' ) ); +// +// OC_FileCache::put( '/admin/files/legacy-encrypted-test.txt', $this->legacyEncryptedData ); +// +// $this->assertTrue( OCA_Encryption\Crypt::isLegacyEncryptedContent( $this->legacyEncryptedData, '/files/admin/test.txt' ) ); +// +// } + function testMultiKeyEncrypt() { # TODO: search in keyfile for actual content as IV will ensure this test always passes diff --git a/apps/files_encryption/tests/legacy-encrypted-text.txt b/apps/files_encryption/tests/legacy-encrypted-text.txt new file mode 100644 index 0000000000000000000000000000000000000000..cb5bf50550d91842c8a0bd214edf9569daeadc48 GIT binary patch literal 3360 zcmXw*_dgVlAIF^#&dQ8V;*3s6r!zj3bymjNJ2E5d2pK2qV8@Fd8~lKcGMxckFp=W&Z&lG`Cl?qvq{7g*T22nF6ox6|SsasI8LEsos-DQ9aF#yai`s+bS3y; zP~n~gPaL~TTZh~^y~4|1$r7qeeU{_@!NsMTc~KRVr*kizynmnkV=~`Fo`k4$+15y&=!O1shrP6Slv8>km%C05-hdr*BoA8wIc~wZ>O;{-y-hbAP z=z_BE(nj#Y0y70RLPN|^y&9vU_m;-bsEWf$wn|+j22y@?@JsQO$GCTHY?s8oU75`c zg*Y$P$imS;qfirK@~t^_9HzgHabAaJO^PB96K9BFqyl*5CpH#KCy*t~R$qP1&^Yzq zk3kXBn;QATNd?CIEFb-T%&$++2@vql1B$+QG{L$YwK8X96viQZKm$^=eL&!3*u!(= zSpH!7d)q5M0mGO?{yxfQH)DhUP`K(cXD0ttu1#fnE$43Z8mQK`a9q~jU6T3v!J zTXF1R1|qdJ^9|f|)#TJcI0zKJ8xK8v=R_gbtjT>ENw*&rbulIRHt4()s?tXkpVevcL`m*8f?Kp17<$~W; z`y#&MLkL(UG};~QtNiVenZy09^$a&q=bhbBl6$lgqWI?EG>op-caN}{&1D~qOdrV# zkI=d+BJ;q!6=6rrdXhtbq=2JL;?3L#nv2ck4H_`E%L6>b3{|AveTJA>qoEKGMmVl z*c>Ez>rImsfclTOW6*Lp>EisY42PsSq^5^huHw@u85!~Vx>+-kClVBDh;IsZ zo^P=*h}ft;n~{EC>@#C2{$~}yA(88P1vLCO!Cwfq{4j&asg5p>FM3*Gw~^$Qjvab1 ztGH!hA1|sT)G;`@F(vcv0uOpKaNp5b-AM$~GO%2Z6aeP=h(tW`cin!fK3`FpcdD+5 zn@IIkbi@<=exISY?w!racU8NGo?AW|&5hEIh-nKEkmV;n>-X6$hoQKR=V}KcR!PNU ztW05aR*mv{NO{=Plcpj4f0N4vyG9t$z7DStx<92(y=aEpl_0?smB&j`##X^3lV_RD zWRBiiN%VGCkKyQBGI&x%C*ciKYSgi5x`;YsvWmYf)#u%xTnMQL8dlmHs-3#1ljGX3 zXJJ%upwIoM@sE1xHKDvO`^f9J&tvwLfHjh<_D->q=&7=slQ}Nr=)(Vdagwyk35-a1 zH0#ABVRy_vuqPfY{X1k^vt^yXER5^JcBLJNX2SODYdokf$=!sHI$7SEn*lzRa->FdOP>-2DrnC^5 zDk0OdTcMBmoQWfJ&8G^)f}<1pV>RB=Qc9#+_63Q{1|qj--iCH4FVoH3D7@ofs!tmT zMC`41I?=1Htn0LnKP(CSPD@Wb)z=^S`9@Fn{gc^$U8UXnsQRe~2H!Lj-r0`sHH5b= zm|?rbO)J!aSyX-ktX!#$kH;YkDSMgQ1OEEURah2CeE{-lmOlw5M7q>S=a4Qe7mmX&P1*WTz~I9JsC1 zeJyl#i9m>Hf=q30Bd}@06AqhuA;#BSgXn|@$lE;CX_P5lk+f=w`qU$@Am&PL*S!4c zRN22OW|_>C+6>3BR||3(Xhp8LH{hhanRC9!zeyie*rJ~pFSWk*c~61w8`rmL4bBNe z)pN2+z?LKc#n3Dtbu-_E9i7lHx%3FweIp3xJDtqaQ!&B8c&`P_P}W8p0-iM`*m^y` zR~nAO(0&Qd#F%hm6cH?FEm`sl?T$J|%lFO|n6t1&**a#DucE2!HLutGIac3V{vn?! z(&SbH#~gfZ=qw*lX7C9IExH{=uo22;$TdzAs9BW~AS)(niq!$R6MuDmf4PL5De5)_ z5zdpWK02EWi~q4XdcW?W2Yks0zoXgyiFTfy{bR-jyfQbldUaxctg|A3gOeridX2Y{w8(G(WAS=x8%{JyLovPe06_FrqH6856a!ez@Guv#_ftsb?dxtiKHN7nr-=M0^pU& zSI=;>Hliyt3F7v1sN(}F9@@P;0Uhs!Ay&bDd}tz+%hlItxwoT6_l5Fulw(ZQVZxy} zXJk2(s`GL8@}Mfuj)u11vRF8UR`2I31zQk=vsx|ri>uZ3J_<5lqLfZlTlu`afO0b7 zctIKRm#(5XzU%zU$bfd6Geoj$j*8?vIA7<)QfTP-7;LHUtet+GO2eJS-HkGhxuWD29(6TlL{qhT)T>lV zZ~kI< zCx*YfkY%u-s43Rym5J;$4H4z{clZ+VO&`CJW#7jP?AQ1wR^U+ TWaK9_8%OLm9CpY~&*%LQ#;b)= literal 0 HcmV?d00001 diff --git a/lib/filecache.php b/lib/filecache.php index d956f34dc4..8894c8a3eb 100644 --- a/lib/filecache.php +++ b/lib/filecache.php @@ -23,10 +23,16 @@ * provide caching for filesystem info in the database * * not used by OC_Filesystem for reading filesystem info, - * instread apps should use OC_FileCache::get where possible + * instead apps should use OC_FileCache::get where possible + * + * It will try to keep the data up to date but changes from outside + * ownCloud can invalidate the cache + * + * Methods that take $path and $root params expect $path to be relative, like + * /admin/files/file.txt, if $root is false * - * It will try to keep the data up to date but changes from outside ownCloud can invalidate the cache */ + class OC_FileCache{ /** * get the filesystem info from the cache From 9368ea73c862b2069d3de5cac6ad7827ab33591c Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 25 Jul 2012 12:38:40 +0100 Subject: [PATCH 007/315] added tests and methods relating to handling of legacy keys --- apps/files_encryption/lib/util.php | 88 ++++++++++++---------- apps/files_encryption/tests/encryption.php | 15 +--- apps/files_encryption/tests/util.php | 72 ++++++++++++++++++ 3 files changed, 123 insertions(+), 52 deletions(-) create mode 100644 apps/files_encryption/tests/util.php diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 5185ad351d..c7d9ec07d6 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -39,6 +39,8 @@ class Util { # DONE: add method to check if file is encrypted using new system # DONE: add method to check if file is encrypted using old system + # DONE: add method to fetch legacy key + # DONE: add method to decrypt legacy encrypted data # TODO: add method to encrypt all user files using new system # TODO: add method to decrypt all user files using new system # TODO: add method to encrypt all user files using old system @@ -151,38 +153,6 @@ class Util { } - /** - * @brief Fetch the legacy encryption key from user files - * @param string $login used to locate the legacy key - * @param string $passphrase used to decrypt the legacy key - * @return true / false - * - * if the key is left out, the default handeler will be used - */ - public function getLegacyKey( $login, $passphrase ) { - - OC_FileProxy::$enabled = false; - - if ( - $login - and $passphrase - and $key = $this->view->file_get_contents( '/' . $login . '/encryption.key' ) - ) { - - OC_FileProxy::$enabled = true; - - return $this->legacyDecrypt( $key, $passphrase ); - - } else { - - OC_FileProxy::$enabled = true; - - return false; - - } - - } - /** * @brief Get the blowfish encryption handeler for a key * @param $key string (optional) @@ -192,9 +162,9 @@ class Util { */ public function getBlowfish( $key = '' ) { - if( $key ){ + if ( $key ) { - return new Crypt_Blowfish($key); + return new \Crypt_Blowfish( $key ); } else { @@ -204,6 +174,43 @@ class Util { } + /** + * @brief Fetch the legacy encryption key from user files + * @param string $login used to locate the legacy key + * @param string $passphrase used to decrypt the legacy key + * @return true / false + * + * if the key is left out, the default handeler will be used + */ + public function getLegacyKey( $passphrase ) { + + //OC_FileProxy::$enabled = false; + + if ( + $passphrase + and $key = $this->view->file_get_contents( '/encryption.key' ) + ) { + + //OC_FileProxy::$enabled = true; + + if ( $this->legacyKey = $this->legacyDecrypt( $key, $passphrase ) ) { + + return true; + + } else { + + return false; + + } + + } else { + + return false; + + } + + } + /** * @brief encrypts content using legacy blowfish system * @param $content the cleartext message you want to encrypt @@ -212,9 +219,12 @@ class Util { * * This function encrypts an content */ - public static function legacyEncrypt( $content, $key='') { - $bf = self::getBlowfish($key); - return $bf->encrypt($content); + public function legacyEncrypt( $content, $passphrase = '' ) { + + $bf = $this->getBlowfish( $passphrase ); + + return $bf->encrypt( $content ); + } /** @@ -225,9 +235,9 @@ class Util { * * This function decrypts an content */ - public static function legacyDecrypt( $content, $key = '' ) { + public function legacyDecrypt( $content, $passphrase = '' ) { - $bf = $this->getBlowfish( $key ); + $bf = $this->getBlowfish( $passphrase ); $data = $bf->decrypt( $content ); diff --git a/apps/files_encryption/tests/encryption.php b/apps/files_encryption/tests/encryption.php index 9246e71526..ed3b65b179 100644 --- a/apps/files_encryption/tests/encryption.php +++ b/apps/files_encryption/tests/encryption.php @@ -8,6 +8,7 @@ */ require realpath( dirname(__FILE__).'/../lib/crypt.php' ); +require realpath( dirname(__FILE__).'/../lib/util.php' ); //require realpath( dirname(__FILE__).'/../../../lib/filecache.php' ); class Test_Encryption extends UnitTestCase { @@ -16,6 +17,7 @@ class Test_Encryption extends UnitTestCase { // set content for encrypting / decrypting in tests $this->data = realpath( dirname(__FILE__).'/../lib/crypt.php' ); + $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' ); $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' ); } @@ -112,19 +114,6 @@ class Test_Encryption extends UnitTestCase { } -// // Cannot use this test for now due to hidden dependencies in OC_FileCache -// function testIsLegacyEncryptedContent() { -// -// $keyfileContent = OCA_Encryption\Crypt::symmetricEncryptFileContent( $this->legacyEncryptedData, 'hat' ); -// -// $this->assertFalse( OCA_Encryption\Crypt::isLegacyEncryptedContent( $keyfileContent, '/files/admin/test.txt' ) ); -// -// OC_FileCache::put( '/admin/files/legacy-encrypted-test.txt', $this->legacyEncryptedData ); -// -// $this->assertTrue( OCA_Encryption\Crypt::isLegacyEncryptedContent( $this->legacyEncryptedData, '/files/admin/test.txt' ) ); -// -// } - function testMultiKeyEncrypt() { # TODO: search in keyfile for actual content as IV will ensure this test always passes diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php new file mode 100644 index 0000000000..f24b164205 --- /dev/null +++ b/apps/files_encryption/tests/util.php @@ -0,0 +1,72 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +require realpath( dirname(__FILE__).'/../lib/crypt.php' ); +require realpath( dirname(__FILE__).'/../lib/util.php' ); + +class Test_Encryption extends UnitTestCase { + + function setUp() { + + // set content for encrypting / decrypting in tests + $this->data = realpath( dirname(__FILE__).'/../lib/crypt.php' ); + $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' ); + $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' ); + + $this->view = new OC_FilesystemView( '/admin' ); + + } + + function tearDown(){} + +// // Cannot use this test for now due to hidden dependencies in OC_FileCache +// function testIsLegacyEncryptedContent() { +// +// $keyfileContent = OCA_Encryption\Crypt::symmetricEncryptFileContent( $this->legacyEncryptedData, 'hat' ); +// +// $this->assertFalse( OCA_Encryption\Crypt::isLegacyEncryptedContent( $keyfileContent, '/files/admin/test.txt' ) ); +// +// OC_FileCache::put( '/admin/files/legacy-encrypted-test.txt', $this->legacyEncryptedData ); +// +// $this->assertTrue( OCA_Encryption\Crypt::isLegacyEncryptedContent( $this->legacyEncryptedData, '/files/admin/test.txt' ) ); +// +// } + +// // Cannot use this test for now due to need for different root in OC_Filesystem_view class +// function testGetLegacyKey() { +// +// $c = new \OCA_Encryption\Util( $view, false ); +// +// $bool = $c->getLegacyKey( 'admin' ); +// +// $this->assertTrue( $bool ); +// +// $this->assertTrue( $c->legacyKey ); +// +// $this->assertTrue( is_int( $c->legacyKey ) ); +// +// $this->assertTrue( strlen( $c->legacyKey ) == 20 ); +// +// } + +// // Cannot use this test for now due to need for different root in OC_Filesystem_view class +// function testLegacyDecrypt() { +// +// $c = new OCA_Encryption\Util( $this->view, false ); +// +// $bool = $c->getLegacyKey( 'admin' ); +// +// $encrypted = $c->legacyEncrypt( $this->data, $c->legacyKey ); +// +// $decrypted = $c->legacyDecrypt( $encrypted, $c->legacyKey ); +// +// $this->assertEqual( $decrypted, $this->data ); +// +// } + +} \ No newline at end of file From d766ca8b19c8ac93ac42650cf98cca66ad947309 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 25 Jul 2012 15:33:25 +0100 Subject: [PATCH 008/315] Changed util class methods to use / create public keys in single shared public-keys directory, and group encryption-related user files --- apps/files_encryption/lib/util.php | 83 +++++++++++++++--------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index c7d9ec07d6..e876e886c4 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -32,7 +32,10 @@ namespace OCA_Encryption; /** - * Class for utilities relating to encrypted file storage system + * @brief Class for utilities relating to encrypted file storage system + * @param $view OC_FilesystemView object, expected to have OC '/' as root path + * @param $client flag indicating status of client side encryption. Currently + * unused, likely to become obsolete shortly */ class Util { @@ -41,10 +44,12 @@ class Util { # DONE: add method to check if file is encrypted using old system # DONE: add method to fetch legacy key # DONE: add method to decrypt legacy encrypted data + # TODO: add method to encrypt all user files using new system # TODO: add method to decrypt all user files using new system # TODO: add method to encrypt all user files using old system # TODO: add method to decrypt all user files using old system + # TODO: fix / test the crypt stream proxy class # TODO: add support for optional recovery user in case of lost passphrase / keys # TODO: add admin optional required long passphrase for users @@ -60,26 +65,25 @@ class Util { private $pwd; // User Password private $client; // Client side encryption mode flag - /** - * @brief get a list of all available versions of a file in descending chronological order - * @param $filename file to find versions of, relative to the user files dir - * @param $count number of versions to return - * @returns array - */ - public function __construct( \OC_FilesystemView $view, $client = false ) { + public function __construct( \OC_FilesystemView $view, $userId, $client = false ) { $this->view = $view; + $this->userId = $userId; $this->client = $client; + $this->publicKeyDir = '/' . 'public-keys'; + $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption'; + $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles'; + $this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key + $this->privateKeyPath = $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key } public function ready() { if( - !$this->view->file_exists( '/' . 'keyfiles' ) - or !$this->view->file_exists( '/' . 'keypair' ) - or !$this->view->file_exists( '/' . 'keypair' . '/'. 'encryption.public.key' ) - or !$this->view->file_exists( '/' . 'keypair' . '/'. 'encryption.private.key' ) + !$this->view->file_exists( $this->keyfilesPath ) + or !$this->view->file_exists( $this->publicKeyPath ) + or !$this->view->file_exists( $this->privateKeyPath ) ) { return false; @@ -93,61 +97,58 @@ class Util { } /** - * @brief Sets up encryption folders and keys for a user + * @brief Sets up user folders and keys for serverside encryption * @param $passphrase passphrase to encrypt server-stored private key with */ - public function setup( $passphrase = null ) { - - $publicKeyFileName = 'encryption.public.key'; - $privateKeyFileName = 'encryption.private.key'; + public function setupServerSide( $passphrase = null ) { // Log changes to user's filesystem $this->appInfo = \OC_APP::getAppInfo( 'files_encryption' ); - \OC_Log::write( $this->appInfo['name'], 'File encryption for user will be set up' , \OC_Log::INFO ); + \OC_Log::write( $this->appInfo['name'], 'File encryption for user "' . $this->userId . '" will be set up' , \OC_Log::INFO ); - // Create mirrored keyfile directory - if( !$this->view->file_exists( '/' . 'keyfiles' ) ) { + // Create shared public key directory + if( !$this->view->file_exists( $this->publicKeyDir ) ) { - $this->view->mkdir( '/'. 'keyfiles' ); + $this->view->mkdir( $this->publicKeyDir ); } - // Create keypair directory - if( !$this->view->file_exists( '/'. 'keypair' ) ) { + // Create encryption app directory + if( !$this->view->file_exists( $this->encryptionDir ) ) { - $this->view->mkdir( '/'. 'keypair' ); + $this->view->mkdir( $this->encryptionDir ); + + } + + // Create mirrored keyfile directory + if( !$this->view->file_exists( $this->keyfilesPath ) ) { + + $this->view->mkdir( $this->keyfilesPath ); } // Create user keypair if ( - !$this->view->file_exists( '/'. 'keypair'. '/' . $publicKeyFileName ) - or !$this->view->file_exists( '/'. 'keypair'. '/' . $privateKeyFileName ) + !$this->view->file_exists( $this->publicKeyPath ) + or !$this->view->file_exists( $this->privateKeyPath ) ) { // Generate keypair $keypair = Crypt::createKeypair(); + + \OC_FileProxy::$enabled = false; // Save public key - $this->view->file_put_contents( '/'. 'keypair'. '/' . $publicKeyFileName, $keypair['publicKey'] ); + $this->view->file_put_contents( $this->publicKeyPath, $keypair['publicKey'] ); - if ( $this->client == false ) { - - # TODO: Use proper IV in encryption - - // Encrypt private key with user pwd as passphrase - $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], $passphrase ); - - // $iv = openssl_random_pseudo_bytes(16); - $this->view->file_put_contents( '/'. 'keypair'. '/' . $privateKeyFileName, $encryptedPrivateKey ); - - } else { + // Encrypt private key with user pwd as passphrase + $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], $passphrase ); - # TODO PHASE2: add public key to keyserver for client-side - # TODO PHASE2: encrypt private key using password / new client side specified key, instead of existing user pwd + // Save private key + $this->view->file_put_contents( $this->privateKeyPath, $encryptedPrivateKey ); - } + \OC_FileProxy::$enabled = true; } From 6d1ed388c07329580251a91b3d03b8963b7cd884 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 25 Jul 2012 16:59:55 +0200 Subject: [PATCH 009/315] keymanager class for basic operations to store and retrieve keys --- apps/files_encryption/lib/keymanager.php | 110 +++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 apps/files_encryption/lib/keymanager.php diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php new file mode 100644 index 0000000000..32ee77bb90 --- /dev/null +++ b/apps/files_encryption/lib/keymanager.php @@ -0,0 +1,110 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + * + */ + +namespace OCA_Encryption; + +/* + * This class provides basic operations to read/write encryption keys from/to the filesystem + */ +class Keymanager { + + + /* + * @brief retrieve private key from a user + * + * @param string user name + * @return string private key or false + */ + public static function getPrivateKey($user) { + $privateKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/'; + $view = new \OC_FilesystemView($privateKeyStorage); + return $view->file_get_contents($user.'.private.key'); + } + + /* + * @brief retrieve public key from a user + * + * @param string user name + * @return string private key or false + */ + public static function getPublicKey($user) { + $publicKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/public-keys/'; + $view = $view = new \OC_FilesystemView($publicKeyStorage); + return $view->file_get_contents($user.'.public.key'); + } + + /* + * @brief retrieve file encryption key + * + * @param string file name + * @param string user name of the file owner + * @return string file key or false + */ + public static function getFileKey($user, $file) { + $fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/'; + $view = new \OC_FilesystemView($fileKeyStorage); + return $view->file_get_contents($file.'.key'); + } + + /* + * @brief store private key from a user + * + * @param string user name + * @param string key + * @return bool true/false + */ + public static function setPrivateKey($user, $key) { + $privateKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/'; + $view = new \OC_FilesystemView($privateKeyStorage); + return $view->file_put_contents($user.'.private.key', $key); + } + + + /* + * @brief store public key from a user + * + * @param string user name + * @param string key + * @return bool true/false + */ + public static function setPublicKey($user, $key) { + $publicKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/public-keys/'; + $view = new \OC_FilesystemView($publicKeyStorage); + return $view->file_put_contents($user.'.public.key', $key); + } + + /* + * @brief store file encryption key + * + * @param string user name of the file owner + * @param string file name + * @param string key + * @return bool true/false + */ + public static function setFileKey($user, $file, $key) { + $fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/'; + $view = new \OC_FilesystemView($fileKeyStorage); + return $view->file_put_contents($file.'.key', $key); + + } + +} \ No newline at end of file From 66b461629be6d1585ae0171b9128ad19d2c85bfb Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 25 Jul 2012 16:25:24 +0100 Subject: [PATCH 010/315] Started implementation of new encyryption classes into the encryption proxy --- apps/files_encryption/hooks/hooks.php | 14 ++++++++------ apps/files_encryption/lib/proxy.php | 23 +++++++++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 89d526b704..a8304261e4 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -30,19 +30,21 @@ class Hooks { public static function login( $params ){ - $view = new \OC_FilesystemView( '/' . $params['uid'] ); + $view = new \OC_FilesystemView( '/' ); - $storage = new Storage( $view ); + $storage = new Storage( $view, $params['uid'] ); if ( !$storage->ready() ) { return $storage->setup( $params['password'] ); - } else { - - return true; - } + + $_SESSION['enckey'] = OC_Crypt::decrypt($key, $password); + + return true; + + } } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 3f9b86b988..080fd04cd7 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -26,9 +26,11 @@ * transparent encryption */ -class OC_FileProxy_Encryption extends OC_FileProxy{ - private static $blackList=null; //mimetypes blacklisted from encryption - private static $enableEncryption=null; +class OC_FileProxy_Encryption extends OC_FileProxy { + + private static $blackList = null; //mimetypes blacklisted from encryption + + private static $enableEncryption = null; /** * Check if a file requires encryption @@ -97,7 +99,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ $size = strlen( $data ); - $data = Crypt::blockEncrypt( $data ); + $data = OCA_Encryption\Crypt::symmetricEncryptFileContent( $data, '', $cached['size'] ); OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); @@ -105,11 +107,16 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ } } - public function postFile_get_contents($path,$data){ - if(self::isEncrypted($path)){ - $cached=OC_FileCache_Cached::get($path,''); - $data=OC_Crypt::blockDecrypt($data,'',$cached['size']); + public function postFile_get_contents( $path, $data ) { + + if ( self::isEncrypted( $path ) ) { + + $cached = OC_FileCache_Cached::get( $path, '' ); + + $data = OCA_Encryption\Crypt::symmetricDecryptFileContent( $data, '' ); + } + return $data; } From e6de086fb66b029d70d1e24db5224f236e43198d Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 25 Jul 2012 16:51:48 +0100 Subject: [PATCH 011/315] Fixed various bugs in hooks class Fixed documentation syntax in keymanager --- apps/files_encryption/appinfo/app.php | 11 ++- apps/files_encryption/hooks/hooks.php | 16 +++- apps/files_encryption/lib/keymanager.php | 104 +++++++++++------------ 3 files changed, 71 insertions(+), 60 deletions(-) diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 679d0b95ed..969c824cfd 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -1,16 +1,19 @@ ready() ) { + if ( !$util->ready() ) { - return $storage->setup( $params['password'] ); + return $util->setup( $params['password'] ); } - $_SESSION['enckey'] = OC_Crypt::decrypt($key, $password); + $encryptedKey = Keymanager::getPrivateKey( $params['uid'] ); + + $_SESSION['enckey'] = Crypt::symmetricEncryptFileContent( $encryptedKey, $params['password'] ); return true; diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 32ee77bb90..a75242c7a2 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -1,5 +1,5 @@ -. * - */ - -namespace OCA_Encryption; - -/* - * This class provides basic operations to read/write encryption keys from/to the filesystem - */ -class Keymanager { - - - /* - * @brief retrieve private key from a user - * - * @param string user name - * @return string private key or false - */ - public static function getPrivateKey($user) { + */ + +namespace OCA_Encryption; + +/** + * This class provides basic operations to read/write encryption keys from/to the filesystem + */ +class Keymanager { + + + /** + * @brief retrieve private key from a user + * + * @param string user name + * @return string private key or false + */ + public static function getPrivateKey($user) { $privateKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/'; - $view = new \OC_FilesystemView($privateKeyStorage); - return $view->file_get_contents($user.'.private.key'); - } - - /* + $view = new \OC_FilesystemView($privateKeyStorage); + return $view->file_get_contents($user.'.private.key'); + } + + /** * @brief retrieve public key from a user * * @param string user name * @return string private key or false */ public static function getPublicKey($user) { - $publicKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/public-keys/'; - $view = $view = new \OC_FilesystemView($publicKeyStorage); + $publicKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/public-keys/'; + $view = $view = new \OC_FilesystemView($publicKeyStorage); return $view->file_get_contents($user.'.public.key'); - } - - /* + } + + /** * @brief retrieve file encryption key * - * @param string file name - * @param string user name of the file owner + * @param string file name + * @param string user name of the file owner * @return string file key or false */ public static function getFileKey($user, $file) { - $fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/'; - $view = new \OC_FilesystemView($fileKeyStorage); + $fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/'; + $view = new \OC_FilesystemView($fileKeyStorage); return $view->file_get_contents($file.'.key'); - } - - /* + } + + /** * @brief store private key from a user * - * @param string user name + * @param string user name * @param string key * @return bool true/false - */ + */ public static function setPrivateKey($user, $key) { $privateKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/'; - $view = new \OC_FilesystemView($privateKeyStorage); + $view = new \OC_FilesystemView($privateKeyStorage); return $view->file_put_contents($user.'.private.key', $key); - } - - - /* + } + + + /** * @brief store public key from a user * * @param string user name * @param string key * @return bool true/false - */ - public static function setPublicKey($user, $key) { + */ + public static function setPublicKey($user, $key) { $publicKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/public-keys/'; $view = new \OC_FilesystemView($publicKeyStorage); return $view->file_put_contents($user.'.public.key', $key); } - - /* + + /** * @brief store file encryption key - * - * @param string user name of the file owner + * + * @param string user name of the file owner * @param string file name * @param string key * @return bool true/false */ - public static function setFileKey($user, $file, $key) { + public static function setFileKey($user, $file, $key) { $fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/'; $view = new \OC_FilesystemView($fileKeyStorage); return $view->file_put_contents($file.'.key', $key); - } - + } + } \ No newline at end of file From adf5c953ddc0aeea15824e0e677d4e1fb753d554 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 25 Jul 2012 16:56:52 +0100 Subject: [PATCH 012/315] Fixed use of OCFSV in getPrivateKey() --- apps/files_encryption/lib/keymanager.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index a75242c7a2..d78db132b1 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -34,10 +34,11 @@ class Keymanager { * @param string user name * @return string private key or false */ - public static function getPrivateKey($user) { - $privateKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/'; - $view = new \OC_FilesystemView($privateKeyStorage); - return $view->file_get_contents($user.'.private.key'); + public static function getPrivateKey( $user ) { + + $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' . '/' ); + + return $view->file_get_contents( $user.'.private.key' ); } /** From 9f51841c57ca96eb7ce518dde9c6d35c905110c6 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 25 Jul 2012 18:28:56 +0100 Subject: [PATCH 013/315] Mainly work on implementing new encryption system (+ keyfile handling) into proxy classs --- apps/files_encryption/appinfo/app.php | 16 ++++-- apps/files_encryption/hooks/hooks.php | 1 - apps/files_encryption/lib/keymanager.php | 24 +++++---- apps/files_encryption/lib/proxy.php | 65 +++++++++++++++--------- apps/files_encryption/lib/util.php | 9 ++-- 5 files changed, 73 insertions(+), 42 deletions(-) diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 969c824cfd..1a4021e939 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -5,18 +5,26 @@ OC::$CLASSPATH['OCA_Encryption\Hooks'] = 'apps/files_encryption/hooks/hooks.php' OC::$CLASSPATH['OCA_Encryption\Util'] = 'apps/files_encryption/lib/util.php'; OC::$CLASSPATH['OCA_Encryption\Keymanager'] = 'apps/files_encryption/lib/keymanager.php'; OC::$CLASSPATH['OC_CryptStream'] = 'apps/files_encryption/lib/cryptstream.php'; -OC::$CLASSPATH['OC_FileProxy_Encryption'] = 'apps/files_encryption/lib/proxy.php'; +OC::$CLASSPATH['OCA_Encryption\Proxy'] = 'apps/files_encryption/lib/proxy.php'; -//OC_FileProxy::register(new OC_FileProxy_Encryption()); +OC_FileProxy::register(new OCA_Encryption\Proxy()); OCP\Util::connectHook('OC_User','post_login','OCA_Encryption\Hooks','login'); stream_wrapper_register('crypt','OC_CryptStream'); -if( !isset($_SESSION['enckey']) and OCP\User::isLoggedIn() ){//force the user to re-loggin if the encryption key isn't unlocked (happens when a user is logged in before the encryption app is enabled) +if( +!isset( $_SESSION['enckey'] ) +and OCP\User::isLoggedIn() +) { + + // Force the user to re-log in if the encryption key isn't unlocked (happens when a user is logged in before the encryption app is enabled) OCP\User::logout(); + header("Location: ".OC::$WEBROOT.'/'); + exit(); + } -OCP\App::registerAdmin('files_encryption', 'settings'); +OCP\App::registerAdmin('files_encryption', 'settings'); \ No newline at end of file diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 70bbbcf478..654686208f 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -52,7 +52,6 @@ class Hooks { return true; - } } diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index d78db132b1..e4462796f0 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -27,6 +27,7 @@ namespace OCA_Encryption; */ class Keymanager { + # TODO: Try and get rid of username dependencies as these methods need to be used in a proxy class that doesn't have username access /** * @brief retrieve private key from a user @@ -36,9 +37,9 @@ class Keymanager { */ public static function getPrivateKey( $user ) { - $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' . '/' ); + $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' ); - return $view->file_get_contents( $user.'.private.key' ); + return $view->file_get_contents( '/' . $user.'.private.key' ); } /** @@ -96,15 +97,20 @@ class Keymanager { /** * @brief store file encryption key * - * @param string user name of the file owner - * @param string file name - * @param string key + * @param string $userId name of the file owner + * @param string $path relative path of the file, including filename + * @param string $key * @return bool true/false */ - public static function setFileKey($user, $file, $key) { - $fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/'; - $view = new \OC_FilesystemView($fileKeyStorage); - return $view->file_put_contents($file.'.key', $key); + public static function setFileKey( $userId, $path, $key ) { + + \OC_FileProxy::$enabled = false; + + $view = new \OC_FilesystemView( '/' . $userId . '/' . 'files_encryption' ); + + return $view->file_put_contents( '/' . $path . '.key', $key ); + + \OC_FileProxy::$enabled = true; } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 080fd04cd7..53ed05d2c3 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -3,8 +3,9 @@ /** * ownCloud * -* @author Robin Appelman -* @copyright 2011 Robin Appelman icewind1991@gmail.com +* @author Sam Tuke, Robin Appelman +* @copyright 2012 Sam Tuke samtuke@owncloud.com, Robin Appelman +* icewind1991@gmail.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -26,7 +27,9 @@ * transparent encryption */ -class OC_FileProxy_Encryption extends OC_FileProxy { +namespace OCA_Encryption; + +class Proxy extends \OC_FileProxy { private static $blackList = null; //mimetypes blacklisted from encryption @@ -43,7 +46,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy { if ( is_null( self::$enableEncryption ) ) { - self::$enableEncryption = ( OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' ); + self::$enableEncryption = ( \OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' ); } @@ -55,11 +58,11 @@ class OC_FileProxy_Encryption extends OC_FileProxy { if( is_null(self::$blackList ) ) { - self::$blackList = explode(',',OCP\Config::getAppValue( 'files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) ); + self::$blackList = explode(',', \OCP\Config::getAppValue( 'files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) ); } - if( self::isEncrypted( $path ) ) { + if( Crypt::isEncryptedContent( $path ) ) { return true; @@ -84,7 +87,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy { private static function isEncrypted( $path ){ // Fetch all file metadata from DB - $metadata = OC_FileCache_Cached::get( $path, '' ); + $metadata = \OC_FileCache_Cached::get( $path, '' ); // Return encryption status return isset( $metadata['encrypted'] ) and ( bool )$metadata['encrypted']; @@ -95,13 +98,24 @@ class OC_FileProxy_Encryption extends OC_FileProxy { if ( self::shouldEncrypt( $path ) ) { - if ( !is_resource( $data ) ) {//stream put contents should have been converter to fopen + if ( !is_resource( $data ) ) { //stream put contents should have been converter to fopen + // Set the filesize for userland, before encrypting $size = strlen( $data ); - $data = OCA_Encryption\Crypt::symmetricEncryptFileContent( $data, '', $cached['size'] ); + // Encrypt plain data and fetch key + $encrypted = Crypt::symmetricEncryptFileContentKeyfile( $data, $_SESSION['enckey'] ); - OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); + // Replace plain content with encrypted content by reference + $data = $encrypted['encrypted']; + + # TODO: check if file is in subdirectories, and if so, create those parent directories. Or else monitor creation of directories using hooks to ensure path will always exist (what about existing directories when encryption is enabled?) + + // Save keyfile for newly encrypted file in parallel directory + Keymanager::setFileKey( \OCP\USER::getUser(), $path, $encrypted['key'] ); + + // Update the file cache with file info + \OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); } } @@ -109,11 +123,11 @@ class OC_FileProxy_Encryption extends OC_FileProxy { public function postFile_get_contents( $path, $data ) { - if ( self::isEncrypted( $path ) ) { - - $cached = OC_FileCache_Cached::get( $path, '' ); + if ( Crypt::isEncryptedContent( $data ) ) { + trigger_error('best'); + $cached = \OC_FileCache_Cached::get( $path, '' ); - $data = OCA_Encryption\Crypt::symmetricDecryptFileContent( $data, '' ); + $data = Crypt::symmetricDecryptFileContent( $data, $_SESSION['enckey'] ); } @@ -121,21 +135,22 @@ class OC_FileProxy_Encryption extends OC_FileProxy { } public function postFopen($path,&$result){ + if(!$result){ return $result; } $meta=stream_get_meta_data($result); - if(self::isEncrypted($path)){ + if(Crypt::isEncryptedContent($path)){ fclose($result); $result=fopen('crypt://'.$path,$meta['mode']); }elseif(self::shouldEncrypt($path) and $meta['mode']!='r' and $meta['mode']!='rb'){ - if(OC_Filesystem::file_exists($path) and OC_Filesystem::filesize($path)>0){ + if( \OC_Filesystem::file_exists( $path ) and \OC_Filesystem::filesize($path)>0){ //first encrypt the target file so we don't end up with a half encrypted file - OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing',OCP\Util::DEBUG); + \OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing', \OCP\Util::DEBUG); $tmp=fopen('php://temp'); - OCP\Files::streamCopy($result,$tmp); + \OCP\Files::streamCopy($result,$tmp); fclose($result); - OC_Filesystem::file_put_contents($path,$tmp); + \OC_Filesystem::file_put_contents($path,$tmp); fclose($tmp); } $result=fopen('crypt://'.$path,$meta['mode']); @@ -144,23 +159,23 @@ class OC_FileProxy_Encryption extends OC_FileProxy { } public function postGetMimeType($path,$mime){ - if(self::isEncrypted($path)){ - $mime=OCP\Files::getMimeType('crypt://'.$path,'w'); + if(Crypt::isEncryptedContent($path)){ + $mime = \OCP\Files::getMimeType('crypt://'.$path,'w'); } return $mime; } public function postStat($path,$data){ - if(self::isEncrypted($path)){ - $cached=OC_FileCache_Cached::get($path,''); + if(Crypt::isEncryptedContent($path)){ + $cached= \OC_FileCache_Cached::get($path,''); $data['size']=$cached['size']; } return $data; } public function postFileSize($path,$size){ - if(self::isEncrypted($path)){ - $cached=OC_FileCache_Cached::get($path,''); + if(Crypt::isEncryptedContent($path)){ + $cached = \OC_FileCache_Cached::get($path,''); return $cached['size']; }else{ return $size; diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index e876e886c4..ab58b4aa72 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -184,15 +184,16 @@ class Util { * if the key is left out, the default handeler will be used */ public function getLegacyKey( $passphrase ) { - - //OC_FileProxy::$enabled = false; + + // Disable proxies to prevent attempt to automatically decrypt key + OC_FileProxy::$enabled = false; if ( $passphrase and $key = $this->view->file_get_contents( '/encryption.key' ) ) { - //OC_FileProxy::$enabled = true; + OC_FileProxy::$enabled = true; if ( $this->legacyKey = $this->legacyDecrypt( $key, $passphrase ) ) { @@ -206,6 +207,8 @@ class Util { } else { + OC_FileProxy::$enabled = true; + return false; } From 3ab4ddd1da8a1d9c919a38c15770e14fbeda5ea2 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 26 Jul 2012 13:47:43 +0200 Subject: [PATCH 014/315] function to ask for the encryption mode (server side or client side). Needs to be implemented and integrated into the settings. --- apps/files_encryption/lib/crypt.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 668101014a..090b1db061 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -30,6 +30,17 @@ namespace OCA_Encryption; class Crypt { + /** + * @brief return encryption mode client or server side encryption + * @param string user name + * @return string 'client' or 'server' + */ + public static function mode($user) { + //TODO: allow user to set encryption mode and check the selection of the user + // for the moment I just return 'client' for test purposes + return 'client'; + } + /** * @brief Create a new encryption keypair * @return array publicKey, privatekey From bdb406916cf7306abf03a83e4fde81baf71d22bc Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 26 Jul 2012 13:49:22 +0200 Subject: [PATCH 015/315] fixed path for filesystem view --- apps/files_encryption/lib/keymanager.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index d78db132b1..de6db08ae1 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -48,8 +48,7 @@ class Keymanager { * @return string private key or false */ public static function getPublicKey($user) { - $publicKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/public-keys/'; - $view = $view = new \OC_FilesystemView($publicKeyStorage); + $view = new \OC_FilesystemView( '/public-keys/' ); return $view->file_get_contents($user.'.public.key'); } @@ -61,8 +60,7 @@ class Keymanager { * @return string file key or false */ public static function getFileKey($user, $file) { - $fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/'; - $view = new \OC_FilesystemView($fileKeyStorage); + $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); return $view->file_get_contents($file.'.key'); } @@ -74,8 +72,7 @@ class Keymanager { * @return bool true/false */ public static function setPrivateKey($user, $key) { - $privateKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/'; - $view = new \OC_FilesystemView($privateKeyStorage); + $view = new \OC_FilesystemView('/'.$user.'/files_encryption/'); return $view->file_put_contents($user.'.private.key', $key); } @@ -88,8 +85,7 @@ class Keymanager { * @return bool true/false */ public static function setPublicKey($user, $key) { - $publicKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/public-keys/'; - $view = new \OC_FilesystemView($publicKeyStorage); + $view = new \OC_FilesystemView('/public-keys/'); return $view->file_put_contents($user.'.public.key', $key); } @@ -102,8 +98,7 @@ class Keymanager { * @return bool true/false */ public static function setFileKey($user, $file, $key) { - $fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/'; - $view = new \OC_FilesystemView($fileKeyStorage); + $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); return $view->file_put_contents($file.'.key', $key); } From cb5d935b82643a3e3c369c11835ca1f5b2ad0b58 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 26 Jul 2012 13:57:50 +0200 Subject: [PATCH 016/315] implemented publicKeyGet() and privateKeyGet() calls --- lib/ocs.php | 65 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/lib/ocs.php b/lib/ocs.php index 218f7a9312..9d30b062bc 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -652,17 +652,25 @@ class OC_OCS { */ private static function publicKeyGet($format, $user) { $login=OC_OCS::checkpassword(); - if(OC_User::userExists($user)){ - //TODO: GET public key - $xml=array(); - $xml['key']="this is the public key of $user"; - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if(OC_User::userExists($user)){ + if (($key = OCA_Encryption\Keymanager::getPublicKey($user))) { + $xml=array(); + $xml['key'] = $key; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + } + else { + echo self::generateXml('', 'fail', 404, 'public key does not exist'); + } + } else { + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); } } - + /** * set the public key of a user * @param string $format @@ -690,22 +698,25 @@ class OC_OCS { * @param string $user * @return string xml/json */ - private static function privateKeyGet($format, $user) { - $login=OC_OCS::checkpassword(); - if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { - if(OC_User::userExists($user)){ - //TODO: GET private key - $xml=array(); - $xml['key']="this is the private key of $user"; - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); - } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - } + private static function privateKeyGet($format, $user) { + $login=OC_OCS::checkpassword(); + if(($login==$user)) { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::getPrivateKey($user))) { + $xml=array(); + $xml['key']=$key; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + } else { + echo self::generateXml('', 'fail', 404, 'private Key does not exist'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } /** * set the private key of a user @@ -735,7 +746,7 @@ class OC_OCS { * @param string $file * @return string xml/json */ - private static function privateKeyGet($format, $user, $file) { + private static function fileKeyGet($format, $user, $file) { $login=OC_OCS::checkpassword(); if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { if(OC_User::userExists($user)){ @@ -760,7 +771,7 @@ class OC_OCS { * @param string $key * @return string xml/json */ - private static function privateKeySet($format, $user, $file, $key) { + private static function fileKeySet($format, $user, $file, $key) { $login=OC_OCS::checkpassword(); if($login == $user) { if(OC_User::userExists($user)){ From bb229f729114bcd20b861e8b118fd6c805b96b73 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 26 Jul 2012 17:19:55 +0200 Subject: [PATCH 017/315] write private/public key from the client to the server --- apps/files_encryption/lib/keymanager.php | 31 ++++++++++--- lib/ocs.php | 58 +++++++++++++++--------- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index f48047a692..0bef3b7492 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -73,8 +73,16 @@ class Keymanager { * @return bool true/false */ public static function setPrivateKey($user, $key) { - $view = new \OC_FilesystemView('/'.$user.'/files_encryption/'); - return $view->file_put_contents($user.'.private.key', $key); + + \OC_FileProxy::$enabled = false; + + $view = new \OC_FilesystemView('/'.$user.'/files_encryption'); + if (!$view->file_exists('')) $view->mkdir(''); + $result = $view->file_put_contents($user.'.private.key', $key); + + \OC_FileProxy::$enabled = true; + + return $result; } @@ -86,8 +94,16 @@ class Keymanager { * @return bool true/false */ public static function setPublicKey($user, $key) { - $view = new \OC_FilesystemView('/public-keys/'); - return $view->file_put_contents($user.'.public.key', $key); + + \OC_FileProxy::$enabled = false; + + $view = new \OC_FilesystemView('/public-keys'); + if (!$view->file_exists('')) $view->mkdir(''); + $result = $view->file_put_contents($user.'.public.key', $key); + + \OC_FileProxy::$enabled = true; + + return $result; } /** @@ -103,10 +119,13 @@ class Keymanager { \OC_FileProxy::$enabled = false; $view = new \OC_FilesystemView( '/' . $userId . '/' . 'files_encryption' ); - - return $view->file_put_contents( '/' . $path . '.key', $key ); + $path_parts = pathinfo($path); + if (!$view->file_exists($path_parts['dirname'])) $view->mkdir($path_parts['dirname']); + $result = $view->file_put_contents( '/' . $path . '.key', $key ); \OC_FileProxy::$enabled = true; + + return $result; } } \ No newline at end of file diff --git a/lib/ocs.php b/lib/ocs.php index 9d30b062bc..5349053ad2 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -173,10 +173,20 @@ class OC_OCS { $user=$ex[$paracount-3]; OC_OCS::publicKeyGet($format,$user); + //keysetpublic + }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){ + $user=$ex[$paracount-3]; + $key = self::readData('post', 'key', 'string'); + OC_OCS::publicKeySet($format,$user, $key); + // keygetprivate }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ $user=$ex[$paracount-3]; OC_OCS::privateKeyGet($format,$user); + }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ + $user=$ex[$paracount-3]; + $key = self::readData('post', 'key', 'string'); + OC_OCS::privateKeySet($format,$user, $key); // add more calls here @@ -678,20 +688,23 @@ class OC_OCS { * @param string $key * @return string xml/json */ - private static function publicKeySet($format, $user, $key) { + private static function publicKeySet($format, $user, $key) { $login=OC_OCS::checkpassword(); - if($login == $user) { - if(OC_User::userExists($user)){ - //TODO: SET public key - echo self::generateXml('', 'ok', 100, 'Public key uploaded'); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); + if(($login==$user)) { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::setPublicKey($user, $key))) { + echo self::generateXml('', 'ok', 100, ''); + } else { + echo self::generateXml('', 'fail', 404, 'could not add your public key to the key storage'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); } }else{ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); } } - + /** * get the private key of a user * @param string $format @@ -725,19 +738,22 @@ class OC_OCS { * @param string $key * @return string xml/json */ - private static function privateKeySet($format, $user, $key) { - $login=OC_OCS::checkpassword(); - if($login == $user) { - if(OC_User::userExists($user)){ - //TODO: SET private key - echo self::generateXml('', 'ok', 100, 'Private key uploaded'); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); - } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - } + private static function privateKeySet($format, $user, $key) { + $login=OC_OCS::checkpassword(); + if(($login==$user)) { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::setPrivateKey($user, $key))) { + echo self::generateXml('', 'ok', 100, ''); + } else { + echo self::generateXml('', 'fail', 404, 'could not add your private key to the key storage'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } /** * get the encryption key of a file From 931c4695a60d7c46d225152f0628fdd7f1574027 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 27 Jul 2012 13:58:58 +0200 Subject: [PATCH 018/315] run setup routine only for server side encryption --- apps/files_encryption/hooks/hooks.php | 36 +++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 654686208f..80daf50a24 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -34,24 +34,28 @@ class Hooks { * @brief Startup encryption backend upon user login * @note This method should never be called for users using client side encryption */ - public static function login( $params ){ - - $view = new \OC_FilesystemView( '/' ); - - $util = new Util( $view, $params['uid'] ); - - if ( !$util->ready() ) { - - return $util->setup( $params['password'] ); - + + public static function login( $params ) { + + if (Crypt::mode($params['uid'])=='server') { + + $view = new \OC_FilesystemView( '/' ); + + $util = new Util( $view, $params['uid'] ); + + if ( !$util->ready()) { + + return $util->setupServerSide( $params['password'] ); + + } + + $encryptedKey = Keymanager::getPrivateKey( $params['uid'] ); + + $_SESSION['enckey'] = Crypt::symmetricEncryptFileContent( $encryptedKey, $params['password'] ); } - - $encryptedKey = Keymanager::getPrivateKey( $params['uid'] ); - - $_SESSION['enckey'] = Crypt::symmetricEncryptFileContent( $encryptedKey, $params['password'] ); - + return true; - + } } From f752a2760584614c160e4eaf5bf0fdeb938ee4ae Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 27 Jul 2012 14:00:41 +0200 Subject: [PATCH 019/315] write keyfiles to server --- apps/files_encryption/lib/keymanager.php | 2 +- lib/filestorage/local.php | 2 +- lib/ocs.php | 42 +++++++++++++++++------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 0bef3b7492..ab50fba697 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -118,7 +118,7 @@ class Keymanager { \OC_FileProxy::$enabled = false; - $view = new \OC_FilesystemView( '/' . $userId . '/' . 'files_encryption' ); + $view = new \OC_FilesystemView( '/' . $userId . '/' . 'files_encryption/keyfiles' ); $path_parts = pathinfo($path); if (!$view->file_exists($path_parts['dirname'])) $view->mkdir($path_parts['dirname']); $result = $view->file_put_contents( '/' . $path . '.key', $key ); diff --git a/lib/filestorage/local.php b/lib/filestorage/local.php index b2eba05151..f04cf7c107 100644 --- a/lib/filestorage/local.php +++ b/lib/filestorage/local.php @@ -12,7 +12,7 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{ } } public function mkdir($path){ - return @mkdir($this->datadir.$path); + return @mkdir($this->datadir.$path, 0755, true); } public function rmdir($path){ return @rmdir($this->datadir.$path); diff --git a/lib/ocs.php b/lib/ocs.php index 5349053ad2..e0c240d330 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -183,11 +183,24 @@ class OC_OCS { }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ $user=$ex[$paracount-3]; OC_OCS::privateKeyGet($format,$user); + + //keysetprivate }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ $user=$ex[$paracount-3]; $key = self::readData('post', 'key', 'string'); OC_OCS::privateKeySet($format,$user, $key); - + + // keygetfiles + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'filekey')){ + $user=$ex[$paracount-3]; + OC_OCS::fileKeyGet($format,$user); + + //keysetfiles + }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'filekey')){ + $user=$ex[$paracount-3]; + $key = self::readData('post', 'key', 'string'); + $file = self::readData('post', 'file', 'string'); + OC_OCS::fileKeySet($format,$user, $file, $key); // add more calls here // please document all the call in the draft spec @@ -766,7 +779,7 @@ class OC_OCS { $login=OC_OCS::checkpassword(); if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { if(OC_User::userExists($user)){ - //TODO: GET file key + //TODO: GET file key, check needed if it is a shared file or not $xml=array(); $xml['key']="this is the key for $file"; $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); @@ -787,18 +800,25 @@ class OC_OCS { * @param string $key * @return string xml/json */ - private static function fileKeySet($format, $user, $file, $key) { + private static function fileKeySet($format, $user, $file, $key) { $login=OC_OCS::checkpassword(); - if($login == $user) { - if(OC_User::userExists($user)){ - //TODO: SET file key - echo self::generateXml('', 'ok', 100, 'File key uploaded'); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); + if(($login==$user)) { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::setFileKey($user, $file, $key))) { + // TODO: emit hook to move file from tmp location to the right place + echo self::generateXml('', 'ok', 100, ''); + return true; + } else { + echo self::generateXml('', 'fail', 404, 'could not write key file'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); } }else{ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - } + } + //TODO: emit signal to remove file from tmp location + return false; + } } From e5704bf8bfcec968e8b8ce5a85c83fea766a8dbf Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 30 Jul 2012 10:07:52 +0200 Subject: [PATCH 020/315] ocs call to get file key for client side enncryption --- lib/ocs.php | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/ocs.php b/lib/ocs.php index e0c240d330..526688b430 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -191,12 +191,13 @@ class OC_OCS { OC_OCS::privateKeySet($format,$user, $key); // keygetfiles - }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'filekey')){ - $user=$ex[$paracount-3]; - OC_OCS::fileKeyGet($format,$user); + }elseif(($method=='get') and ($ex[$paracount-7] == 'v1.php') and ($ex[$paracount-6]=='cloud') and ($ex[$paracount-5] == 'user') and ($ex[$paracount-3] == 'filekey')){ + $user=$ex[$paracount-4]; + $file = urldecode($ex[$paracount-2]); + OC_OCS::fileKeyGet($format,$user, $file); //keysetfiles - }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'filekey')){ + }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'filekey')){ $user=$ex[$paracount-3]; $key = self::readData('post', 'key', 'string'); $file = self::readData('post', 'file', 'string'); @@ -734,7 +735,7 @@ class OC_OCS { $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); echo($txt); } else { - echo self::generateXml('', 'fail', 404, 'private Key does not exist'); + echo self::generateXml('', 'fail', 404, 'private key does not exist'); } } else { echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); @@ -775,21 +776,24 @@ class OC_OCS { * @param string $file * @return string xml/json */ - private static function fileKeyGet($format, $user, $file) { - $login=OC_OCS::checkpassword(); - if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { - if(OC_User::userExists($user)){ - //TODO: GET file key, check needed if it is a shared file or not - $xml=array(); - $xml['key']="this is the key for $file"; - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); + private static function fileKeyGet($format, $user, $file) { + $login=OC_OCS::checkpassword(); + if(($login==$user)) { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::getFileKey($user, $file))) { + $xml=array(); + $xml['key']=$key; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + } else { + echo self::generateXml('', 'fail', 404, 'file key does not exist'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); } }else{ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } + } } /** From 23391b3694120ee6a0aa443aab0a2eebd6400d11 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 30 Jul 2012 12:38:38 +0200 Subject: [PATCH 021/315] get/set key files, take shared files into account --- apps/files_encryption/lib/keymanager.php | 40 ++++++++++++++++++++---- lib/ocs.php | 4 +-- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index ab50fba697..9dc95ea676 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -60,9 +60,23 @@ class Keymanager { * @param string user name of the file owner * @return string file key or false */ - public static function getFileKey($user, $file) { + public static function getFileKey($userId, $path) { + + $keypath = ltrim($path, '/'); + $user = $userId; + + // update $keypath and $user if path point to a file shared by someone else + $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); + $result = $query->execute( array ('/'.$userId.'/files/'.$keypath, $userId)); + if ($row = $result->fetchRow()){ + $keypath = $row['source']; + $keypath_parts=explode('/',$keypath); + $user = $keypath_parts[1]; + $keypath = str_replace('/'.$user.'/files/', '', $keypath); + } + $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); - return $view->file_get_contents($file.'.key'); + return $view->file_get_contents($keypath.'.key'); } /** @@ -115,13 +129,27 @@ class Keymanager { * @return bool true/false */ public static function setFileKey( $userId, $path, $key ) { - + \OC_FileProxy::$enabled = false; + + $targetpath = ltrim($path, '/'); + $user = $userId; + + // update $keytarget and $user if key belongs to a file shared by someone else + $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); + $result = $query->execute( array ('/'.$userId.'/files/'.$targetpath, $userId)); + if ($row = $result->fetchRow()){ + $targetpath = $row['source']; + $targetpath_parts=explode('/',$targetpath); + $user = $targetpath_parts[1]; + $targetpath = str_replace('/'.$user.'/files/', '', $targetpath); + } + + $view = new \OC_FilesystemView( '/' . $user . '/files_encryption/keyfiles' ); + $path_parts = pathinfo($targetpath); - $view = new \OC_FilesystemView( '/' . $userId . '/' . 'files_encryption/keyfiles' ); - $path_parts = pathinfo($path); if (!$view->file_exists($path_parts['dirname'])) $view->mkdir($path_parts['dirname']); - $result = $view->file_put_contents( '/' . $path . '.key', $key ); + $result = $view->file_put_contents( '/' . $targetpath . '.key', $key ); \OC_FileProxy::$enabled = true; diff --git a/lib/ocs.php b/lib/ocs.php index 526688b430..1681219650 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -192,8 +192,8 @@ class OC_OCS { // keygetfiles }elseif(($method=='get') and ($ex[$paracount-7] == 'v1.php') and ($ex[$paracount-6]=='cloud') and ($ex[$paracount-5] == 'user') and ($ex[$paracount-3] == 'filekey')){ - $user=$ex[$paracount-4]; - $file = urldecode($ex[$paracount-2]); + $user=$ex[$paracount-4]; + $file = urldecode($ex[$paracount-2]); OC_OCS::fileKeyGet($format,$user, $file); //keysetfiles From 1f2aa32d22a7b8dc5f85a3183b5142cfea81b811 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 30 Jul 2012 12:39:28 +0200 Subject: [PATCH 022/315] url needs to be case sensitive to be able to have files and paths as part of the URL --- lib/ocs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ocs.php b/lib/ocs.php index 1681219650..cf4248395f 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -93,7 +93,7 @@ class OC_OCS { } // preprocess url - $url = strtolower($_SERVER['REQUEST_URI']); + $url = $_SERVER['REQUEST_URI']; if(substr($url,(strlen($url)-1))<>'/') $url.='/'; $ex=explode('/',$url); $paracount=count($ex); From ee15c40b1416507abbe6d0fb568bde77bb94e5f4 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 30 Jul 2012 12:43:17 +0200 Subject: [PATCH 023/315] comment added --- apps/files_encryption/lib/keymanager.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 9dc95ea676..bafe8f1a5f 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -143,6 +143,7 @@ class Keymanager { $targetpath_parts=explode('/',$targetpath); $user = $targetpath_parts[1]; $targetpath = str_replace('/'.$user.'/files/', '', $targetpath); + //TODO: check for write permission on shared file once the new sharing API is in place } $view = new \OC_FilesystemView( '/' . $user . '/files_encryption/keyfiles' ); From 9bab06537c8d455c1a93b167193ec7cdebe89ffe Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 31 Jul 2012 15:03:28 +0200 Subject: [PATCH 024/315] update file encryption key over webdav properties for client side encryption --- apps/files_encryption/appinfo/app.php | 1 + apps/files_encryption/hooks/hooks.php | 12 +++++++++++ lib/connector/sabre/node.php | 30 ++++++++++++++++++++++++++- lib/ocs.php | 4 +--- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 1a4021e939..2047bdbb1f 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -10,6 +10,7 @@ OC::$CLASSPATH['OCA_Encryption\Proxy'] = 'apps/files_encryption/lib/proxy.php'; OC_FileProxy::register(new OCA_Encryption\Proxy()); OCP\Util::connectHook('OC_User','post_login','OCA_Encryption\Hooks','login'); +OCP\Util::connectHook('OC_Webdav_Properties', 'update', 'OCA_Encryption\Hooks', 'updateKeyfile'); stream_wrapper_register('crypt','OC_CryptStream'); diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 80daf50a24..35e14e2810 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -58,6 +58,18 @@ class Hooks { } + + /** + * @brief update the encryption key of the file uploaded by the client + */ + public static function updateKeyfile( $params ) { + if (Crypt::mode(\OCP\User::getUser()) == 'client') + if (isset($params['properties']['key'])) { + Keymanager::setFileKey(\OCP\User::getUser(), $params['path'], $params['properties']['key']); + } else { + error_log("Client side encryption is enabled but the client doesn't provide a encryption key for the file!"); + } + } } ?> \ No newline at end of file diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index be315a0ffd..90f88566a4 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -22,6 +22,7 @@ */ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties { + const GETETAG_PROPERTYNAME = '{DAV:}getetag'; /** * The path to the current node @@ -140,7 +141,9 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr */ public function updateProperties($properties) { $existing = $this->getProperties(array()); + OC_Hook::emit('OC_Webdav_Properties', 'update', array('properties' => $properties, 'path' => $this->path)); foreach($properties as $propertyName => $propertyValue) { + $propertyName = preg_replace("/^{.*}/", "", $propertyName); // remove leading namespace from property name // If it was null, we need to delete the property if (is_null($propertyValue)) { if(array_key_exists( $propertyName, $existing )){ @@ -178,7 +181,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * @param array $properties * @return void */ - function getProperties($properties) { + public function getProperties($properties) { if (is_null($this->property_cache)) { $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); $result = $query->execute( array( OC_User::getUser(), $this->path )); @@ -200,4 +203,29 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } return $props; } + + /** + * Returns the ETag surrounded by double-quotes for this path. + * @param string $path Path of the file + * @return string|null Returns null if the ETag can not effectively be determined + */ + static public function getETagPropertyForFile($path) { + $tag = OC_Filesystem::hash('md5', $path); + if (empty($tag)) { + return null; + } + $etag = '"'.$tag.'"'; + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' ); + $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag )); + return $etag; + } + + /** + * Remove the ETag from the cache. + * @param string $path Path of the file + */ + static public function removeETagPropertyForFile($path) { + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); + $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME )); + } } diff --git a/lib/ocs.php b/lib/ocs.php index cf4248395f..17ae649deb 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -808,8 +808,7 @@ class OC_OCS { $login=OC_OCS::checkpassword(); if(($login==$user)) { if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { - if (($key = OCA_Encryption\Keymanager::setFileKey($user, $file, $key))) { - // TODO: emit hook to move file from tmp location to the right place + if (($key = OCA_Encryption\Keymanager::setFileKey($user, $file, $key))) { echo self::generateXml('', 'ok', 100, ''); return true; } else { @@ -821,7 +820,6 @@ class OC_OCS { }else{ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); } - //TODO: emit signal to remove file from tmp location return false; } From e4e6574e425b666170ac56238a3bb6c84a2d50e2 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 31 Jul 2012 16:37:37 +0200 Subject: [PATCH 025/315] allow admin to choose between client and server side encryption --- apps/files_encryption/js/settings.js | 11 +++++++++++ apps/files_encryption/templates/settings.php | 11 ++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js index 8cc433246c..49dcf2bfca 100644 --- a/apps/files_encryption/js/settings.js +++ b/apps/files_encryption/js/settings.js @@ -21,4 +21,15 @@ $(document).ready(function(){ var checked=$('#enable_encryption').is(':checked'); OC.AppConfig.setValue('files_encryption','enable_encryption',(checked)?'true':'false'); }) + $('input[name=encryption_mode]').change(function(){ + var client=$('input[value="client"]:checked').val() + ,server=$('input[value="server"]:checked').val() + ,none=$('input[value="none"]:checked').val() + if (client) + OC.AppConfig.setValue('files_encryption','mode','client'); + if (server) + OC.AppConfig.setValue('files_encryption','mode','server'); + if (none) + OC.AppConfig.setValue('files_encryption','mode','none'); + }) }) \ No newline at end of file diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php index 79780d694c..80b3da84ca 100644 --- a/apps/files_encryption/templates/settings.php +++ b/apps/files_encryption/templates/settings.php @@ -1,5 +1,14 @@
+ + Choose encryption mode: + +

+ Client side encryption (most secure but makes it impossible to access your data from the web interface)
+ Server side encryption (allows you to access your files from the web interface and the desktop client)
+ None (no encryption at all)
+

+

t('Encryption'); ?> t("Exclude the following file types from encryption"); ?> - > +

From f6863f9e51ca1523e43c92a1ecbfe6f70c090494 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 31 Jul 2012 16:52:21 +0200 Subject: [PATCH 026/315] get encryption mode from the settings --- apps/files_encryption/lib/crypt.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 090b1db061..fdace3e61d 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -32,13 +32,19 @@ class Crypt { /** * @brief return encryption mode client or server side encryption - * @param string user name + * @param string user name (use system wide setting if name=null) * @return string 'client' or 'server' */ - public static function mode($user) { - //TODO: allow user to set encryption mode and check the selection of the user - // for the moment I just return 'client' for test purposes - return 'client'; + public static function mode($user=null) { + + $mode = \OC_Appconfig::getValue('files_encryption', 'mode', 'unknown'); + + if ($mode == 'unknown') { + error_log('no encryption mode configured'); + return false; + } + + return $mode; } /** From eebf76d34457df616d2b739582d9630f58df60b1 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 31 Jul 2012 19:28:11 +0100 Subject: [PATCH 027/315] Implemented writing of keyfiles and directory hierarchy in proxy class Added crypt::findFiles() method for finding different types of files, ready for batch encrypting / decrypting Added comments to postFopen in proxy class --- apps/files_encryption/hooks/hooks.php | 4 +- apps/files_encryption/lib/crypt.php | 830 +++++++++++----------- apps/files_encryption/lib/cryptstream.php | 83 ++- apps/files_encryption/lib/keymanager.php | 26 +- apps/files_encryption/lib/proxy.php | 86 ++- apps/files_encryption/lib/util.php | 96 ++- 6 files changed, 646 insertions(+), 479 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 80daf50a24..57d379b936 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -37,14 +37,14 @@ class Hooks { public static function login( $params ) { - if (Crypt::mode($params['uid'])=='server') { + if ( Crypt::mode( $params['uid'] ) == 'server' ) { $view = new \OC_FilesystemView( '/' ); $util = new Util( $view, $params['uid'] ); if ( !$util->ready()) { - + return $util->setupServerSide( $params['password'] ); } diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 090b1db061..cd65860184 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -1,420 +1,422 @@ -. - * - */ - -namespace OCA_Encryption; - -/** - * Class for common cryptography functionality - */ - -class Crypt { - +. + * + */ + +namespace OCA_Encryption; + +/** + * Class for common cryptography functionality + */ + +class Crypt { + /** - * @brief return encryption mode client or server side encryption + * @brief return encryption mode client or server side encryption * @param string user name * @return string 'client' or 'server' */ - public static function mode($user) { - //TODO: allow user to set encryption mode and check the selection of the user + public static function mode( $user ) { + + //TODO: allow user to set encryption mode and check the selection of the user // for the moment I just return 'client' for test purposes - return 'client'; - } - - /** - * @brief Create a new encryption keypair - * @return array publicKey, privatekey - */ - public static function createKeypair() { - - $res = openssl_pkey_new(); - - // Get private key - openssl_pkey_export( $res, $privateKey ); - - // Get public key - $publicKey = openssl_pkey_get_details( $res ); - - $publicKey = $publicKey['key']; - - return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) ); - - } - - /** - * @brief Check if a file's contents contains an IV and is symmetrically encrypted - * @return true / false - */ - public static function isEncryptedContent( $content ) { - - if ( !$content ) { - - return false; - - } - - // Fetch encryption metadata from end of file - $meta = substr( $content, -22 ); - - // Fetch IV from end of file - $iv = substr( $meta, -16 ); - - // Fetch identifier from start of metadata - $identifier = substr( $meta, 0, 6 ); - - if ( $identifier == '00iv00') { - - return true; - - } else { - - return false; - - } - - } - - /** - * @brief Check if a file is encrypted via legacy system - * @return true / false - */ - public static function isLegacyEncryptedContent( $content, $path ) { - - // Fetch all file metadata from DB - $metadata = \OC_FileCache_Cached::get( $content, '' ); - - // If a file is flagged with encryption in DB, but isn't a valid content + IV combination, it's probably using the legacy encryption system - if ( - $content - and isset( $metadata['encrypted'] ) - and $metadata['encrypted'] === true - and !self::isEncryptedContent( $content ) - ) { - - return true; - - } else { - - return false; - - } - - } - - /** - * @brief Symmetrically encrypt a string - * @returns encrypted file - */ - public static function encrypt( $plainContent, $iv, $passphrase = '' ) { - - if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { - - return $encryptedContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Symmetrically decrypt a string - * @returns decrypted file - */ - public static function decrypt( $encryptedContent, $iv, $passphrase ) { - - if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { - - return $plainContent; - - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Symmetrically encrypts a string and returns keyfile content - * @param $plainContent content to be encrypted in keyfile - * @returns encrypted content combined with IV - * @note IV need not be specified, as it will be stored in the returned keyfile - * and remain accessible therein. - */ - public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) { - - if ( !$plainContent ) { - - return false; - - } - - $iv = self::generateIv(); - - if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { - - // Combine content to encrypt with IV identifier and actual IV - $combinedKeyfile = $encryptedContent . '00iv00' . $iv; - - return $combinedKeyfile; - - } else { - - \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - - /** - * @brief Symmetrically decrypts keyfile content - * @param string $source - * @param string $target - * @param string $key the decryption key - * - * This function decrypts a file - */ - public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) { - - if ( !$keyfileContent ) { - - return false; - - } - - // Fetch IV from end of file - $iv = substr( $keyfileContent, -16 ); - - // Remove IV and IV identifier text to expose encrypted content - $encryptedContent = substr( $keyfileContent, 0, -22 ); - - if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) { - - return $plainContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Creates symmetric keyfile content using a generated key - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function symmetricEncryptFileContentKeyfile( $plainContent ) { - - $key = self::generateKey(); - - if( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) { - - return array( - 'key' => $key - , 'encrypted' => $encryptedContent - ); - - } else { - - return false; - - } - - } - - /** - * @brief Create asymmetrically encrypted keyfile content using a generated key - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { - - $envKeys = array(); - - if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) { - - return array( - 'keys' => $envKeys - , 'encrypted' => $sealed - ); - - } else { - - return false; - - } - - } - - /** - * @brief Asymmetrically encrypt a file using multiple public keys - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function multiKeyDecrypt( $encryptedContent, $envKey, $privateKey ) { - - if ( !$encryptedContent ) { - - return false; - - } - - if ( openssl_open( $encryptedContent, $plainContent, $envKey, $privateKey ) ) { - - return $plainContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Asymetrically encrypt a string using a public key - * @returns encrypted file - */ - public static function keyEncrypt( $plainContent, $publicKey ) { - - openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey ); - - return $encryptedContent; - - } - - /** - * @brief Asymetrically decrypt a file using a private key - * @returns decrypted file - */ - public static function keyDecrypt( $encryptedContent, $privatekey ) { - - openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); - - return $plainContent; - - } - - /** - * @brief Generate a pseudo random 1024kb ASCII key - * @returns $key Generated key - */ - public static function generateIv() { - - if ( $random = openssl_random_pseudo_bytes( 13, $strong ) ) { - - if ( !$strong ) { - - // If OpenSSL indicates randomness is insecure, log error - \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); - - } - - $iv = substr( base64_encode( $random ), 0, -4 ); - - return $iv; - - } else { - - return false; - - } - - } - - /** - * @brief Generate a pseudo random 1024kb ASCII key - * @returns $key Generated key - */ - public static function generateKey() { - - // $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); - - // Generate key - if ( $key = base64_encode( openssl_random_pseudo_bytes( 768000, $strong ) ) ) { - - if ( !$strong ) { - - // If OpenSSL indicates randomness is insecure, log error - \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); - - } - - return $key; - - } else { - - return false; - - } - - } - - public static function changekeypasscode($oldPassword, $newPassword) { - if(OCP\User::isLoggedIn()){ - $username=OCP\USER::getUser(); - $view=new OC_FilesystemView('/'.$username); - - // read old key - $key=$view->file_get_contents('/encryption.key'); - - // decrypt key with old passcode - $key=OC_Crypt::decrypt($key, $oldPassword); - - // encrypt again with new passcode - $key=OC_Crypt::encrypt($key, $newPassword); - - // store the new key - $view->file_put_contents('/encryption.key', $key ); - } - } - -} - + return 'server'; + + } + + /** + * @brief Create a new encryption keypair + * @return array publicKey, privatekey + */ + public static function createKeypair() { + + $res = openssl_pkey_new(); + + // Get private key + openssl_pkey_export( $res, $privateKey ); + + // Get public key + $publicKey = openssl_pkey_get_details( $res ); + + $publicKey = $publicKey['key']; + + return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) ); + + } + + /** + * @brief Check if a file's contents contains an IV and is symmetrically encrypted + * @return true / false + */ + public static function isEncryptedContent( $content ) { + + if ( !$content ) { + + return false; + + } + + // Fetch encryption metadata from end of file + $meta = substr( $content, -22 ); + + // Fetch IV from end of file + $iv = substr( $meta, -16 ); + + // Fetch identifier from start of metadata + $identifier = substr( $meta, 0, 6 ); + + if ( $identifier == '00iv00') { + + return true; + + } else { + + return false; + + } + + } + + /** + * @brief Check if a file is encrypted via legacy system + * @return true / false + */ + public static function isLegacyEncryptedContent( $content, $path ) { + + // Fetch all file metadata from DB + $metadata = \OC_FileCache_Cached::get( $content, '' ); + + // If a file is flagged with encryption in DB, but isn't a valid content + IV combination, it's probably using the legacy encryption system + if ( + $content + and isset( $metadata['encrypted'] ) + and $metadata['encrypted'] === true + and !self::isEncryptedContent( $content ) + ) { + + return true; + + } else { + + return false; + + } + + } + + /** + * @brief Symmetrically encrypt a string + * @returns encrypted file + */ + public static function encrypt( $plainContent, $iv, $passphrase = '' ) { + + if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { + + return $encryptedContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Symmetrically decrypt a string + * @returns decrypted file + */ + public static function decrypt( $encryptedContent, $iv, $passphrase ) { + + if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { + + return $plainContent; + + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Symmetrically encrypts a string and returns keyfile content + * @param $plainContent content to be encrypted in keyfile + * @returns encrypted content combined with IV + * @note IV need not be specified, as it will be stored in the returned keyfile + * and remain accessible therein. + */ + public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) { + + if ( !$plainContent ) { + + return false; + + } + + $iv = self::generateIv(); + + if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { + + // Combine content to encrypt with IV identifier and actual IV + $combinedKeyfile = $encryptedContent . '00iv00' . $iv; + + return $combinedKeyfile; + + } else { + + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + + /** + * @brief Symmetrically decrypts keyfile content + * @param string $source + * @param string $target + * @param string $key the decryption key + * + * This function decrypts a file + */ + public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) { + + if ( !$keyfileContent ) { + + return false; + + } + + // Fetch IV from end of file + $iv = substr( $keyfileContent, -16 ); + + // Remove IV and IV identifier text to expose encrypted content + $encryptedContent = substr( $keyfileContent, 0, -22 ); + + if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) { + + return $plainContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Creates symmetric keyfile content using a generated key + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function symmetricEncryptFileContentKeyfile( $plainContent ) { + + $key = self::generateKey(); + + if( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) { + + return array( + 'key' => $key + , 'encrypted' => $encryptedContent + ); + + } else { + + return false; + + } + + } + + /** + * @brief Create asymmetrically encrypted keyfile content using a generated key + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { + + $envKeys = array(); + + if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) { + + return array( + 'keys' => $envKeys + , 'encrypted' => $sealed + ); + + } else { + + return false; + + } + + } + + /** + * @brief Asymmetrically encrypt a file using multiple public keys + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function multiKeyDecrypt( $encryptedContent, $envKey, $privateKey ) { + + if ( !$encryptedContent ) { + + return false; + + } + + if ( openssl_open( $encryptedContent, $plainContent, $envKey, $privateKey ) ) { + + return $plainContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Asymetrically encrypt a string using a public key + * @returns encrypted file + */ + public static function keyEncrypt( $plainContent, $publicKey ) { + + openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey ); + + return $encryptedContent; + + } + + /** + * @brief Asymetrically decrypt a file using a private key + * @returns decrypted file + */ + public static function keyDecrypt( $encryptedContent, $privatekey ) { + + openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); + + return $plainContent; + + } + + /** + * @brief Generate a pseudo random 1024kb ASCII key + * @returns $key Generated key + */ + public static function generateIv() { + + if ( $random = openssl_random_pseudo_bytes( 13, $strong ) ) { + + if ( !$strong ) { + + // If OpenSSL indicates randomness is insecure, log error + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); + + } + + $iv = substr( base64_encode( $random ), 0, -4 ); + + return $iv; + + } else { + + return false; + + } + + } + + /** + * @brief Generate a pseudo random 1024kb ASCII key + * @returns $key Generated key + */ + public static function generateKey() { + + // $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); + + // Generate key + if ( $key = base64_encode( openssl_random_pseudo_bytes( 768000, $strong ) ) ) { + + if ( !$strong ) { + + // If OpenSSL indicates randomness is insecure, log error + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); + + } + + return $key; + + } else { + + return false; + + } + + } + + public static function changekeypasscode($oldPassword, $newPassword) { + if(OCP\User::isLoggedIn()){ + $username=OCP\USER::getUser(); + $view=new OC_FilesystemView('/'.$username); + + // read old key + $key=$view->file_get_contents('/encryption.key'); + + // decrypt key with old passcode + $key=OC_Crypt::decrypt($key, $oldPassword); + + // encrypt again with new passcode + $key=OC_Crypt::encrypt($key, $newPassword); + + // store the new key + $view->file_put_contents('/encryption.key', $key ); + } + } + +} + ?> \ No newline at end of file diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index e002053756..8c61c933cf 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -28,11 +28,11 @@ */ class OC_CryptStream{ - public static $sourceStreams=array(); + public static $sourceStreams = array(); private $source; private $path; - private $readBuffer;//for streams that dont support seeking - private $meta=array();//header/meta for source stream + private $readBuffer; // For streams that dont support seeking + private $meta = array(); // Header / meta for source stream private $count; private $writeCache; private $size; @@ -98,38 +98,69 @@ class OC_CryptStream{ return $result; } - public function stream_write($data){ - $length=strlen($data); - $written=0; - $currentPos=ftell($this->source); - if($this->writeCache){ - $data=$this->writeCache.$data; - $this->writeCache=''; + public function stream_write( $data ){ + + $length = strlen( $data ); + + $written = 0; + + $currentPos = ftell( $this->source ); + + if( $this->writeCache ){ + + $data = $this->writeCache.$data; + + $this->writeCache = ''; + } - if($currentPos%8192!=0){ + + if( $currentPos%8192 != 0 ){ + //make sure we always start on a block start - fseek($this->source,-($currentPos%8192),SEEK_CUR); - $encryptedBlock=fread($this->source,8192); - fseek($this->source,-($currentPos%8192),SEEK_CUR); - $block=OC_Crypt::decrypt($encryptedBlock); - $data=substr($block,0,$currentPos%8192).$data; - fseek($this->source,-($currentPos%8192),SEEK_CUR); + + fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); + + $encryptedBlock = fread( $this->source,8192 ); + + fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); + + $block = OC_Crypt::decrypt( $encryptedBlock ); + + $data = substr( $block,0,$currentPos%8192 ).$data; + + fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); + } - $currentPos=ftell($this->source); - while($remainingLength=strlen($data)>0){ - if($remainingLength<8192){ - $this->writeCache=$data; - $data=''; + + $currentPos = ftell( $this->source ); + + while( $remainingLength = strlen( $data )>0 ){ + + if( $remainingLength<8192 ){ + + $this->writeCache = $data; + + $data = ''; + }else{ - $encrypted=OC_Crypt::encrypt(substr($data,0,8192)); - fwrite($this->source,$encrypted); - $data=substr($data,8192); + + $encrypted = OC_Crypt::encrypt( substr( $data,0,8192 ) ); + + fwrite( $this->source,$encrypted ); + + $data = substr( $data,8192 ); + } + } - $this->size=max($this->size,$currentPos+$length); + + $this->size = max( $this->size,$currentPos+$length ); + return $length; + } + public function stream_set_option($option,$arg1,$arg2){ switch($option){ case STREAM_OPTION_BLOCKING: diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index bafe8f1a5f..0c76bf27a5 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -27,7 +27,7 @@ namespace OCA_Encryption; */ class Keymanager { - # TODO: Try and get rid of username dependencies as these methods need to be used in a proxy class that doesn't have username access + # TODO: make all dependencies explicit, such as ocfsview objects, by adding them as method arguments (dependency injection) /** * @brief retrieve private key from a user @@ -60,9 +60,9 @@ class Keymanager { * @param string user name of the file owner * @return string file key or false */ - public static function getFileKey($userId, $path) { + public static function getFileKey( $userId, $path ) { - $keypath = ltrim($path, '/'); + $keypath = ltrim( $path, '/' ); $user = $userId; // update $keypath and $user if path point to a file shared by someone else @@ -127,29 +127,33 @@ class Keymanager { * @param string $path relative path of the file, including filename * @param string $key * @return bool true/false - */ + */ public static function setFileKey( $userId, $path, $key ) { \OC_FileProxy::$enabled = false; - $targetpath = ltrim($path, '/'); + $targetpath = ltrim( $path, '/' ); $user = $userId; // update $keytarget and $user if key belongs to a file shared by someone else $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); - $result = $query->execute( array ('/'.$userId.'/files/'.$targetpath, $userId)); - if ($row = $result->fetchRow()){ + + $result = $query->execute( array ( '/'.$userId.'/files/'.$targetpath, $userId ) ); + + if ( $row = $result->fetchRow( ) ) { $targetpath = $row['source']; - $targetpath_parts=explode('/',$targetpath); + $targetpath_parts=explode( '/',$targetpath ); $user = $targetpath_parts[1]; - $targetpath = str_replace('/'.$user.'/files/', '', $targetpath); + $targetpath = str_replace( '/'.$user.'/files/', '', $targetpath ); //TODO: check for write permission on shared file once the new sharing API is in place } $view = new \OC_FilesystemView( '/' . $user . '/files_encryption/keyfiles' ); - $path_parts = pathinfo($targetpath); - if (!$view->file_exists($path_parts['dirname'])) $view->mkdir($path_parts['dirname']); + $path_parts = pathinfo( $targetpath ); + + if ( !$view->file_exists( $path_parts['dirname'] ) ) $view->mkdir( $path_parts['dirname'] ); + $result = $view->file_put_contents( '/' . $targetpath . '.key', $key ); \OC_FileProxy::$enabled = true; diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 53ed05d2c3..c1956ad021 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -109,10 +109,14 @@ class Proxy extends \OC_FileProxy { // Replace plain content with encrypted content by reference $data = $encrypted['encrypted']; - # TODO: check if file is in subdirectories, and if so, create those parent directories. Or else monitor creation of directories using hooks to ensure path will always exist (what about existing directories when encryption is enabled?) + $filePath = explode( '/', $path ); - // Save keyfile for newly encrypted file in parallel directory - Keymanager::setFileKey( \OCP\USER::getUser(), $path, $encrypted['key'] ); + $filePath = array_slice( $filePath, 3 ); + + $filePath = '/' . implode( '/', $filePath ); + + // Save keyfile for newly encrypted file in parallel directory tree + Keymanager::setFileKey( \OCP\USER::getUser(), $filePath, $encrypted['key'] ); // Update the file cache with file info \OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); @@ -124,38 +128,80 @@ class Proxy extends \OC_FileProxy { public function postFile_get_contents( $path, $data ) { if ( Crypt::isEncryptedContent( $data ) ) { - trigger_error('best'); + + $filePath = explode( '/', $path ); + + $filePath = array_slice( $filePath, 3 ); + + $filePath = '/' . implode( '/', $filePath ); + + trigger_error( "CAT " . $filePath); + $cached = \OC_FileCache_Cached::get( $path, '' ); - $data = Crypt::symmetricDecryptFileContent( $data, $_SESSION['enckey'] ); + // Get keyfile for encrypted file + $keyFile = Keymanager::getFileKey( \OCP\USER::getUser(), $filePath ); + + $data = Crypt::symmetricDecryptFileContent( $data, $keyFile ); } return $data; + } - public function postFopen($path,&$result){ + public function postFopen( $path, &$result ){ - if(!$result){ + if ( !$result ) { + return $result; + } - $meta=stream_get_meta_data($result); - if(Crypt::isEncryptedContent($path)){ - fclose($result); - $result=fopen('crypt://'.$path,$meta['mode']); - }elseif(self::shouldEncrypt($path) and $meta['mode']!='r' and $meta['mode']!='rb'){ - if( \OC_Filesystem::file_exists( $path ) and \OC_Filesystem::filesize($path)>0){ + + $meta = stream_get_meta_data( $result ); + + // If file is encrypted, decrypt using crypto protocol + if ( Crypt::isEncryptedContent( $path ) ) { + + fclose ( $result ); + + $result = fopen( 'crypt://'.$path, $meta['mode'] ); + + } elseif ( + self::shouldEncrypt( $path ) + and $meta ['mode'] != 'r' + and $meta['mode'] != 'rb' + ) { + + # TODO: figure out what this does + + if ( + \OC_Filesystem::file_exists( $path ) + and \OC_Filesystem::filesize( $path ) > 0 + ) { + //first encrypt the target file so we don't end up with a half encrypted file - \OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing', \OCP\Util::DEBUG); - $tmp=fopen('php://temp'); - \OCP\Files::streamCopy($result,$tmp); - fclose($result); - \OC_Filesystem::file_put_contents($path,$tmp); - fclose($tmp); + \OCP\Util::writeLog( 'files_encryption', 'Decrypting '.$path.' before writing', \OCP\Util::DEBUG ); + + $tmp = fopen( 'php://temp' ); + + \OCP\Files::streamCopy( $result, $tmp ); + + // Close the original stream, we'll return another one + fclose( $result ); + + \OC_Filesystem::file_put_contents( $path, $tmp ); + + fclose( $tmp ); + } - $result=fopen('crypt://'.$path,$meta['mode']); + + $result = fopen( 'crypt://'.$path, $meta['mode'] ); + } + return $result; + } public function postGetMimeType($path,$mime){ diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index ab58b4aa72..609f787124 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -44,18 +44,19 @@ class Util { # DONE: add method to check if file is encrypted using old system # DONE: add method to fetch legacy key # DONE: add method to decrypt legacy encrypted data + # DONE: fix / test the crypt stream proxy class + + # TODO: replace cryptstream wrapper with stream_socket_enable_crypto, or fix it to use new crypt class methods + # TODO: add support for optional recovery user in case of lost passphrase / keys + # TODO: add admin optional required long passphrase for users + # TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc. + # TODO: add UI buttons for encrypt / decrypt everything? # TODO: add method to encrypt all user files using new system # TODO: add method to decrypt all user files using new system # TODO: add method to encrypt all user files using old system # TODO: add method to decrypt all user files using old system - # TODO: fix / test the crypt stream proxy class - # TODO: add support for optional recovery user in case of lost passphrase / keys - # TODO: add admin optional required long passphrase for users - # TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc. - # TODO: add UI buttons for encrypt / decrypt everything? - # TODO: test new encryption with webdav # TODO: test new encryption with versioning # TODO: test new encryption with sharing @@ -154,6 +155,89 @@ class Util { } + public function findFiles( $directory, $type = 'plain' ) { + + # TODO: test finding non plain content + + if ( $handle = $this->view->opendir( $directory ) ) { + + while ( false !== ( $file = readdir( $handle ) ) ) { + + if ( + $file != "." + && $file != ".." + ) { + + $filePath = $directory . '/' . $this->view->getRelativePath( '/' . $file ); + + var_dump($filePath); + + if ( $this->view->is_dir( $filePath ) ) { + + $this->findFiles( $filePath ); + + } elseif ( $this->view->is_file( $filePath ) ) { + + if ( $type == 'plain' ) { + + $this->files[] = array( 'name' => $file, 'path' => $filePath ); + + } elseif ( $type == 'encrypted' ) { + + if ( Crypt::isEncryptedContent( $this->view->file_get_contents( $filePath ) ) ) { + + $this->files[] = array( 'name' => $file, 'path' => $filePath ); + + } + + } elseif ( $type == 'legacy' ) { + + if ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ) ) ) { + + $this->files[] = array( 'name' => $file, 'path' => $filePath ); + + } + + } + + } + + } + + } + + if ( !empty( $this->files ) ) { + + return $this->files; + + } else { + + return false; + + } + + } + + return false; + + } + + public function encryptAll( OC_FilesystemView $view ) { + + $plainFiles = $this->findPlainFiles( $view ); + + if ( $this->encryptFiles( $plainFiles ) ) { + + return true; + + } else { + + return false; + + } + + } + /** * @brief Get the blowfish encryption handeler for a key * @param $key string (optional) From 84fd62b13047cb756d9f39c192e17fd5f2179f83 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 31 Jul 2012 19:35:36 +0100 Subject: [PATCH 028/315] Implemented writing of keyfiles and directory hierarchy in proxy class Added crypt::findFiles() method for finding different types of files, ready for batch encrypting / decrypting Added comments to postFopen in proxy class --- apps/files_encryption/hooks/hooks.php | 4 +- apps/files_encryption/lib/crypt.php | 843 +++++++++++----------- apps/files_encryption/lib/cryptstream.php | 83 ++- apps/files_encryption/lib/keymanager.php | 26 +- apps/files_encryption/lib/proxy.php | 86 ++- apps/files_encryption/lib/util.php | 96 ++- 6 files changed, 653 insertions(+), 485 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 35e14e2810..d06e9a0d2d 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -37,14 +37,14 @@ class Hooks { public static function login( $params ) { - if (Crypt::mode($params['uid'])=='server') { + if ( Crypt::mode( $params['uid'] ) == 'server' ) { $view = new \OC_FilesystemView( '/' ); $util = new Util( $view, $params['uid'] ); if ( !$util->ready()) { - + return $util->setupServerSide( $params['password'] ); } diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index fdace3e61d..7e50c900fa 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -1,426 +1,429 @@ -. - * - */ - -namespace OCA_Encryption; - -/** - * Class for common cryptography functionality - */ - -class Crypt { - +. + * + */ + +namespace OCA_Encryption; + +/** + * Class for common cryptography functionality + */ + +class Crypt { + /** - * @brief return encryption mode client or server side encryption + * @brief return encryption mode client or server side encryption * @param string user name (use system wide setting if name=null) * @return string 'client' or 'server' */ - public static function mode($user=null) { - - $mode = \OC_Appconfig::getValue('files_encryption', 'mode', 'unknown'); - - if ($mode == 'unknown') { - error_log('no encryption mode configured'); - return false; - } - + public static function mode( $user = null ) { + + $mode = \OC_Appconfig::getValue( 'files_encryption', 'mode', 'unknown' ); + + if ( $mode == 'unknown' ) { + + error_log('no encryption mode configured'); + + return false; + + } + return $mode; - } - - /** - * @brief Create a new encryption keypair - * @return array publicKey, privatekey - */ - public static function createKeypair() { - - $res = openssl_pkey_new(); - - // Get private key - openssl_pkey_export( $res, $privateKey ); - - // Get public key - $publicKey = openssl_pkey_get_details( $res ); - - $publicKey = $publicKey['key']; - - return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) ); - - } - - /** - * @brief Check if a file's contents contains an IV and is symmetrically encrypted - * @return true / false - */ - public static function isEncryptedContent( $content ) { - - if ( !$content ) { - - return false; - - } - - // Fetch encryption metadata from end of file - $meta = substr( $content, -22 ); - - // Fetch IV from end of file - $iv = substr( $meta, -16 ); - - // Fetch identifier from start of metadata - $identifier = substr( $meta, 0, 6 ); - - if ( $identifier == '00iv00') { - - return true; - - } else { - - return false; - - } - - } - - /** - * @brief Check if a file is encrypted via legacy system - * @return true / false - */ - public static function isLegacyEncryptedContent( $content, $path ) { - - // Fetch all file metadata from DB - $metadata = \OC_FileCache_Cached::get( $content, '' ); - - // If a file is flagged with encryption in DB, but isn't a valid content + IV combination, it's probably using the legacy encryption system - if ( - $content - and isset( $metadata['encrypted'] ) - and $metadata['encrypted'] === true - and !self::isEncryptedContent( $content ) - ) { - - return true; - - } else { - - return false; - - } - - } - - /** - * @brief Symmetrically encrypt a string - * @returns encrypted file - */ - public static function encrypt( $plainContent, $iv, $passphrase = '' ) { - - if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { - - return $encryptedContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Symmetrically decrypt a string - * @returns decrypted file - */ - public static function decrypt( $encryptedContent, $iv, $passphrase ) { - - if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { - - return $plainContent; - - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Symmetrically encrypts a string and returns keyfile content - * @param $plainContent content to be encrypted in keyfile - * @returns encrypted content combined with IV - * @note IV need not be specified, as it will be stored in the returned keyfile - * and remain accessible therein. - */ - public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) { - - if ( !$plainContent ) { - - return false; - - } - - $iv = self::generateIv(); - - if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { - - // Combine content to encrypt with IV identifier and actual IV - $combinedKeyfile = $encryptedContent . '00iv00' . $iv; - - return $combinedKeyfile; - - } else { - - \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - - /** - * @brief Symmetrically decrypts keyfile content - * @param string $source - * @param string $target - * @param string $key the decryption key - * - * This function decrypts a file - */ - public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) { - - if ( !$keyfileContent ) { - - return false; - - } - - // Fetch IV from end of file - $iv = substr( $keyfileContent, -16 ); - - // Remove IV and IV identifier text to expose encrypted content - $encryptedContent = substr( $keyfileContent, 0, -22 ); - - if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) { - - return $plainContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Creates symmetric keyfile content using a generated key - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function symmetricEncryptFileContentKeyfile( $plainContent ) { - - $key = self::generateKey(); - - if( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) { - - return array( - 'key' => $key - , 'encrypted' => $encryptedContent - ); - - } else { - - return false; - - } - - } - - /** - * @brief Create asymmetrically encrypted keyfile content using a generated key - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { - - $envKeys = array(); - - if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) { - - return array( - 'keys' => $envKeys - , 'encrypted' => $sealed - ); - - } else { - - return false; - - } - - } - - /** - * @brief Asymmetrically encrypt a file using multiple public keys - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function multiKeyDecrypt( $encryptedContent, $envKey, $privateKey ) { - - if ( !$encryptedContent ) { - - return false; - - } - - if ( openssl_open( $encryptedContent, $plainContent, $envKey, $privateKey ) ) { - - return $plainContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Asymetrically encrypt a string using a public key - * @returns encrypted file - */ - public static function keyEncrypt( $plainContent, $publicKey ) { - - openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey ); - - return $encryptedContent; - - } - - /** - * @brief Asymetrically decrypt a file using a private key - * @returns decrypted file - */ - public static function keyDecrypt( $encryptedContent, $privatekey ) { - - openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); - - return $plainContent; - - } - - /** - * @brief Generate a pseudo random 1024kb ASCII key - * @returns $key Generated key - */ - public static function generateIv() { - - if ( $random = openssl_random_pseudo_bytes( 13, $strong ) ) { - - if ( !$strong ) { - - // If OpenSSL indicates randomness is insecure, log error - \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); - - } - - $iv = substr( base64_encode( $random ), 0, -4 ); - - return $iv; - - } else { - - return false; - - } - - } - - /** - * @brief Generate a pseudo random 1024kb ASCII key - * @returns $key Generated key - */ - public static function generateKey() { - - // $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); - - // Generate key - if ( $key = base64_encode( openssl_random_pseudo_bytes( 768000, $strong ) ) ) { - - if ( !$strong ) { - - // If OpenSSL indicates randomness is insecure, log error - \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); - - } - - return $key; - - } else { - - return false; - - } - - } - - public static function changekeypasscode($oldPassword, $newPassword) { - if(OCP\User::isLoggedIn()){ - $username=OCP\USER::getUser(); - $view=new OC_FilesystemView('/'.$username); - - // read old key - $key=$view->file_get_contents('/encryption.key'); - - // decrypt key with old passcode - $key=OC_Crypt::decrypt($key, $oldPassword); - - // encrypt again with new passcode - $key=OC_Crypt::encrypt($key, $newPassword); - - // store the new key - $view->file_put_contents('/encryption.key', $key ); - } - } - -} - + } + + /** + * @brief Create a new encryption keypair + * @return array publicKey, privatekey + */ + public static function createKeypair() { + + $res = openssl_pkey_new(); + + // Get private key + openssl_pkey_export( $res, $privateKey ); + + // Get public key + $publicKey = openssl_pkey_get_details( $res ); + + $publicKey = $publicKey['key']; + + return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) ); + + } + + /** + * @brief Check if a file's contents contains an IV and is symmetrically encrypted + * @return true / false + */ + public static function isEncryptedContent( $content ) { + + if ( !$content ) { + + return false; + + } + + // Fetch encryption metadata from end of file + $meta = substr( $content, -22 ); + + // Fetch IV from end of file + $iv = substr( $meta, -16 ); + + // Fetch identifier from start of metadata + $identifier = substr( $meta, 0, 6 ); + + if ( $identifier == '00iv00') { + + return true; + + } else { + + return false; + + } + + } + + /** + * @brief Check if a file is encrypted via legacy system + * @return true / false + */ + public static function isLegacyEncryptedContent( $content, $path ) { + + // Fetch all file metadata from DB + $metadata = \OC_FileCache_Cached::get( $content, '' ); + + // If a file is flagged with encryption in DB, but isn't a valid content + IV combination, it's probably using the legacy encryption system + if ( + $content + and isset( $metadata['encrypted'] ) + and $metadata['encrypted'] === true + and !self::isEncryptedContent( $content ) + ) { + + return true; + + } else { + + return false; + + } + + } + + /** + * @brief Symmetrically encrypt a string + * @returns encrypted file + */ + public static function encrypt( $plainContent, $iv, $passphrase = '' ) { + + if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { + + return $encryptedContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Symmetrically decrypt a string + * @returns decrypted file + */ + public static function decrypt( $encryptedContent, $iv, $passphrase ) { + + if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { + + return $plainContent; + + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Symmetrically encrypts a string and returns keyfile content + * @param $plainContent content to be encrypted in keyfile + * @returns encrypted content combined with IV + * @note IV need not be specified, as it will be stored in the returned keyfile + * and remain accessible therein. + */ + public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) { + + if ( !$plainContent ) { + + return false; + + } + + $iv = self::generateIv(); + + if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { + + // Combine content to encrypt with IV identifier and actual IV + $combinedKeyfile = $encryptedContent . '00iv00' . $iv; + + return $combinedKeyfile; + + } else { + + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + + /** + * @brief Symmetrically decrypts keyfile content + * @param string $source + * @param string $target + * @param string $key the decryption key + * + * This function decrypts a file + */ + public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) { + + if ( !$keyfileContent ) { + + return false; + + } + + // Fetch IV from end of file + $iv = substr( $keyfileContent, -16 ); + + // Remove IV and IV identifier text to expose encrypted content + $encryptedContent = substr( $keyfileContent, 0, -22 ); + + if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) { + + return $plainContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Creates symmetric keyfile content using a generated key + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function symmetricEncryptFileContentKeyfile( $plainContent ) { + + $key = self::generateKey(); + + if( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) { + + return array( + 'key' => $key + , 'encrypted' => $encryptedContent + ); + + } else { + + return false; + + } + + } + + /** + * @brief Create asymmetrically encrypted keyfile content using a generated key + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { + + $envKeys = array(); + + if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) { + + return array( + 'keys' => $envKeys + , 'encrypted' => $sealed + ); + + } else { + + return false; + + } + + } + + /** + * @brief Asymmetrically encrypt a file using multiple public keys + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function multiKeyDecrypt( $encryptedContent, $envKey, $privateKey ) { + + if ( !$encryptedContent ) { + + return false; + + } + + if ( openssl_open( $encryptedContent, $plainContent, $envKey, $privateKey ) ) { + + return $plainContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Asymetrically encrypt a string using a public key + * @returns encrypted file + */ + public static function keyEncrypt( $plainContent, $publicKey ) { + + openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey ); + + return $encryptedContent; + + } + + /** + * @brief Asymetrically decrypt a file using a private key + * @returns decrypted file + */ + public static function keyDecrypt( $encryptedContent, $privatekey ) { + + openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); + + return $plainContent; + + } + + /** + * @brief Generate a pseudo random 1024kb ASCII key + * @returns $key Generated key + */ + public static function generateIv() { + + if ( $random = openssl_random_pseudo_bytes( 13, $strong ) ) { + + if ( !$strong ) { + + // If OpenSSL indicates randomness is insecure, log error + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); + + } + + $iv = substr( base64_encode( $random ), 0, -4 ); + + return $iv; + + } else { + + return false; + + } + + } + + /** + * @brief Generate a pseudo random 1024kb ASCII key + * @returns $key Generated key + */ + public static function generateKey() { + + // $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); + + // Generate key + if ( $key = base64_encode( openssl_random_pseudo_bytes( 768000, $strong ) ) ) { + + if ( !$strong ) { + + // If OpenSSL indicates randomness is insecure, log error + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); + + } + + return $key; + + } else { + + return false; + + } + + } + + public static function changekeypasscode($oldPassword, $newPassword) { + if(OCP\User::isLoggedIn()){ + $username=OCP\USER::getUser(); + $view=new OC_FilesystemView('/'.$username); + + // read old key + $key=$view->file_get_contents('/encryption.key'); + + // decrypt key with old passcode + $key=OC_Crypt::decrypt($key, $oldPassword); + + // encrypt again with new passcode + $key=OC_Crypt::encrypt($key, $newPassword); + + // store the new key + $view->file_put_contents('/encryption.key', $key ); + } + } + +} + ?> \ No newline at end of file diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index e002053756..8c61c933cf 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -28,11 +28,11 @@ */ class OC_CryptStream{ - public static $sourceStreams=array(); + public static $sourceStreams = array(); private $source; private $path; - private $readBuffer;//for streams that dont support seeking - private $meta=array();//header/meta for source stream + private $readBuffer; // For streams that dont support seeking + private $meta = array(); // Header / meta for source stream private $count; private $writeCache; private $size; @@ -98,38 +98,69 @@ class OC_CryptStream{ return $result; } - public function stream_write($data){ - $length=strlen($data); - $written=0; - $currentPos=ftell($this->source); - if($this->writeCache){ - $data=$this->writeCache.$data; - $this->writeCache=''; + public function stream_write( $data ){ + + $length = strlen( $data ); + + $written = 0; + + $currentPos = ftell( $this->source ); + + if( $this->writeCache ){ + + $data = $this->writeCache.$data; + + $this->writeCache = ''; + } - if($currentPos%8192!=0){ + + if( $currentPos%8192 != 0 ){ + //make sure we always start on a block start - fseek($this->source,-($currentPos%8192),SEEK_CUR); - $encryptedBlock=fread($this->source,8192); - fseek($this->source,-($currentPos%8192),SEEK_CUR); - $block=OC_Crypt::decrypt($encryptedBlock); - $data=substr($block,0,$currentPos%8192).$data; - fseek($this->source,-($currentPos%8192),SEEK_CUR); + + fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); + + $encryptedBlock = fread( $this->source,8192 ); + + fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); + + $block = OC_Crypt::decrypt( $encryptedBlock ); + + $data = substr( $block,0,$currentPos%8192 ).$data; + + fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); + } - $currentPos=ftell($this->source); - while($remainingLength=strlen($data)>0){ - if($remainingLength<8192){ - $this->writeCache=$data; - $data=''; + + $currentPos = ftell( $this->source ); + + while( $remainingLength = strlen( $data )>0 ){ + + if( $remainingLength<8192 ){ + + $this->writeCache = $data; + + $data = ''; + }else{ - $encrypted=OC_Crypt::encrypt(substr($data,0,8192)); - fwrite($this->source,$encrypted); - $data=substr($data,8192); + + $encrypted = OC_Crypt::encrypt( substr( $data,0,8192 ) ); + + fwrite( $this->source,$encrypted ); + + $data = substr( $data,8192 ); + } + } - $this->size=max($this->size,$currentPos+$length); + + $this->size = max( $this->size,$currentPos+$length ); + return $length; + } + public function stream_set_option($option,$arg1,$arg2){ switch($option){ case STREAM_OPTION_BLOCKING: diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index bafe8f1a5f..0c76bf27a5 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -27,7 +27,7 @@ namespace OCA_Encryption; */ class Keymanager { - # TODO: Try and get rid of username dependencies as these methods need to be used in a proxy class that doesn't have username access + # TODO: make all dependencies explicit, such as ocfsview objects, by adding them as method arguments (dependency injection) /** * @brief retrieve private key from a user @@ -60,9 +60,9 @@ class Keymanager { * @param string user name of the file owner * @return string file key or false */ - public static function getFileKey($userId, $path) { + public static function getFileKey( $userId, $path ) { - $keypath = ltrim($path, '/'); + $keypath = ltrim( $path, '/' ); $user = $userId; // update $keypath and $user if path point to a file shared by someone else @@ -127,29 +127,33 @@ class Keymanager { * @param string $path relative path of the file, including filename * @param string $key * @return bool true/false - */ + */ public static function setFileKey( $userId, $path, $key ) { \OC_FileProxy::$enabled = false; - $targetpath = ltrim($path, '/'); + $targetpath = ltrim( $path, '/' ); $user = $userId; // update $keytarget and $user if key belongs to a file shared by someone else $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); - $result = $query->execute( array ('/'.$userId.'/files/'.$targetpath, $userId)); - if ($row = $result->fetchRow()){ + + $result = $query->execute( array ( '/'.$userId.'/files/'.$targetpath, $userId ) ); + + if ( $row = $result->fetchRow( ) ) { $targetpath = $row['source']; - $targetpath_parts=explode('/',$targetpath); + $targetpath_parts=explode( '/',$targetpath ); $user = $targetpath_parts[1]; - $targetpath = str_replace('/'.$user.'/files/', '', $targetpath); + $targetpath = str_replace( '/'.$user.'/files/', '', $targetpath ); //TODO: check for write permission on shared file once the new sharing API is in place } $view = new \OC_FilesystemView( '/' . $user . '/files_encryption/keyfiles' ); - $path_parts = pathinfo($targetpath); - if (!$view->file_exists($path_parts['dirname'])) $view->mkdir($path_parts['dirname']); + $path_parts = pathinfo( $targetpath ); + + if ( !$view->file_exists( $path_parts['dirname'] ) ) $view->mkdir( $path_parts['dirname'] ); + $result = $view->file_put_contents( '/' . $targetpath . '.key', $key ); \OC_FileProxy::$enabled = true; diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 53ed05d2c3..c1956ad021 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -109,10 +109,14 @@ class Proxy extends \OC_FileProxy { // Replace plain content with encrypted content by reference $data = $encrypted['encrypted']; - # TODO: check if file is in subdirectories, and if so, create those parent directories. Or else monitor creation of directories using hooks to ensure path will always exist (what about existing directories when encryption is enabled?) + $filePath = explode( '/', $path ); - // Save keyfile for newly encrypted file in parallel directory - Keymanager::setFileKey( \OCP\USER::getUser(), $path, $encrypted['key'] ); + $filePath = array_slice( $filePath, 3 ); + + $filePath = '/' . implode( '/', $filePath ); + + // Save keyfile for newly encrypted file in parallel directory tree + Keymanager::setFileKey( \OCP\USER::getUser(), $filePath, $encrypted['key'] ); // Update the file cache with file info \OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); @@ -124,38 +128,80 @@ class Proxy extends \OC_FileProxy { public function postFile_get_contents( $path, $data ) { if ( Crypt::isEncryptedContent( $data ) ) { - trigger_error('best'); + + $filePath = explode( '/', $path ); + + $filePath = array_slice( $filePath, 3 ); + + $filePath = '/' . implode( '/', $filePath ); + + trigger_error( "CAT " . $filePath); + $cached = \OC_FileCache_Cached::get( $path, '' ); - $data = Crypt::symmetricDecryptFileContent( $data, $_SESSION['enckey'] ); + // Get keyfile for encrypted file + $keyFile = Keymanager::getFileKey( \OCP\USER::getUser(), $filePath ); + + $data = Crypt::symmetricDecryptFileContent( $data, $keyFile ); } return $data; + } - public function postFopen($path,&$result){ + public function postFopen( $path, &$result ){ - if(!$result){ + if ( !$result ) { + return $result; + } - $meta=stream_get_meta_data($result); - if(Crypt::isEncryptedContent($path)){ - fclose($result); - $result=fopen('crypt://'.$path,$meta['mode']); - }elseif(self::shouldEncrypt($path) and $meta['mode']!='r' and $meta['mode']!='rb'){ - if( \OC_Filesystem::file_exists( $path ) and \OC_Filesystem::filesize($path)>0){ + + $meta = stream_get_meta_data( $result ); + + // If file is encrypted, decrypt using crypto protocol + if ( Crypt::isEncryptedContent( $path ) ) { + + fclose ( $result ); + + $result = fopen( 'crypt://'.$path, $meta['mode'] ); + + } elseif ( + self::shouldEncrypt( $path ) + and $meta ['mode'] != 'r' + and $meta['mode'] != 'rb' + ) { + + # TODO: figure out what this does + + if ( + \OC_Filesystem::file_exists( $path ) + and \OC_Filesystem::filesize( $path ) > 0 + ) { + //first encrypt the target file so we don't end up with a half encrypted file - \OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing', \OCP\Util::DEBUG); - $tmp=fopen('php://temp'); - \OCP\Files::streamCopy($result,$tmp); - fclose($result); - \OC_Filesystem::file_put_contents($path,$tmp); - fclose($tmp); + \OCP\Util::writeLog( 'files_encryption', 'Decrypting '.$path.' before writing', \OCP\Util::DEBUG ); + + $tmp = fopen( 'php://temp' ); + + \OCP\Files::streamCopy( $result, $tmp ); + + // Close the original stream, we'll return another one + fclose( $result ); + + \OC_Filesystem::file_put_contents( $path, $tmp ); + + fclose( $tmp ); + } - $result=fopen('crypt://'.$path,$meta['mode']); + + $result = fopen( 'crypt://'.$path, $meta['mode'] ); + } + return $result; + } public function postGetMimeType($path,$mime){ diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index ab58b4aa72..609f787124 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -44,18 +44,19 @@ class Util { # DONE: add method to check if file is encrypted using old system # DONE: add method to fetch legacy key # DONE: add method to decrypt legacy encrypted data + # DONE: fix / test the crypt stream proxy class + + # TODO: replace cryptstream wrapper with stream_socket_enable_crypto, or fix it to use new crypt class methods + # TODO: add support for optional recovery user in case of lost passphrase / keys + # TODO: add admin optional required long passphrase for users + # TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc. + # TODO: add UI buttons for encrypt / decrypt everything? # TODO: add method to encrypt all user files using new system # TODO: add method to decrypt all user files using new system # TODO: add method to encrypt all user files using old system # TODO: add method to decrypt all user files using old system - # TODO: fix / test the crypt stream proxy class - # TODO: add support for optional recovery user in case of lost passphrase / keys - # TODO: add admin optional required long passphrase for users - # TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc. - # TODO: add UI buttons for encrypt / decrypt everything? - # TODO: test new encryption with webdav # TODO: test new encryption with versioning # TODO: test new encryption with sharing @@ -154,6 +155,89 @@ class Util { } + public function findFiles( $directory, $type = 'plain' ) { + + # TODO: test finding non plain content + + if ( $handle = $this->view->opendir( $directory ) ) { + + while ( false !== ( $file = readdir( $handle ) ) ) { + + if ( + $file != "." + && $file != ".." + ) { + + $filePath = $directory . '/' . $this->view->getRelativePath( '/' . $file ); + + var_dump($filePath); + + if ( $this->view->is_dir( $filePath ) ) { + + $this->findFiles( $filePath ); + + } elseif ( $this->view->is_file( $filePath ) ) { + + if ( $type == 'plain' ) { + + $this->files[] = array( 'name' => $file, 'path' => $filePath ); + + } elseif ( $type == 'encrypted' ) { + + if ( Crypt::isEncryptedContent( $this->view->file_get_contents( $filePath ) ) ) { + + $this->files[] = array( 'name' => $file, 'path' => $filePath ); + + } + + } elseif ( $type == 'legacy' ) { + + if ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ) ) ) { + + $this->files[] = array( 'name' => $file, 'path' => $filePath ); + + } + + } + + } + + } + + } + + if ( !empty( $this->files ) ) { + + return $this->files; + + } else { + + return false; + + } + + } + + return false; + + } + + public function encryptAll( OC_FilesystemView $view ) { + + $plainFiles = $this->findPlainFiles( $view ); + + if ( $this->encryptFiles( $plainFiles ) ) { + + return true; + + } else { + + return false; + + } + + } + /** * @brief Get the blowfish encryption handeler for a key * @param $key string (optional) From a7f3a67bc2c7b923316ab440f7a76f32531e42fd Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 1 Aug 2012 10:37:21 +0200 Subject: [PATCH 029/315] get settings from DB and check the right checkbox in the settings --- apps/files_encryption/settings.php | 2 +- apps/files_encryption/templates/settings.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files_encryption/settings.php b/apps/files_encryption/settings.php index 0a0d4d1abb..a4e91627dd 100644 --- a/apps/files_encryption/settings.php +++ b/apps/files_encryption/settings.php @@ -10,7 +10,7 @@ $tmpl = new OCP\Template( 'files_encryption', 'settings'); $blackList=explode(',',OCP\Config::getAppValue('files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg')); $enabled=(OCP\Config::getAppValue('files_encryption','enable_encryption','true')=='true'); $tmpl->assign('blacklist',$blackList); -$tmpl->assign('encryption_enabled',$enabled); +$tmpl->assign('encryption_mode',\OC_Appconfig::getValue('files_encryption', 'mode', 'none')); OCP\Util::addscript('files_encryption','settings'); OCP\Util::addscript('core','multiselect'); diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php index 80b3da84ca..38c89ecde3 100644 --- a/apps/files_encryption/templates/settings.php +++ b/apps/files_encryption/templates/settings.php @@ -4,9 +4,9 @@ Choose encryption mode:

- Client side encryption (most secure but makes it impossible to access your data from the web interface)
- Server side encryption (allows you to access your files from the web interface and the desktop client)
- None (no encryption at all)
+ /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
+ /> Server side encryption (allows you to access your files from the web interface and the desktop client)
+ /> None (no encryption at all)

t('Encryption'); ?> From c4d1ad1b7d4507e387a5833622b4831044eb9e09 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 1 Aug 2012 14:11:41 +0100 Subject: [PATCH 030/315] Made dependencies of Kaymanager::setFileKey() explicit using dependency injection --- apps/files_encryption/lib/crypt.php | 822 +++++++++++------------ apps/files_encryption/lib/keymanager.php | 31 +- apps/files_encryption/lib/proxy.php | 5 +- 3 files changed, 432 insertions(+), 426 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 8cd8de73bc..7e50c900fa 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -1,37 +1,37 @@ -. - * - */ - -namespace OCA_Encryption; - -/** - * Class for common cryptography functionality - */ - -class Crypt { - +. + * + */ + +namespace OCA_Encryption; + +/** + * Class for common cryptography functionality + */ + +class Crypt { + /** - * @brief return encryption mode client or server side encryption + * @brief return encryption mode client or server side encryption * @param string user name (use system wide setting if name=null) * @return string 'client' or 'server' */ @@ -48,382 +48,382 @@ class Crypt { } return $mode; - } - - /** - * @brief Create a new encryption keypair - * @return array publicKey, privatekey - */ - public static function createKeypair() { - - $res = openssl_pkey_new(); - - // Get private key - openssl_pkey_export( $res, $privateKey ); - - // Get public key - $publicKey = openssl_pkey_get_details( $res ); - - $publicKey = $publicKey['key']; - - return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) ); - - } - - /** - * @brief Check if a file's contents contains an IV and is symmetrically encrypted - * @return true / false - */ - public static function isEncryptedContent( $content ) { - - if ( !$content ) { - - return false; - - } - - // Fetch encryption metadata from end of file - $meta = substr( $content, -22 ); - - // Fetch IV from end of file - $iv = substr( $meta, -16 ); - - // Fetch identifier from start of metadata - $identifier = substr( $meta, 0, 6 ); - - if ( $identifier == '00iv00') { - - return true; - - } else { - - return false; - - } - - } - - /** - * @brief Check if a file is encrypted via legacy system - * @return true / false - */ - public static function isLegacyEncryptedContent( $content, $path ) { - - // Fetch all file metadata from DB - $metadata = \OC_FileCache_Cached::get( $content, '' ); - - // If a file is flagged with encryption in DB, but isn't a valid content + IV combination, it's probably using the legacy encryption system - if ( - $content - and isset( $metadata['encrypted'] ) - and $metadata['encrypted'] === true - and !self::isEncryptedContent( $content ) - ) { - - return true; - - } else { - - return false; - - } - - } - - /** - * @brief Symmetrically encrypt a string - * @returns encrypted file - */ - public static function encrypt( $plainContent, $iv, $passphrase = '' ) { - - if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { - - return $encryptedContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Symmetrically decrypt a string - * @returns decrypted file - */ - public static function decrypt( $encryptedContent, $iv, $passphrase ) { - - if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { - - return $plainContent; - - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Symmetrically encrypts a string and returns keyfile content - * @param $plainContent content to be encrypted in keyfile - * @returns encrypted content combined with IV - * @note IV need not be specified, as it will be stored in the returned keyfile - * and remain accessible therein. - */ - public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) { - - if ( !$plainContent ) { - - return false; - - } - - $iv = self::generateIv(); - - if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { - - // Combine content to encrypt with IV identifier and actual IV - $combinedKeyfile = $encryptedContent . '00iv00' . $iv; - - return $combinedKeyfile; - - } else { - - \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - - /** - * @brief Symmetrically decrypts keyfile content - * @param string $source - * @param string $target - * @param string $key the decryption key - * - * This function decrypts a file - */ - public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) { - - if ( !$keyfileContent ) { - - return false; - - } - - // Fetch IV from end of file - $iv = substr( $keyfileContent, -16 ); - - // Remove IV and IV identifier text to expose encrypted content - $encryptedContent = substr( $keyfileContent, 0, -22 ); - - if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) { - - return $plainContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Creates symmetric keyfile content using a generated key - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function symmetricEncryptFileContentKeyfile( $plainContent ) { - - $key = self::generateKey(); - - if( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) { - - return array( - 'key' => $key - , 'encrypted' => $encryptedContent - ); - - } else { - - return false; - - } - - } - - /** - * @brief Create asymmetrically encrypted keyfile content using a generated key - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { - - $envKeys = array(); - - if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) { - - return array( - 'keys' => $envKeys - , 'encrypted' => $sealed - ); - - } else { - - return false; - - } - - } - - /** - * @brief Asymmetrically encrypt a file using multiple public keys - * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted - * @note symmetricDecryptFileContent() can be used to decrypt files created using this method - * - * This function decrypts a file - */ - public static function multiKeyDecrypt( $encryptedContent, $envKey, $privateKey ) { - - if ( !$encryptedContent ) { - - return false; - - } - - if ( openssl_open( $encryptedContent, $plainContent, $envKey, $privateKey ) ) { - - return $plainContent; - - } else { - - \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed' , \OC_Log::ERROR ); - - return false; - - } - - } - - /** - * @brief Asymetrically encrypt a string using a public key - * @returns encrypted file - */ - public static function keyEncrypt( $plainContent, $publicKey ) { - - openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey ); - - return $encryptedContent; - - } - - /** - * @brief Asymetrically decrypt a file using a private key - * @returns decrypted file - */ - public static function keyDecrypt( $encryptedContent, $privatekey ) { - - openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); - - return $plainContent; - - } - - /** - * @brief Generate a pseudo random 1024kb ASCII key - * @returns $key Generated key - */ - public static function generateIv() { - - if ( $random = openssl_random_pseudo_bytes( 13, $strong ) ) { - - if ( !$strong ) { - - // If OpenSSL indicates randomness is insecure, log error - \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); - - } - - $iv = substr( base64_encode( $random ), 0, -4 ); - - return $iv; - - } else { - - return false; - - } - - } - - /** - * @brief Generate a pseudo random 1024kb ASCII key - * @returns $key Generated key - */ - public static function generateKey() { - - // $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); - - // Generate key - if ( $key = base64_encode( openssl_random_pseudo_bytes( 768000, $strong ) ) ) { - - if ( !$strong ) { - - // If OpenSSL indicates randomness is insecure, log error - \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); - - } - - return $key; - - } else { - - return false; - - } - - } - - public static function changekeypasscode($oldPassword, $newPassword) { - if(OCP\User::isLoggedIn()){ - $username=OCP\USER::getUser(); - $view=new OC_FilesystemView('/'.$username); - - // read old key - $key=$view->file_get_contents('/encryption.key'); - - // decrypt key with old passcode - $key=OC_Crypt::decrypt($key, $oldPassword); - - // encrypt again with new passcode - $key=OC_Crypt::encrypt($key, $newPassword); - - // store the new key - $view->file_put_contents('/encryption.key', $key ); - } - } - -} - + } + + /** + * @brief Create a new encryption keypair + * @return array publicKey, privatekey + */ + public static function createKeypair() { + + $res = openssl_pkey_new(); + + // Get private key + openssl_pkey_export( $res, $privateKey ); + + // Get public key + $publicKey = openssl_pkey_get_details( $res ); + + $publicKey = $publicKey['key']; + + return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) ); + + } + + /** + * @brief Check if a file's contents contains an IV and is symmetrically encrypted + * @return true / false + */ + public static function isEncryptedContent( $content ) { + + if ( !$content ) { + + return false; + + } + + // Fetch encryption metadata from end of file + $meta = substr( $content, -22 ); + + // Fetch IV from end of file + $iv = substr( $meta, -16 ); + + // Fetch identifier from start of metadata + $identifier = substr( $meta, 0, 6 ); + + if ( $identifier == '00iv00') { + + return true; + + } else { + + return false; + + } + + } + + /** + * @brief Check if a file is encrypted via legacy system + * @return true / false + */ + public static function isLegacyEncryptedContent( $content, $path ) { + + // Fetch all file metadata from DB + $metadata = \OC_FileCache_Cached::get( $content, '' ); + + // If a file is flagged with encryption in DB, but isn't a valid content + IV combination, it's probably using the legacy encryption system + if ( + $content + and isset( $metadata['encrypted'] ) + and $metadata['encrypted'] === true + and !self::isEncryptedContent( $content ) + ) { + + return true; + + } else { + + return false; + + } + + } + + /** + * @brief Symmetrically encrypt a string + * @returns encrypted file + */ + public static function encrypt( $plainContent, $iv, $passphrase = '' ) { + + if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { + + return $encryptedContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Symmetrically decrypt a string + * @returns decrypted file + */ + public static function decrypt( $encryptedContent, $iv, $passphrase ) { + + if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { + + return $plainContent; + + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Symmetrically encrypts a string and returns keyfile content + * @param $plainContent content to be encrypted in keyfile + * @returns encrypted content combined with IV + * @note IV need not be specified, as it will be stored in the returned keyfile + * and remain accessible therein. + */ + public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) { + + if ( !$plainContent ) { + + return false; + + } + + $iv = self::generateIv(); + + if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { + + // Combine content to encrypt with IV identifier and actual IV + $combinedKeyfile = $encryptedContent . '00iv00' . $iv; + + return $combinedKeyfile; + + } else { + + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + + /** + * @brief Symmetrically decrypts keyfile content + * @param string $source + * @param string $target + * @param string $key the decryption key + * + * This function decrypts a file + */ + public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) { + + if ( !$keyfileContent ) { + + return false; + + } + + // Fetch IV from end of file + $iv = substr( $keyfileContent, -16 ); + + // Remove IV and IV identifier text to expose encrypted content + $encryptedContent = substr( $keyfileContent, 0, -22 ); + + if ( $plainContent = self::decrypt( $encryptedContent, $iv, $passphrase ) ) { + + return $plainContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (symmetric) of keyfile content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Creates symmetric keyfile content using a generated key + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function symmetricEncryptFileContentKeyfile( $plainContent ) { + + $key = self::generateKey(); + + if( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) { + + return array( + 'key' => $key + , 'encrypted' => $encryptedContent + ); + + } else { + + return false; + + } + + } + + /** + * @brief Create asymmetrically encrypted keyfile content using a generated key + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { + + $envKeys = array(); + + if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) { + + return array( + 'keys' => $envKeys + , 'encrypted' => $sealed + ); + + } else { + + return false; + + } + + } + + /** + * @brief Asymmetrically encrypt a file using multiple public keys + * @param string $plainContent content to be encrypted + * @returns array keys: key, encrypted + * @note symmetricDecryptFileContent() can be used to decrypt files created using this method + * + * This function decrypts a file + */ + public static function multiKeyDecrypt( $encryptedContent, $envKey, $privateKey ) { + + if ( !$encryptedContent ) { + + return false; + + } + + if ( openssl_open( $encryptedContent, $plainContent, $envKey, $privateKey ) ) { + + return $plainContent; + + } else { + + \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed' , \OC_Log::ERROR ); + + return false; + + } + + } + + /** + * @brief Asymetrically encrypt a string using a public key + * @returns encrypted file + */ + public static function keyEncrypt( $plainContent, $publicKey ) { + + openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey ); + + return $encryptedContent; + + } + + /** + * @brief Asymetrically decrypt a file using a private key + * @returns decrypted file + */ + public static function keyDecrypt( $encryptedContent, $privatekey ) { + + openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); + + return $plainContent; + + } + + /** + * @brief Generate a pseudo random 1024kb ASCII key + * @returns $key Generated key + */ + public static function generateIv() { + + if ( $random = openssl_random_pseudo_bytes( 13, $strong ) ) { + + if ( !$strong ) { + + // If OpenSSL indicates randomness is insecure, log error + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); + + } + + $iv = substr( base64_encode( $random ), 0, -4 ); + + return $iv; + + } else { + + return false; + + } + + } + + /** + * @brief Generate a pseudo random 1024kb ASCII key + * @returns $key Generated key + */ + public static function generateKey() { + + // $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); + + // Generate key + if ( $key = base64_encode( openssl_random_pseudo_bytes( 768000, $strong ) ) ) { + + if ( !$strong ) { + + // If OpenSSL indicates randomness is insecure, log error + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()' , \OC_Log::WARN ); + + } + + return $key; + + } else { + + return false; + + } + + } + + public static function changekeypasscode($oldPassword, $newPassword) { + if(OCP\User::isLoggedIn()){ + $username=OCP\USER::getUser(); + $view=new OC_FilesystemView('/'.$username); + + // read old key + $key=$view->file_get_contents('/encryption.key'); + + // decrypt key with old passcode + $key=OC_Crypt::decrypt($key, $oldPassword); + + // encrypt again with new passcode + $key=OC_Crypt::encrypt($key, $newPassword); + + // store the new key + $view->file_put_contents('/encryption.key', $key ); + } + } + +} + ?> \ No newline at end of file diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 0c76bf27a5..7f67fc7e5e 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -27,7 +27,7 @@ namespace OCA_Encryption; */ class Keymanager { - # TODO: make all dependencies explicit, such as ocfsview objects, by adding them as method arguments (dependency injection) + # TODO: make all dependencies (including static classes) explicit, such as ocfsview objects, by adding them as method arguments (dependency injection) /** * @brief retrieve private key from a user @@ -128,27 +128,30 @@ class Keymanager { * @param string $key * @return bool true/false */ - public static function setFileKey( $userId, $path, $key ) { + public static function setFileKey( $user, $path, $key, $view, $dbClassName, $fileProxyClassName ) { - \OC_FileProxy::$enabled = false; + $fileProxyClassName::$enabled = false; $targetpath = ltrim( $path, '/' ); - $user = $userId; // update $keytarget and $user if key belongs to a file shared by someone else - $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); + $query = $dbClassName::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); - $result = $query->execute( array ( '/'.$userId.'/files/'.$targetpath, $userId ) ); + $result = $query->execute( array ( '/'.$user.'/files/'.$targetpath, $user ) ); if ( $row = $result->fetchRow( ) ) { - $targetpath = $row['source']; - $targetpath_parts=explode( '/',$targetpath ); - $user = $targetpath_parts[1]; - $targetpath = str_replace( '/'.$user.'/files/', '', $targetpath ); - //TODO: check for write permission on shared file once the new sharing API is in place - } - $view = new \OC_FilesystemView( '/' . $user . '/files_encryption/keyfiles' ); + $targetpath = $row['source']; + + $targetpath_parts=explode( '/',$targetpath ); + + $user = $targetpath_parts[1]; + + $targetpath = str_replace( '/'.$user.'/files/', '', $targetpath ); + + //TODO: check for write permission on shared file once the new sharing API is in place + + } $path_parts = pathinfo( $targetpath ); @@ -156,7 +159,7 @@ class Keymanager { $result = $view->file_put_contents( '/' . $targetpath . '.key', $key ); - \OC_FileProxy::$enabled = true; + $fileProxyClassName::$enabled = true; return $result; } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index c1956ad021..94f427f2f2 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -115,8 +115,11 @@ class Proxy extends \OC_FileProxy { $filePath = '/' . implode( '/', $filePath ); + # TODO: make keyfile dir dynamic from app config + $view = new \OC_FilesystemView( '/' . \OCP\USER::getUser() . '/files_encryption/keyfiles' ); + // Save keyfile for newly encrypted file in parallel directory tree - Keymanager::setFileKey( \OCP\USER::getUser(), $filePath, $encrypted['key'] ); + Keymanager::setFileKey( \OCP\USER::getUser(), $filePath, $encrypted['key'], $view, '\OC_DB', '\OC_FileProxy' ); // Update the file cache with file info \OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); From 6b058cd3594d80a27097b04507355b219f4726e4 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 2 Aug 2012 10:39:30 +0200 Subject: [PATCH 031/315] allow user to choose encryption mode --- apps/files_encryption/ajax/changemode.php | 17 +++++++++++++ apps/files_encryption/appinfo/app.php | 3 ++- apps/files_encryption/appinfo/database.xml | 24 ++++++++++++++++++ apps/files_encryption/appinfo/version | 2 +- apps/files_encryption/js/settings-personal.js | 22 ++++++++++++++++ apps/files_encryption/js/settings.js | 11 ++++---- apps/files_encryption/lib/crypt.php | 19 ++++++++------ apps/files_encryption/settings-personal.php | 25 +++++++++++++++++++ apps/files_encryption/settings.php | 1 - .../templates/settings-personal.php | 14 +++++++++++ apps/files_encryption/templates/settings.php | 3 ++- apps/files_sharing/appinfo/database.xml | 2 +- 12 files changed, 124 insertions(+), 19 deletions(-) create mode 100644 apps/files_encryption/ajax/changemode.php create mode 100644 apps/files_encryption/appinfo/database.xml create mode 100644 apps/files_encryption/js/settings-personal.js create mode 100644 apps/files_encryption/settings-personal.php create mode 100644 apps/files_encryption/templates/settings-personal.php diff --git a/apps/files_encryption/ajax/changemode.php b/apps/files_encryption/ajax/changemode.php new file mode 100644 index 0000000000..0e6678e4bb --- /dev/null +++ b/apps/files_encryption/ajax/changemode.php @@ -0,0 +1,17 @@ +execute(array(\OCP\User::getUser())); + +if ($row = $result->fetchRow()){ + $query = OC_DB::prepare( 'UPDATE *PREFIX*encryption SET mode = ? WHERE uid = ?' ); +} else { + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*encryption ( mode, uid ) VALUES( ?, ? )' ); +} +$query->execute(array($mode, \OCP\User::getUser())); \ No newline at end of file diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 2047bdbb1f..1c2fafa8da 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -28,4 +28,5 @@ and OCP\User::isLoggedIn() } -OCP\App::registerAdmin('files_encryption', 'settings'); \ No newline at end of file +OCP\App::registerAdmin('files_encryption', 'settings'); +OCP\App::registerPersonal('files_encryption','settings-personal'); \ No newline at end of file diff --git a/apps/files_encryption/appinfo/database.xml b/apps/files_encryption/appinfo/database.xml new file mode 100644 index 0000000000..d294c35d63 --- /dev/null +++ b/apps/files_encryption/appinfo/database.xml @@ -0,0 +1,24 @@ + + + *dbname* + true + false + utf8 + + *dbprefix*encryption + + + uid + text + true + 64 + + + mode + text + true + 64 + + +
+
\ No newline at end of file diff --git a/apps/files_encryption/appinfo/version b/apps/files_encryption/appinfo/version index 2f4536184b..7dff5b8921 100644 --- a/apps/files_encryption/appinfo/version +++ b/apps/files_encryption/appinfo/version @@ -1 +1 @@ -0.2 \ No newline at end of file +0.2.1 \ No newline at end of file diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js new file mode 100644 index 0000000000..76f9a37f69 --- /dev/null +++ b/apps/files_encryption/js/settings-personal.js @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2012, Bjoern Schiessle + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +$(document).ready(function(){ + console.log("loaded!"); + $('input[name=encryption_mode]').change(function(){ + console.log("HERE!!!!!!!!!!!"); + var client=$('input[value="client"]:checked').val() + ,server=$('input[value="server"]:checked').val() + ,user=$('input[value="user"]:checked').val() + ,none=$('input[value="none"]:checked').val() + if (client) + $.post(OC.filePath('files_encryption', 'ajax', 'changemode.php'), { mode: 'client' }); + else if (server) + $.post(OC.filePath('files_encryption', 'ajax', 'changemode.php'), { mode: 'server' }); + else + $.post(OC.filePath('files_encryption', 'ajax', 'changemode.php'), { mode: 'none' }); + }) +}) \ No newline at end of file diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js index 49dcf2bfca..d4dc470ced 100644 --- a/apps/files_encryption/js/settings.js +++ b/apps/files_encryption/js/settings.js @@ -17,19 +17,18 @@ $(document).ready(function(){ OC.AppConfig.setValue('files_encryption','type_blacklist',blackList); } - $('#enable_encryption').change(function(){ - var checked=$('#enable_encryption').is(':checked'); - OC.AppConfig.setValue('files_encryption','enable_encryption',(checked)?'true':'false'); - }) $('input[name=encryption_mode]').change(function(){ var client=$('input[value="client"]:checked').val() ,server=$('input[value="server"]:checked').val() + ,user=$('input[value="user"]:checked').val() ,none=$('input[value="none"]:checked').val() if (client) OC.AppConfig.setValue('files_encryption','mode','client'); - if (server) + else if (server) OC.AppConfig.setValue('files_encryption','mode','server'); - if (none) + else if (user) + OC.AppConfig.setValue('files_encryption','mode','user'); + else OC.AppConfig.setValue('files_encryption','mode','none'); }) }) \ No newline at end of file diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 7e50c900fa..90b24dc8dd 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -37,14 +37,17 @@ class Crypt { */ public static function mode( $user = null ) { - $mode = \OC_Appconfig::getValue( 'files_encryption', 'mode', 'unknown' ); - - if ( $mode == 'unknown' ) { - - error_log('no encryption mode configured'); - - return false; - + $mode = \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' ); + + if ( $mode == 'user') { + $mode = 'none'; + if ( $user ) { + $query = \OC_DB::prepare( "SELECT mode FROM *PREFIX*encryption WHERE uid = ?" ); + $result = $query->execute(array($user)); + if ($row = $result->fetchRow()){ + $mode = $row['mode']; + } + } } return $mode; diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php new file mode 100644 index 0000000000..d4071e75ff --- /dev/null +++ b/apps/files_encryption/settings-personal.php @@ -0,0 +1,25 @@ +execute(array(\OCP\User::getUser())); + + if ($row = $result->fetchRow()){ + $mode = $row['mode']; + } else { + $mode = 'none'; + } + + OCP\Util::addscript('files_encryption','settings-personal'); + $tmpl->assign('encryption_mode', $mode); + return $tmpl->fetchPage(); +} + +return null; + +?> \ No newline at end of file diff --git a/apps/files_encryption/settings.php b/apps/files_encryption/settings.php index a4e91627dd..963fdf826c 100644 --- a/apps/files_encryption/settings.php +++ b/apps/files_encryption/settings.php @@ -8,7 +8,6 @@ $tmpl = new OCP\Template( 'files_encryption', 'settings'); $blackList=explode(',',OCP\Config::getAppValue('files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg')); -$enabled=(OCP\Config::getAppValue('files_encryption','enable_encryption','true')=='true'); $tmpl->assign('blacklist',$blackList); $tmpl->assign('encryption_mode',\OC_Appconfig::getValue('files_encryption', 'mode', 'none')); diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php new file mode 100644 index 0000000000..2b51ab8694 --- /dev/null +++ b/apps/files_encryption/templates/settings-personal.php @@ -0,0 +1,14 @@ + +

+
+ +Choose encryption mode: + +

+ /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
+ /> Server side encryption (allows you to access your files from the web interface and the desktop client)
+ /> None (no encryption at all)
+

+
+
+ diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php index 38c89ecde3..2a3c1fd5bd 100644 --- a/apps/files_encryption/templates/settings.php +++ b/apps/files_encryption/templates/settings.php @@ -1,4 +1,4 @@ -
+
Choose encryption mode: @@ -6,6 +6,7 @@

/> Client side encryption (most secure but makes it impossible to access your data from the web interface)
/> Server side encryption (allows you to access your files from the web interface and the desktop client)
+ /> User specific (let the user decide)
/> None (no encryption at all)

diff --git a/apps/files_sharing/appinfo/database.xml b/apps/files_sharing/appinfo/database.xml index c5cb632d4f..bb6275fbac 100644 --- a/apps/files_sharing/appinfo/database.xml +++ b/apps/files_sharing/appinfo/database.xml @@ -39,4 +39,4 @@ - + \ No newline at end of file From 5996ea735a5a6f72c586c32c8b15ada07e35c5b2 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 2 Aug 2012 10:59:06 +0200 Subject: [PATCH 032/315] remove debug output --- apps/files_encryption/js/settings-personal.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index 76f9a37f69..7ca2ce5697 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -5,9 +5,7 @@ */ $(document).ready(function(){ - console.log("loaded!"); $('input[name=encryption_mode]').change(function(){ - console.log("HERE!!!!!!!!!!!"); var client=$('input[value="client"]:checked').val() ,server=$('input[value="server"]:checked').val() ,user=$('input[value="user"]:checked').val() From 19b31096552c9f602449b010754ea97e48d94c42 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 2 Aug 2012 13:55:23 +0200 Subject: [PATCH 033/315] code cleanup --- apps/files_encryption/ajax/changemode.php | 7 ++++++- apps/files_encryption/settings-personal.php | 8 ++++++-- apps/files_encryption/templates/settings-personal.php | 1 - 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/files_encryption/ajax/changemode.php b/apps/files_encryption/ajax/changemode.php index 0e6678e4bb..64e7dbef68 100644 --- a/apps/files_encryption/ajax/changemode.php +++ b/apps/files_encryption/ajax/changemode.php @@ -1,4 +1,9 @@ + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ OCP\JSON::checkAppEnabled('files_encryption'); OCP\JSON::checkLoggedIn(); @@ -9,7 +14,7 @@ $mode = $_POST['mode']; $query = \OC_DB::prepare( "SELECT mode FROM *PREFIX*encryption WHERE uid = ?" ); $result = $query->execute(array(\OCP\User::getUser())); -if ($row = $result->fetchRow()){ +if ($result->fetchRow()){ $query = OC_DB::prepare( 'UPDATE *PREFIX*encryption SET mode = ? WHERE uid = ?' ); } else { $query = OC_DB::prepare( 'INSERT INTO *PREFIX*encryption ( mode, uid ) VALUES( ?, ? )' ); diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index d4071e75ff..014288f2ef 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -1,4 +1,10 @@ + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ $sysEncMode = \OC_Appconfig::getValue('files_encryption', 'mode', 'none'); @@ -21,5 +27,3 @@ if ($sysEncMode == 'user') { } return null; - -?> \ No newline at end of file diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 2b51ab8694..4546aecacf 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -1,4 +1,3 @@ -

From d5808f07ca729c99482a44aa3e320ad5060cb86a Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 3 Aug 2012 11:49:55 +0200 Subject: [PATCH 034/315] return a list of all public keys for a given file --- apps/files_encryption/lib/crypt.php | 9 +++-- apps/files_encryption/lib/keymanager.php | 44 +++++++++++++++++++++--- lib/ocs.php | 37 +++++++++----------- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 90b24dc8dd..64bbc17ec1 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -38,8 +38,11 @@ class Crypt { public static function mode( $user = null ) { $mode = \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' ); - - if ( $mode == 'user') { + + if ( $mode == 'user') { + if ( !$user ) { + $user = \OCP\User::getUser(); + } $mode = 'none'; if ( $user ) { $query = \OC_DB::prepare( "SELECT mode FROM *PREFIX*encryption WHERE uid = ?" ); @@ -49,7 +52,7 @@ class Crypt { } } } - + return $mode; } diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 7f67fc7e5e..6e3dcaf0ad 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -43,14 +43,48 @@ class Keymanager { } /** - * @brief retrieve public key from a user + * @brief retrieve a list of the public key from all users with access to the file * - * @param string user name - * @return string private key or false + * @param string path to file + * @return array of public keys for the given file */ - public static function getPublicKey($user) { + public static function getPublicKeys($path) { + $userId = \OCP\User::getUser(); + $path = ltrim( $path, '/' ); + $filepath = '/'.$userId.'/files/'.$path; + + // check if file was shared with other users + $query = \OC_DB::prepare( "SELECT uid_owner, source, target, uid_shared_with FROM `*PREFIX*sharing` WHERE ( target = ? AND uid_shared_with = ? ) OR source = ? " ); + $result = $query->execute( array ($filepath, $userId, $filepath)); + $users = array(); + if ($row = $result->fetchRow()){ + $source = $row['source']; + $owner = $row['uid_owner']; + $users[] = $owner; + // get the uids of all user with access to the file + $query = \OC_DB::prepare( "SELECT source, uid_shared_with FROM `*PREFIX*sharing` WHERE source = ?" ); + $result = $query->execute( array ($source)); + while ( ($row = $result->fetchRow()) ) { + $users[] = $row['uid_shared_with']; + } + } else { + // check if it is a file owned by the user and not shared at all + $userview = new \OC_FilesystemView( '/'.$userId.'/files/' ); + if ($userview->file_exists($path)) { + $users[] = $userId; + } + } + $view = new \OC_FilesystemView( '/public-keys/' ); - return $view->file_get_contents($user.'.public.key'); + + $keylist = array(); + $count = 0; + foreach ($users as $user) { + $keylist['key'.++$count] = $view->file_get_contents($user.'.public.key'); + } + + return $keylist; + } /** diff --git a/lib/ocs.php b/lib/ocs.php index 17ae649deb..6617beb806 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -169,9 +169,9 @@ class OC_OCS { OC_OCS::quotaset($format,$user,$quota); // keygetpublic - }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){ - $user=$ex[$paracount-3]; - OC_OCS::publicKeyGet($format,$user); + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'file') and ($ex[$paracount-2] == 'publickeys')){ + $file=urldecode($ex[$paracount-3]); + OC_OCS::publicKeyGet($format,$file); //keysetpublic }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){ @@ -671,27 +671,22 @@ class OC_OCS { /** * get the public key of a user * @param string $format - * @param string $user - * @return string xml/json + * @param string $file + * @return string xml/json list of public keys */ - private static function publicKeyGet($format, $user) { + private static function publicKeyGet($format, $file) { $login=OC_OCS::checkpassword(); - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { - if(OC_User::userExists($user)){ - if (($key = OCA_Encryption\Keymanager::getPublicKey($user))) { - $xml=array(); - $xml['key'] = $key; - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); - echo($txt); - } - else { - echo self::generateXml('', 'fail', 404, 'public key does not exist'); - } - } else { - echo self::generateXml('', 'fail', 300, 'User does not exist'); + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') { + if (($keys = OCA_Encryption\Keymanager::getPublicKeys($file))) { + $xml=$keys; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + } + else { + echo self::generateXml('', 'fail', 404, 'public key does not exist'); } } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled'); } } @@ -782,7 +777,7 @@ class OC_OCS { if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { if (($key = OCA_Encryption\Keymanager::getFileKey($user, $file))) { $xml=array(); - $xml['key']=$key; + $xml['key']=$key; $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); echo($txt); } else { From bed05f030280087ae73f78acd38c1b797f9776c0 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 3 Aug 2012 11:59:32 +0200 Subject: [PATCH 035/315] only force re-login if server-side encryption is enabled --- apps/files_encryption/appinfo/app.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 1c2fafa8da..4fd9c37ed3 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -14,10 +14,7 @@ OCP\Util::connectHook('OC_Webdav_Properties', 'update', 'OCA_Encryption\Hooks', stream_wrapper_register('crypt','OC_CryptStream'); -if( -!isset( $_SESSION['enckey'] ) -and OCP\User::isLoggedIn() -) { +if( !isset( $_SESSION['enckey'] ) && OCP\User::isLoggedIn() && OCA_Encryption\Crypt::mode() == 'server' ) { // Force the user to re-log in if the encryption key isn't unlocked (happens when a user is logged in before the encryption app is enabled) OCP\User::logout(); From a0b2474019e33fa7737ce6d24e76be34dba52a2d Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 3 Aug 2012 12:21:49 +0200 Subject: [PATCH 036/315] code cleanup and TODOs added --- apps/files_encryption/ajax/{changemode.php => mode.php} | 2 ++ apps/files_encryption/js/settings-personal.js | 7 ++++--- apps/files_encryption/js/settings.js | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) rename apps/files_encryption/ajax/{changemode.php => mode.php} (84%) diff --git a/apps/files_encryption/ajax/changemode.php b/apps/files_encryption/ajax/mode.php similarity index 84% rename from apps/files_encryption/ajax/changemode.php rename to apps/files_encryption/ajax/mode.php index 64e7dbef68..0515cdccb0 100644 --- a/apps/files_encryption/ajax/changemode.php +++ b/apps/files_encryption/ajax/mode.php @@ -4,6 +4,8 @@ * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. */ + +//TODO: Handle switch between client and server side encryption OCP\JSON::checkAppEnabled('files_encryption'); OCP\JSON::checkLoggedIn(); diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index 7ca2ce5697..6d3c9f9a48 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -11,10 +11,11 @@ $(document).ready(function(){ ,user=$('input[value="user"]:checked').val() ,none=$('input[value="none"]:checked').val() if (client) - $.post(OC.filePath('files_encryption', 'ajax', 'changemode.php'), { mode: 'client' }); + var encmode= 'client'; else if (server) - $.post(OC.filePath('files_encryption', 'ajax', 'changemode.php'), { mode: 'server' }); + var encmode = 'server'; else - $.post(OC.filePath('files_encryption', 'ajax', 'changemode.php'), { mode: 'none' }); + var encmode = 'none'; + $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: encmode }); }) }) \ No newline at end of file diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js index d4dc470ced..19ff27a3b2 100644 --- a/apps/files_encryption/js/settings.js +++ b/apps/files_encryption/js/settings.js @@ -17,6 +17,7 @@ $(document).ready(function(){ OC.AppConfig.setValue('files_encryption','type_blacklist',blackList); } + //TODO: Handle switch between client and server side encryption $('input[name=encryption_mode]').change(function(){ var client=$('input[value="client"]:checked').val() ,server=$('input[value="server"]:checked').val() From 773d7b119d20d5962817cdd057bf68c8cb39d529 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 3 Aug 2012 13:52:41 +0200 Subject: [PATCH 037/315] OCS api calls cleanup --- apps/files_encryption/lib/keymanager.php | 28 ++-- lib/ocs.php | 172 +++++++++-------------- 2 files changed, 83 insertions(+), 117 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 6e3dcaf0ad..825a3f78fc 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -32,11 +32,11 @@ class Keymanager { /** * @brief retrieve private key from a user * - * @param string user name * @return string private key or false */ - public static function getPrivateKey( $user ) { + public static function getPrivateKey() { + $user = \OCP\User::getUser(); $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' ); return $view->file_get_contents( '/' . $user.'.private.key' ); @@ -91,17 +91,16 @@ class Keymanager { * @brief retrieve file encryption key * * @param string file name - * @param string user name of the file owner * @return string file key or false */ - public static function getFileKey( $userId, $path ) { + public static function getFileKey( $path ) { $keypath = ltrim( $path, '/' ); - $user = $userId; + $user = \OCP\User::getUser(); // update $keypath and $user if path point to a file shared by someone else $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); - $result = $query->execute( array ('/'.$userId.'/files/'.$keypath, $userId)); + $result = $query->execute( array ('/'.$user.'/files/'.$keypath, $user)); if ($row = $result->fetchRow()){ $keypath = $row['source']; $keypath_parts=explode('/',$keypath); @@ -114,16 +113,16 @@ class Keymanager { } /** - * @brief store private key from a user + * @brief store private key from the user * - * @param string user name * @param string key * @return bool true/false */ - public static function setPrivateKey($user, $key) { + public static function setPrivateKey($key) { \OC_FileProxy::$enabled = false; + $user = \OCP\User::getUser(); $view = new \OC_FilesystemView('/'.$user.'/files_encryption'); if (!$view->file_exists('')) $view->mkdir(''); $result = $view->file_put_contents($user.'.private.key', $key); @@ -135,19 +134,18 @@ class Keymanager { /** - * @brief store public key from a user + * @brief store public key of the user * - * @param string user name * @param string key * @return bool true/false */ - public static function setPublicKey($user, $key) { + public static function setPublicKey($key) { \OC_FileProxy::$enabled = false; $view = new \OC_FilesystemView('/public-keys'); if (!$view->file_exists('')) $view->mkdir(''); - $result = $view->file_put_contents($user.'.public.key', $key); + $result = $view->file_put_contents(\OCP\User::getUser().'.public.key', $key); \OC_FileProxy::$enabled = true; @@ -157,16 +155,16 @@ class Keymanager { /** * @brief store file encryption key * - * @param string $userId name of the file owner * @param string $path relative path of the file, including filename * @param string $key * @return bool true/false */ - public static function setFileKey( $user, $path, $key, $view, $dbClassName, $fileProxyClassName ) { + public static function setFileKey( $path, $key, $view, $dbClassName, $fileProxyClassName ) { $fileProxyClassName::$enabled = false; $targetpath = ltrim( $path, '/' ); + $user = \OCP\User::getUser(); // update $keytarget and $user if key belongs to a file shared by someone else $query = $dbClassName::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); diff --git a/lib/ocs.php b/lib/ocs.php index 6617beb806..97314d71ce 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -174,34 +174,29 @@ class OC_OCS { OC_OCS::publicKeyGet($format,$file); //keysetpublic - }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){ - $user=$ex[$paracount-3]; + }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='cloud') and ($ex[$paracount-2] == 'publickey')){ $key = self::readData('post', 'key', 'string'); - OC_OCS::publicKeySet($format,$user, $key); + OC_OCS::publicKeySet($format, $key); // keygetprivate - }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ - $user=$ex[$paracount-3]; - OC_OCS::privateKeyGet($format,$user); + }elseif(($method=='get') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='cloud') and ($ex[$paracount-2] == 'privatekey')){ + OC_OCS::privateKeyGet($format); //keysetprivate - }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ - $user=$ex[$paracount-3]; + }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='cloud') and ($ex[$paracount-2] == 'privatekey')){ $key = self::readData('post', 'key', 'string'); - OC_OCS::privateKeySet($format,$user, $key); - + OC_OCS::privateKeySet($format, $key); + // keygetfiles - }elseif(($method=='get') and ($ex[$paracount-7] == 'v1.php') and ($ex[$paracount-6]=='cloud') and ($ex[$paracount-5] == 'user') and ($ex[$paracount-3] == 'filekey')){ - $user=$ex[$paracount-4]; - $file = urldecode($ex[$paracount-2]); - OC_OCS::fileKeyGet($format,$user, $file); + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'file') and ($ex[$paracount-2] == 'filekey')){ + $file = urldecode($ex[$paracount-3]); + OC_OCS::fileKeyGet($format, $file); //keysetfiles - }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'filekey')){ - $user=$ex[$paracount-3]; + }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='cloud') and ($ex[$paracount-2] == 'filekey')){ $key = self::readData('post', 'key', 'string'); $file = self::readData('post', 'file', 'string'); - OC_OCS::fileKeySet($format,$user, $file, $key); + OC_OCS::fileKeySet($format, $file, $key); // add more calls here // please document all the call in the draft spec @@ -669,7 +664,7 @@ class OC_OCS { } /** - * get the public key of a user + * get the public key from all users associated with a given file * @param string $format * @param string $file * @return string xml/json list of public keys @@ -692,130 +687,103 @@ class OC_OCS { /** * set the public key of a user - * @param string $format - * @param string $user + * @param string $format * @param string $key * @return string xml/json */ - private static function publicKeySet($format, $user, $key) { + private static function publicKeySet($format, $key) { $login=OC_OCS::checkpassword(); - if(($login==$user)) { - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { - if (($key = OCA_Encryption\Keymanager::setPublicKey($user, $key))) { - echo self::generateXml('', 'ok', 100, ''); - } else { - echo self::generateXml('', 'fail', 404, 'could not add your public key to the key storage'); - } + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (OCA_Encryption\Keymanager::setPublicKey($key)) { + echo self::generateXml('', 'ok', 100, ''); } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + echo self::generateXml('', 'fail', 404, 'could not add your public key to the key storage'); } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); } } /** * get the private key of a user * @param string $format - * @param string $user * @return string xml/json */ - private static function privateKeyGet($format, $user) { - $login=OC_OCS::checkpassword(); - if(($login==$user)) { - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { - if (($key = OCA_Encryption\Keymanager::getPrivateKey($user))) { - $xml=array(); - $xml['key']=$key; - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); - echo($txt); - } else { - echo self::generateXml('', 'fail', 404, 'private key does not exist'); - } - } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + private static function privateKeyGet($format) { + $login=OC_OCS::checkpassword(); + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::getPrivateKey())) { + $xml=array(); + $xml['key']=$key; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + } else { + echo self::generateXml('', 'fail', 404, 'private key does not exist'); } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); } } /** * set the private key of a user - * @param string $format - * @param string $user + * @param string $format * @param string $key * @return string xml/json */ - private static function privateKeySet($format, $user, $key) { + private static function privateKeySet($format, $key) { $login=OC_OCS::checkpassword(); - if(($login==$user)) { - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { - if (($key = OCA_Encryption\Keymanager::setPrivateKey($user, $key))) { - echo self::generateXml('', 'ok', 100, ''); - } else { - echo self::generateXml('', 'fail', 404, 'could not add your private key to the key storage'); - } + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::setPrivateKey($key))) { + echo self::generateXml('', 'ok', 100, ''); } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + echo self::generateXml('', 'fail', 404, 'could not add your private key to the key storage'); } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); } } /** * get the encryption key of a file - * @param string $format - * @param string $user + * @param string $format * @param string $file * @return string xml/json */ - private static function fileKeyGet($format, $user, $file) { - $login=OC_OCS::checkpassword(); - if(($login==$user)) { - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { - if (($key = OCA_Encryption\Keymanager::getFileKey($user, $file))) { - $xml=array(); - $xml['key']=$key; - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); - echo($txt); - } else { - echo self::generateXml('', 'fail', 404, 'file key does not exist'); - } - } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); - } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - } + private static function fileKeyGet($format, $file) { + $login=OC_OCS::checkpassword(); + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::getFileKey($file))) { + $xml=array(); + $xml['key']=$key; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + } else { + echo self::generateXml('', 'fail', 404, 'file key does not exist'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + } + } /** * set the encryption keyn of a file - * @param string $format - * @param string $user + * @param string $format * @param string $file * @param string $key * @return string xml/json */ - private static function fileKeySet($format, $user, $file, $key) { - $login=OC_OCS::checkpassword(); - if(($login==$user)) { - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { - if (($key = OCA_Encryption\Keymanager::setFileKey($user, $file, $key))) { - echo self::generateXml('', 'ok', 100, ''); - return true; - } else { - echo self::generateXml('', 'fail', 404, 'could not write key file'); - } - } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); - } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - return false; - } + private static function fileKeySet($format, $file, $key) { + $login=OC_OCS::checkpassword(); + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if (($key = OCA_Encryption\Keymanager::setFileKey($file, $key))) { + echo self::generateXml('', 'ok', 100, ''); + } else { + echo self::generateXml('', 'fail', 404, 'could not write key file'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + } + } } From 5bb3ea97407a251a26272383bfbb073ba2fc3965 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 8 Aug 2012 12:13:14 +0200 Subject: [PATCH 038/315] define default properties in keymanager.php --- apps/files_encryption/lib/keymanager.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 825a3f78fc..ef1080e9d0 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -27,8 +27,16 @@ namespace OCA_Encryption; */ class Keymanager { + private static $defaultProperties = array('dbClassName' => \OC_DB, + 'fileProxyClassName' => \OC_FileProxy, + ); + # TODO: make all dependencies (including static classes) explicit, such as ocfsview objects, by adding them as method arguments (dependency injection) + private static function mergeProperties($properties) { + array_merge(self::$defaultProperties, $properties); + } + /** * @brief retrieve private key from a user * From d4974b6d4a9ce06dadbe419b193579eaa83393c4 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 8 Aug 2012 14:15:35 +0200 Subject: [PATCH 039/315] set default dependencies in keymanager.php fix calls in ocs.php --- apps/files_encryption/lib/keymanager.php | 11 +++++------ lib/ocs.php | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index ef1080e9d0..00817946fd 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -27,10 +27,6 @@ namespace OCA_Encryption; */ class Keymanager { - private static $defaultProperties = array('dbClassName' => \OC_DB, - 'fileProxyClassName' => \OC_FileProxy, - ); - # TODO: make all dependencies (including static classes) explicit, such as ocfsview objects, by adding them as method arguments (dependency injection) private static function mergeProperties($properties) { @@ -167,8 +163,7 @@ class Keymanager { * @param string $key * @return bool true/false */ - public static function setFileKey( $path, $key, $view, $dbClassName, $fileProxyClassName ) { - + public static function setFileKey( $path, $key, $view = Null, $dbClassName = '\OC_DB', $fileProxyClassName = '\OC_FileProxy') { $fileProxyClassName::$enabled = false; $targetpath = ltrim( $path, '/' ); @@ -194,6 +189,10 @@ class Keymanager { } $path_parts = pathinfo( $targetpath ); + + if (!$view) { + $view = new \OC_FilesystemView( '/' . $user . '/files_encryption/keyfiles' ); + } if ( !$view->file_exists( $path_parts['dirname'] ) ) $view->mkdir( $path_parts['dirname'] ); diff --git a/lib/ocs.php b/lib/ocs.php index 97314d71ce..0fc208516e 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -693,14 +693,14 @@ class OC_OCS { */ private static function publicKeySet($format, $key) { $login=OC_OCS::checkpassword(); - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') { if (OCA_Encryption\Keymanager::setPublicKey($key)) { echo self::generateXml('', 'ok', 100, ''); } else { echo self::generateXml('', 'fail', 404, 'could not add your public key to the key storage'); } } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled'); } } @@ -711,7 +711,7 @@ class OC_OCS { */ private static function privateKeyGet($format) { $login=OC_OCS::checkpassword(); - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') { if (($key = OCA_Encryption\Keymanager::getPrivateKey())) { $xml=array(); $xml['key']=$key; @@ -721,7 +721,7 @@ class OC_OCS { echo self::generateXml('', 'fail', 404, 'private key does not exist'); } } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled'); } } @@ -733,14 +733,14 @@ class OC_OCS { */ private static function privateKeySet($format, $key) { $login=OC_OCS::checkpassword(); - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') { if (($key = OCA_Encryption\Keymanager::setPrivateKey($key))) { echo self::generateXml('', 'ok', 100, ''); } else { echo self::generateXml('', 'fail', 404, 'could not add your private key to the key storage'); } } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled'); } } @@ -752,7 +752,7 @@ class OC_OCS { */ private static function fileKeyGet($format, $file) { $login=OC_OCS::checkpassword(); - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') { if (($key = OCA_Encryption\Keymanager::getFileKey($file))) { $xml=array(); $xml['key']=$key; @@ -762,7 +762,7 @@ class OC_OCS { echo self::generateXml('', 'fail', 404, 'file key does not exist'); } } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled'); } } @@ -775,14 +775,14 @@ class OC_OCS { */ private static function fileKeySet($format, $file, $key) { $login=OC_OCS::checkpassword(); - if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode($user) === 'client') { + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') { if (($key = OCA_Encryption\Keymanager::setFileKey($file, $key))) { echo self::generateXml('', 'ok', 100, ''); } else { echo self::generateXml('', 'fail', 404, 'could not write key file'); } } else { - echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled for user ' . $user); + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled'); } } From dc596a72c385a5bd1159ec1c19b8cb05f36a4a30 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 8 Aug 2012 14:20:29 +0200 Subject: [PATCH 040/315] remove function which is no longer needed --- apps/files_encryption/lib/keymanager.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 00817946fd..0bf9be26ae 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -28,11 +28,7 @@ namespace OCA_Encryption; class Keymanager { # TODO: make all dependencies (including static classes) explicit, such as ocfsview objects, by adding them as method arguments (dependency injection) - - private static function mergeProperties($properties) { - array_merge(self::$defaultProperties, $properties); - } - + /** * @brief retrieve private key from a user * From 5983643abdf0d451f46eed97ab34b486179c6d4a Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 8 Aug 2012 15:32:05 +0200 Subject: [PATCH 041/315] fix setFileKey() call in updateKeyfile hook --- apps/files_encryption/hooks/hooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index d06e9a0d2d..b7e8df9eac 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -65,7 +65,7 @@ class Hooks { public static function updateKeyfile( $params ) { if (Crypt::mode(\OCP\User::getUser()) == 'client') if (isset($params['properties']['key'])) { - Keymanager::setFileKey(\OCP\User::getUser(), $params['path'], $params['properties']['key']); + Keymanager::setFileKey($params['path'], $params['properties']['key']); } else { error_log("Client side encryption is enabled but the client doesn't provide a encryption key for the file!"); } From a7cbc9e71398d5e08684ffdfd1f07e7d8defbf31 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 8 Aug 2012 18:27:12 +0200 Subject: [PATCH 042/315] lock system wide encryption settings once the admin took a decision --- apps/files_encryption/templates/settings.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php index 2a3c1fd5bd..4133f4573d 100644 --- a/apps/files_encryption/templates/settings.php +++ b/apps/files_encryption/templates/settings.php @@ -4,10 +4,10 @@ Choose encryption mode:

- /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
- /> Server side encryption (allows you to access your files from the web interface and the desktop client)
- /> User specific (let the user decide)
- /> None (no encryption at all)
+ /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
+ /> Server side encryption (allows you to access your files from the web interface and the desktop client)
+ /> User specific (let the user decide)
+ /> None (no encryption at all)

t('Encryption'); ?> From 5a261b5b8ffd01c34ce009a431a5587c548fa9a7 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 9 Aug 2012 12:19:51 +0200 Subject: [PATCH 043/315] ask user for passwords when switching from client to server side encryption --- apps/files_encryption/ajax/mode.php | 17 +++++++++- apps/files_encryption/js/settings-personal.js | 31 ++++++++++++++----- apps/files_encryption/lib/keymanager.php | 6 ++++ .../templates/settings-personal.php | 8 ++--- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/apps/files_encryption/ajax/mode.php b/apps/files_encryption/ajax/mode.php index 0515cdccb0..c81d494795 100644 --- a/apps/files_encryption/ajax/mode.php +++ b/apps/files_encryption/ajax/mode.php @@ -7,11 +7,22 @@ //TODO: Handle switch between client and server side encryption +use OCA_Encryption\Keymanager; + OCP\JSON::checkAppEnabled('files_encryption'); OCP\JSON::checkLoggedIn(); OCP\JSON::callCheck(); $mode = $_POST['mode']; +$changePasswd = false; +$passwdChanged = false; + +if ( isset($_POST['newpasswd']) && isset($_POST['oldpasswd']) ) { + $oldpasswd = $_POST['oldpasswd']; + $newpasswd = $_POST['newpasswd']; + $changePasswd = true; + $passwdChanged = Keymanager::changePasswd($oldpasswd, $newpasswd); +} $query = \OC_DB::prepare( "SELECT mode FROM *PREFIX*encryption WHERE uid = ?" ); $result = $query->execute(array(\OCP\User::getUser())); @@ -21,4 +32,8 @@ if ($result->fetchRow()){ } else { $query = OC_DB::prepare( 'INSERT INTO *PREFIX*encryption ( mode, uid ) VALUES( ?, ? )' ); } -$query->execute(array($mode, \OCP\User::getUser())); \ No newline at end of file +if ( (!$changePasswd || $passwdChanged) && $query->execute(array($mode, \OCP\User::getUser())) ) { + OCP\JSON::success(); +} else { + OCP\JSON::error(); +} \ No newline at end of file diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index 6d3c9f9a48..fad077a8dd 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -6,16 +6,33 @@ $(document).ready(function(){ $('input[name=encryption_mode]').change(function(){ + var prevmode = document.getElementById('prev_encryption_mode').value var client=$('input[value="client"]:checked').val() ,server=$('input[value="server"]:checked').val() ,user=$('input[value="user"]:checked').val() ,none=$('input[value="none"]:checked').val() - if (client) - var encmode= 'client'; - else if (server) - var encmode = 'server'; - else - var encmode = 'none'; - $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: encmode }); + if (client) { + $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'client' }); + if (prevmode == 'server') { + OC.dialogs.info(t('encryption', 'Please go to your owncloud client and change your encryption password to complete the conversion'), t('encryption', 'switched to client side encryption')); + } + } else if (server) { + if (prevmode == 'client') { + OC.dialogs.form([{text:'login password', name:'newpasswd', type:'password'},{text:'Encryption password used on the client', name:'oldpasswd', type:'password'}],t('encryption', 'Please enter your passwords'), function(data) { + $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'server', newpasswd: data[0].value, oldpasswd: data[1].value }, function(result) { + if (result.status != 'success') { + console.log("change selection back to " + prevmode+'_encryption'); + document.getElementById(prevmode+'_encryption').checked = true; + } else { + } + + }); + }); + } else { + $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'server' }); + } + } else { + $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'none' }); + } }) }) \ No newline at end of file diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 0bf9be26ae..e546ba825e 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -199,4 +199,10 @@ class Keymanager { return $result; } + public static function changePasswd($oldpasswd, $newpasswd) { + //TODO change password of private key + error_log("password changed from '$oldpasswd' to '$newpasswd'"); + return true; + } + } \ No newline at end of file diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 4546aecacf..de05fa5a4b 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -4,10 +4,10 @@ Choose encryption mode:

- /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
- /> Server side encryption (allows you to access your files from the web interface and the desktop client)
- /> None (no encryption at all)
+ + /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
+ /> Server side encryption (allows you to access your files from the web interface and the desktop client)
+ /> None (no encryption at all)

- From 800942ece74ac336c4a9213228f14406d7e494f7 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 9 Aug 2012 13:47:27 +0200 Subject: [PATCH 044/315] change key password when user switches from client to server side encryption. make use of the keymanager class in changekeypasscode() --- apps/files_encryption/ajax/mode.php | 1 + apps/files_encryption/js/settings-personal.js | 6 ++--- apps/files_encryption/lib/crypt.php | 22 ++++++++++--------- apps/files_encryption/lib/keymanager.php | 9 +++++--- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/apps/files_encryption/ajax/mode.php b/apps/files_encryption/ajax/mode.php index c81d494795..f1a026ca43 100644 --- a/apps/files_encryption/ajax/mode.php +++ b/apps/files_encryption/ajax/mode.php @@ -32,6 +32,7 @@ if ($result->fetchRow()){ } else { $query = OC_DB::prepare( 'INSERT INTO *PREFIX*encryption ( mode, uid ) VALUES( ?, ? )' ); } + if ( (!$changePasswd || $passwdChanged) && $query->execute(array($mode, \OCP\User::getUser())) ) { OCP\JSON::success(); } else { diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index fad077a8dd..f335cf7f88 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -18,14 +18,12 @@ $(document).ready(function(){ } } else if (server) { if (prevmode == 'client') { - OC.dialogs.form([{text:'login password', name:'newpasswd', type:'password'},{text:'Encryption password used on the client', name:'oldpasswd', type:'password'}],t('encryption', 'Please enter your passwords'), function(data) { + OC.dialogs.form([{text:'login password', name:'newpasswd', type:'password'},{text:'Encryption password used on the client', name:'oldpasswd', type:'password'}],t('encryption', 'Change encryption password to login password'), function(data) { $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'server', newpasswd: data[0].value, oldpasswd: data[1].value }, function(result) { if (result.status != 'success') { - console.log("change selection back to " + prevmode+'_encryption'); document.getElementById(prevmode+'_encryption').checked = true; - } else { + OC.dialogs.alert(t('encryption', 'Please check your passwords and try again'), t('encryption', 'Could not change encryption password to login password')) } - }); }); } else { diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 64bbc17ec1..1fa7013776 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -412,21 +412,23 @@ class Crypt { } public static function changekeypasscode($oldPassword, $newPassword) { - if(OCP\User::isLoggedIn()){ - $username=OCP\USER::getUser(); - $view=new OC_FilesystemView('/'.$username); + if(\OCP\User::isLoggedIn()){ + $username = \OCP\USER::getUser(); + $view = new \OC_FilesystemView('/'.$username); // read old key - $key=$view->file_get_contents('/encryption.key'); + $key = Keymanager::getPrivateKey(); // decrypt key with old passcode - $key=OC_Crypt::decrypt($key, $oldPassword); + if ( ($key = self::decrypt($key, $oldPassword)) ) { + // encrypt again with new passcode + $key = self::encrypt($key, $newPassword); - // encrypt again with new passcode - $key=OC_Crypt::encrypt($key, $newPassword); - - // store the new key - $view->file_put_contents('/encryption.key', $key ); + // store the new key + return Keymanager::setPrivateKey($key); + } else { + return false; + } } } diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index e546ba825e..4c30c16395 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -200,9 +200,12 @@ class Keymanager { } public static function changePasswd($oldpasswd, $newpasswd) { - //TODO change password of private key - error_log("password changed from '$oldpasswd' to '$newpasswd'"); - return true; + if ( \OCP\User::checkPassword(\OCP\User::getUser(), $newpasswd) ) { + return Crypt::changekeypasscode($oldpasswd, $newpasswd); + } else { + return false; + } + } } \ No newline at end of file From a969c23e59e26f2d82a1f8626444a59ae003c30e Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 9 Aug 2012 14:25:09 +0200 Subject: [PATCH 045/315] disable admin choice of encryption mode once a decision was taken --- apps/files_encryption/js/settings-personal.js | 2 +- apps/files_encryption/js/settings.js | 19 +++++++++++++++---- apps/files_encryption/lib/keymanager.php | 7 +++++++ apps/files_encryption/templates/settings.php | 12 +++++++----- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index f335cf7f88..d70f9318e5 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -22,7 +22,7 @@ $(document).ready(function(){ $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'server', newpasswd: data[0].value, oldpasswd: data[1].value }, function(result) { if (result.status != 'success') { document.getElementById(prevmode+'_encryption').checked = true; - OC.dialogs.alert(t('encryption', 'Please check your passwords and try again'), t('encryption', 'Could not change encryption password to login password')) + OC.dialogs.alert(t('encryption', 'Please check your passwords and try again'), t('encryption', 'Could not change your file encryption password to your login password')) } }); }); diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js index 19ff27a3b2..60563bde85 100644 --- a/apps/files_encryption/js/settings.js +++ b/apps/files_encryption/js/settings.js @@ -23,13 +23,24 @@ $(document).ready(function(){ ,server=$('input[value="server"]:checked').val() ,user=$('input[value="user"]:checked').val() ,none=$('input[value="none"]:checked').val() - if (client) + ,disable=false + if (client) { OC.AppConfig.setValue('files_encryption','mode','client'); - else if (server) + disable = true; + } else if (server) { OC.AppConfig.setValue('files_encryption','mode','server'); - else if (user) + disable = true; + } else if (user) { OC.AppConfig.setValue('files_encryption','mode','user'); - else + disable = true; + } else { OC.AppConfig.setValue('files_encryption','mode','none'); + } + if (disable) { + document.getElementById('server_encryption').disabled = true; + document.getElementById('client_encryption').disabled = true; + document.getElementById('user_encryption').disabled = true; + document.getElementById('none_encryption').disabled = true; + } }) }) \ No newline at end of file diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 4c30c16395..62c5082a2f 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -199,6 +199,13 @@ class Keymanager { return $result; } + /** + * @brief change password of private encryption key + * + * @param string $oldpasswd old password + * @param string $newpasswd new password + * @return bool true/false + */ public static function changePasswd($oldpasswd, $newpasswd) { if ( \OCP\User::checkPassword(\OCP\User::getUser(), $newpasswd) ) { return Crypt::changekeypasscode($oldpasswd, $newpasswd); diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php index 4133f4573d..e2a9bcc3be 100644 --- a/apps/files_encryption/templates/settings.php +++ b/apps/files_encryption/templates/settings.php @@ -2,12 +2,14 @@
Choose encryption mode: - + +

Important: Once you selected an encryption mode there is no way to change it back

+

- /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
- /> Server side encryption (allows you to access your files from the web interface and the desktop client)
- /> User specific (let the user decide)
- /> None (no encryption at all)
+ /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
+ /> Server side encryption (allows you to access your files from the web interface and the desktop client)
+ /> User specific (let the user decide)
+ /> None (no encryption at all)

t('Encryption'); ?> From bd7d5667330e1f9c8674602ea489805def2ba4f4 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 9 Aug 2012 15:45:34 +0200 Subject: [PATCH 046/315] change private key passphrase; disable file proxy for keymanager operations --- apps/files_encryption/lib/keymanager.php | 36 ++++++++++++++++++------ 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 62c5082a2f..8d56ac97dc 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -36,10 +36,15 @@ class Keymanager { */ public static function getPrivateKey() { - $user = \OCP\User::getUser(); - $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' ); + \OC_FileProxy::$enabled = false; - return $view->file_get_contents( '/' . $user.'.private.key' ); + $user = \OCP\User::getUser(); + $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' ); + $result = $view->file_get_contents( '/' . $user.'.private.key' ); + + \OC_FileProxy::$enabled = true; + + return $result; } /** @@ -75,6 +80,8 @@ class Keymanager { } } + \OC_FileProxy::$enabled = false; + $view = new \OC_FilesystemView( '/public-keys/' ); $keylist = array(); @@ -83,6 +90,8 @@ class Keymanager { $keylist['key'.++$count] = $view->file_get_contents($user.'.public.key'); } + \OC_FileProxy::$enabled = true; + return $keylist; } @@ -108,8 +117,14 @@ class Keymanager { $keypath = str_replace('/'.$user.'/files/', '', $keypath); } + \OC_FileProxy::$enabled = false; + $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); - return $view->file_get_contents($keypath.'.key'); + $result = $view->file_get_contents($keypath.'.key'); + + \OC_FileProxy::$enabled = true; + + return $result; } /** @@ -208,11 +223,16 @@ class Keymanager { */ public static function changePasswd($oldpasswd, $newpasswd) { if ( \OCP\User::checkPassword(\OCP\User::getUser(), $newpasswd) ) { - return Crypt::changekeypasscode($oldpasswd, $newpasswd); - } else { - return false; + $key = Keymanager::getPrivateKey(); + if ( ($key = Crypt::symmetricDecryptFileContent($key,$oldpasswd)) ) { + if ( ($key = Crypt::symmetricEncryptFileContent($key, $newpasswd)) ) { + Keymanager::setPrivateKey($key); + return true; + + } + } } - + return false; } } \ No newline at end of file From 368ade6b2faef1d7ee0095b3921f285c62ba3a8f Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 9 Aug 2012 17:25:57 +0200 Subject: [PATCH 047/315] code cleanup --- apps/files_encryption/js/settings-personal.js | 20 ++++++++++--------- apps/files_encryption/lib/keymanager.php | 1 - 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index d70f9318e5..8afea6d77d 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -14,18 +14,20 @@ $(document).ready(function(){ if (client) { $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'client' }); if (prevmode == 'server') { - OC.dialogs.info(t('encryption', 'Please go to your owncloud client and change your encryption password to complete the conversion'), t('encryption', 'switched to client side encryption')); + OC.dialogs.info(t('encryption', 'Please switch to your ownCloud client and change your encryption password to complete the conversion.'), t('encryption', 'switched to client side encryption')); } } else if (server) { if (prevmode == 'client') { - OC.dialogs.form([{text:'login password', name:'newpasswd', type:'password'},{text:'Encryption password used on the client', name:'oldpasswd', type:'password'}],t('encryption', 'Change encryption password to login password'), function(data) { - $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'server', newpasswd: data[0].value, oldpasswd: data[1].value }, function(result) { - if (result.status != 'success') { - document.getElementById(prevmode+'_encryption').checked = true; - OC.dialogs.alert(t('encryption', 'Please check your passwords and try again'), t('encryption', 'Could not change your file encryption password to your login password')) - } - }); - }); + OC.dialogs.form([{text:'login password', name:'newpasswd', type:'password'},{text:'Encryption password used on the client', name:'oldpasswd', type:'password'}],t('encryption', 'Change encryption password to login password'), function(data) { + $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'server', newpasswd: data[0].value, oldpasswd: data[1].value }, function(result) { + if (result.status != 'success') { + document.getElementById(prevmode+'_encryption').checked = true; + OC.dialogs.alert(t('encryption', 'Please check your passwords and try again.'), t('encryption', 'Could not change your file encryption password to your login password')) + } else { + console.log("alles super"); + } + }, true); + }); } else { $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'server' }); } diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 8d56ac97dc..43ac67f8cb 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -228,7 +228,6 @@ class Keymanager { if ( ($key = Crypt::symmetricEncryptFileContent($key, $newpasswd)) ) { Keymanager::setPrivateKey($key); return true; - } } } From 7e3f5492cca404e009141798c41f4921a15ac3b3 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 9 Aug 2012 17:56:43 +0200 Subject: [PATCH 048/315] typo fixed --- apps/files_encryption/js/settings-personal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index 8afea6d77d..1a53e99d2b 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -18,7 +18,7 @@ $(document).ready(function(){ } } else if (server) { if (prevmode == 'client') { - OC.dialogs.form([{text:'login password', name:'newpasswd', type:'password'},{text:'Encryption password used on the client', name:'oldpasswd', type:'password'}],t('encryption', 'Change encryption password to login password'), function(data) { + OC.dialogs.form([{text:'Login password', name:'newpasswd', type:'password'},{text:'Encryption password used on the client', name:'oldpasswd', type:'password'}],t('encryption', 'Change encryption password to login password'), function(data) { $.post(OC.filePath('files_encryption', 'ajax', 'mode.php'), { mode: 'server', newpasswd: data[0].value, oldpasswd: data[1].value }, function(result) { if (result.status != 'success') { document.getElementById(prevmode+'_encryption').checked = true; From 12628be38bd8a8225139c19c6725255fcebc3d93 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 10 Aug 2012 11:44:38 +0200 Subject: [PATCH 049/315] only call proxies for server side encryption --- apps/files_encryption/lib/keymanager.php | 31 +++--------------------- apps/files_encryption/lib/proxy.php | 2 +- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 43ac67f8cb..0705205682 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -35,15 +35,11 @@ class Keymanager { * @return string private key or false */ public static function getPrivateKey() { - - \OC_FileProxy::$enabled = false; - + $user = \OCP\User::getUser(); $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' ); $result = $view->file_get_contents( '/' . $user.'.private.key' ); - - \OC_FileProxy::$enabled = true; - + return $result; } @@ -80,8 +76,6 @@ class Keymanager { } } - \OC_FileProxy::$enabled = false; - $view = new \OC_FilesystemView( '/public-keys/' ); $keylist = array(); @@ -89,8 +83,6 @@ class Keymanager { foreach ($users as $user) { $keylist['key'.++$count] = $view->file_get_contents($user.'.public.key'); } - - \OC_FileProxy::$enabled = true; return $keylist; @@ -117,13 +109,9 @@ class Keymanager { $keypath = str_replace('/'.$user.'/files/', '', $keypath); } - \OC_FileProxy::$enabled = false; - $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); $result = $view->file_get_contents($keypath.'.key'); - - \OC_FileProxy::$enabled = true; - + return $result; } @@ -134,16 +122,12 @@ class Keymanager { * @return bool true/false */ public static function setPrivateKey($key) { - - \OC_FileProxy::$enabled = false; $user = \OCP\User::getUser(); $view = new \OC_FilesystemView('/'.$user.'/files_encryption'); if (!$view->file_exists('')) $view->mkdir(''); $result = $view->file_put_contents($user.'.private.key', $key); - \OC_FileProxy::$enabled = true; - return $result; } @@ -156,14 +140,10 @@ class Keymanager { */ public static function setPublicKey($key) { - \OC_FileProxy::$enabled = false; - $view = new \OC_FilesystemView('/public-keys'); if (!$view->file_exists('')) $view->mkdir(''); $result = $view->file_put_contents(\OCP\User::getUser().'.public.key', $key); - \OC_FileProxy::$enabled = true; - return $result; } @@ -174,8 +154,7 @@ class Keymanager { * @param string $key * @return bool true/false */ - public static function setFileKey( $path, $key, $view = Null, $dbClassName = '\OC_DB', $fileProxyClassName = '\OC_FileProxy') { - $fileProxyClassName::$enabled = false; + public static function setFileKey( $path, $key, $view = Null, $dbClassName = '\OC_DB') { $targetpath = ltrim( $path, '/' ); $user = \OCP\User::getUser(); @@ -209,8 +188,6 @@ class Keymanager { $result = $view->file_put_contents( '/' . $targetpath . '.key', $key ); - $fileProxyClassName::$enabled = true; - return $result; } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 94f427f2f2..32b7a67e65 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -46,7 +46,7 @@ class Proxy extends \OC_FileProxy { if ( is_null( self::$enableEncryption ) ) { - self::$enableEncryption = ( \OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' ); + self::$enableEncryption = ( \OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' && Crypt::mode() == 'server' ); } From e4450d10354a23d8b20eea6657fb7bd1e57580fa Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 10 Aug 2012 12:27:09 +0200 Subject: [PATCH 050/315] execute file hooks only if server side encryption is enabled --- apps/files_encryption/hooks/hooks.php | 2 +- apps/files_encryption/lib/keymanager.php | 21 +++++++++------------ apps/files_encryption/lib/proxy.php | 12 ++++++------ 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index b7e8df9eac..a9b3b2bcd8 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -63,7 +63,7 @@ class Hooks { * @brief update the encryption key of the file uploaded by the client */ public static function updateKeyfile( $params ) { - if (Crypt::mode(\OCP\User::getUser()) == 'client') + if (Crypt::mode() == 'client') if (isset($params['properties']['key'])) { Keymanager::setFileKey($params['path'], $params['properties']['key']); } else { diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 0705205682..42aaf9b60b 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -38,9 +38,8 @@ class Keymanager { $user = \OCP\User::getUser(); $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' ); - $result = $view->file_get_contents( '/' . $user.'.private.key' ); - - return $result; + return $view->file_get_contents( '/' . $user.'.private.key' ); + } /** @@ -110,9 +109,8 @@ class Keymanager { } $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); - $result = $view->file_get_contents($keypath.'.key'); - - return $result; + return $view->file_get_contents($keypath.'.key'); + } /** @@ -126,9 +124,8 @@ class Keymanager { $user = \OCP\User::getUser(); $view = new \OC_FilesystemView('/'.$user.'/files_encryption'); if (!$view->file_exists('')) $view->mkdir(''); - $result = $view->file_put_contents($user.'.private.key', $key); + return $view->file_put_contents($user.'.private.key', $key); - return $result; } @@ -142,9 +139,8 @@ class Keymanager { $view = new \OC_FilesystemView('/public-keys'); if (!$view->file_exists('')) $view->mkdir(''); - $result = $view->file_put_contents(\OCP\User::getUser().'.public.key', $key); + return $view->file_put_contents(\OCP\User::getUser().'.public.key', $key); - return $result; } /** @@ -186,9 +182,8 @@ class Keymanager { if ( !$view->file_exists( $path_parts['dirname'] ) ) $view->mkdir( $path_parts['dirname'] ); - $result = $view->file_put_contents( '/' . $targetpath . '.key', $key ); + return $view->file_put_contents( '/' . $targetpath . '.key', $key ); - return $result; } /** @@ -199,6 +194,7 @@ class Keymanager { * @return bool true/false */ public static function changePasswd($oldpasswd, $newpasswd) { + if ( \OCP\User::checkPassword(\OCP\User::getUser(), $newpasswd) ) { $key = Keymanager::getPrivateKey(); if ( ($key = Crypt::symmetricDecryptFileContent($key,$oldpasswd)) ) { @@ -209,6 +205,7 @@ class Keymanager { } } return false; + } } \ No newline at end of file diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 32b7a67e65..85b5c868f3 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -40,7 +40,7 @@ class Proxy extends \OC_FileProxy { * @param string $path * @return bool * - * Tests if encryption is enabled, and file is allowed by blacklists + * Tests if server side encryption is enabled, and file is allowed by blacklists */ private static function shouldEncrypt( $path ) { @@ -130,7 +130,7 @@ class Proxy extends \OC_FileProxy { public function postFile_get_contents( $path, $data ) { - if ( Crypt::isEncryptedContent( $data ) ) { + if ( Crypt::mode() == 'server' && Crypt::isEncryptedContent( $data ) ) { $filePath = explode( '/', $path ); @@ -164,7 +164,7 @@ class Proxy extends \OC_FileProxy { $meta = stream_get_meta_data( $result ); // If file is encrypted, decrypt using crypto protocol - if ( Crypt::isEncryptedContent( $path ) ) { + if ( Crypt::mode() == 'server' && Crypt::isEncryptedContent( $path ) ) { fclose ( $result ); @@ -208,14 +208,14 @@ class Proxy extends \OC_FileProxy { } public function postGetMimeType($path,$mime){ - if(Crypt::isEncryptedContent($path)){ + if( Crypt::isEncryptedContent($path)){ $mime = \OCP\Files::getMimeType('crypt://'.$path,'w'); } return $mime; } public function postStat($path,$data){ - if(Crypt::isEncryptedContent($path)){ + if( Crypt::isEncryptedContent($path)){ $cached= \OC_FileCache_Cached::get($path,''); $data['size']=$cached['size']; } @@ -223,7 +223,7 @@ class Proxy extends \OC_FileProxy { } public function postFileSize($path,$size){ - if(Crypt::isEncryptedContent($path)){ + if( Crypt::isEncryptedContent($path)){ $cached = \OC_FileCache_Cached::get($path,''); return $cached['size']; }else{ From 3ec6dc56c93c1c71b58aceef4b211ed75c807f6c Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 10 Aug 2012 12:37:04 +0200 Subject: [PATCH 051/315] ToDo item removed --- apps/files_encryption/ajax/mode.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/files_encryption/ajax/mode.php b/apps/files_encryption/ajax/mode.php index f1a026ca43..64203b42cf 100644 --- a/apps/files_encryption/ajax/mode.php +++ b/apps/files_encryption/ajax/mode.php @@ -4,8 +4,6 @@ * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. */ - -//TODO: Handle switch between client and server side encryption use OCA_Encryption\Keymanager; From 34f93ac765690c956fb7f7be1ab087c6b65c6f3b Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 13 Aug 2012 11:31:15 +0200 Subject: [PATCH 052/315] check if user has write access to a given file before updating the filekey --- apps/files_encryption/lib/keymanager.php | 6 ++++++ lib/ocs.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 42aaf9b60b..10b673f31a 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -167,6 +167,12 @@ class Keymanager { $targetpath_parts=explode( '/',$targetpath ); $user = $targetpath_parts[1]; + + $rootview = new \OC_FilesystemView( '/'); + if (!$rootview->is_writable($targetpath)) { + \OC_Log::write( 'Encryption library', "File Key not updated because you don't have write access for the corresponding file" , \OC_Log::ERROR ); + return false; + } $targetpath = str_replace( '/'.$user.'/files/', '', $targetpath ); diff --git a/lib/ocs.php b/lib/ocs.php index 0fc208516e..5d4e19c0c4 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -767,7 +767,7 @@ class OC_OCS { } /** - * set the encryption keyn of a file + * set the encryption key of a file * @param string $format * @param string $file * @param string $key From b1f6bb36b023f609c4602b651394dce7d3bf1d60 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 13 Aug 2012 13:29:22 +0200 Subject: [PATCH 053/315] write error to OC_Log --- apps/files_encryption/hooks/hooks.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index a9b3b2bcd8..5215ac1062 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -67,6 +67,7 @@ class Hooks { if (isset($params['properties']['key'])) { Keymanager::setFileKey($params['path'], $params['properties']['key']); } else { + \OC_Log::write( 'Encryption library', "Client side encryption is enabled but the client doesn't provide a encryption key for the file!", \OC_Log::ERROR ); error_log("Client side encryption is enabled but the client doesn't provide a encryption key for the file!"); } } From 6ce315fe5826d058722353f3d4c0b2f025dabd43 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 14 Aug 2012 19:06:56 +0100 Subject: [PATCH 054/315] added wrapper method in crypt class for encrypting asymmetric and symmetric simultaneously fixed bugs with keymanager integration added unit tests --- apps/files_encryption/hooks/hooks.php | 145 +++++++++--------- apps/files_encryption/lib/crypt.php | 51 +++++- apps/files_encryption/lib/keymanager.php | 27 +++- apps/files_encryption/lib/proxy.php | 25 ++- .../tests/{encryption.php => crypt.php} | 48 +++++- 5 files changed, 199 insertions(+), 97 deletions(-) rename apps/files_encryption/tests/{encryption.php => crypt.php} (80%) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 5215ac1062..e23e3a09d4 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -1,76 +1,77 @@ -. - * - */ - -namespace OCA_Encryption; - -/** - * Class for hook specific logic - */ - -class Hooks { - - # TODO: use passphrase for encrypting private key that is separate to the login password - - /** - * @brief Startup encryption backend upon user login - * @note This method should never be called for users using client side encryption - */ - - public static function login( $params ) { - - if ( Crypt::mode( $params['uid'] ) == 'server' ) { - - $view = new \OC_FilesystemView( '/' ); - - $util = new Util( $view, $params['uid'] ); - - if ( !$util->ready()) { - - return $util->setupServerSide( $params['password'] ); - - } - - $encryptedKey = Keymanager::getPrivateKey( $params['uid'] ); - - $_SESSION['enckey'] = Crypt::symmetricEncryptFileContent( $encryptedKey, $params['password'] ); - } - - return true; - - } - +. + * + */ + +namespace OCA_Encryption; + +/** + * Class for hook specific logic + */ + +class Hooks { + + # TODO: use passphrase for encrypting private key that is separate to the login password + + /** + * @brief Startup encryption backend upon user login + * @note This method should never be called for users using client side encryption + */ + + public static function login( $params ) { + + if ( Crypt::mode( $params['uid'] ) == 'server' ) { + + $view = new \OC_FilesystemView( '/' ); + + $util = new Util( $view, $params['uid'] ); + + if ( !$util->ready()) { + + return $util->setupServerSide( $params['password'] ); + + } + + $encryptedKey = Keymanager::getPrivateKey( $params['uid'] ); + + $_SESSION['enckey'] = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); + + } + + return true; + + } + /** * @brief update the encryption key of the file uploaded by the client - */ - public static function updateKeyfile( $params ) { - if (Crypt::mode() == 'client') - if (isset($params['properties']['key'])) { - Keymanager::setFileKey($params['path'], $params['properties']['key']); - } else { - \OC_Log::write( 'Encryption library', "Client side encryption is enabled but the client doesn't provide a encryption key for the file!", \OC_Log::ERROR ); - error_log("Client side encryption is enabled but the client doesn't provide a encryption key for the file!"); - } - } -} - + */ + public static function updateKeyfile( $params ) { + if (Crypt::mode() == 'client') + if (isset($params['properties']['key'])) { + Keymanager::setFileKey($params['path'], $params['properties']['key']); + } else { + \OC_Log::write( 'Encryption library', "Client side encryption is enabled but the client doesn't provide a encryption key for the file!", \OC_Log::ERROR ); + error_log("Client side encryption is enabled but the client doesn't provide a encryption key for the file!"); + } + } +} + ?> \ No newline at end of file diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 1fa7013776..f868028be9 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -38,19 +38,19 @@ class Crypt { public static function mode( $user = null ) { $mode = \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' ); - + if ( $mode == 'user') { if ( !$user ) { $user = \OCP\User::getUser(); - } - $mode = 'none'; - if ( $user ) { + } + $mode = 'none'; + if ( $user ) { $query = \OC_DB::prepare( "SELECT mode FROM *PREFIX*encryption WHERE uid = ?" ); $result = $query->execute(array($user)); if ($row = $result->fetchRow()){ $mode = $row['mode']; - } - } + } + } } return $mode; @@ -217,6 +217,7 @@ class Crypt { * @param string $source * @param string $target * @param string $key the decryption key + * @returns decrypted content * * This function decrypts a file */ @@ -305,7 +306,7 @@ class Crypt { /** * @brief Asymmetrically encrypt a file using multiple public keys * @param string $plainContent content to be encrypted - * @returns array keys: key, encrypted + * @returns string $plainContent decrypted string * @note symmetricDecryptFileContent() can be used to decrypt files created using this method * * This function decrypts a file @@ -355,6 +356,40 @@ class Crypt { return $plainContent; } + + /** + * @brief Encrypts content symmetrically and generated keyfile asymmetrically + * @returns array keys: data, key + * @note this method is a wrapper for combining other crypt class methods + */ + public static function keyEncryptKeyfile( $plainContent, $publicKey ) { + + // Encrypt plain data, generate keyfile & encrypted file + $cryptedData = self::symmetricEncryptFileContentKeyfile( $plainContent ); + + // Encrypt keyfile + $cryptedKey = self::keyEncrypt( $cryptedData['key'], $publicKey ); + + return array( 'data' => $cryptedData['encrypted'], 'key' => $cryptedKey ); + + } + + /** + * @brief Encrypts content symmetrically and generated keyfile asymmetrically + * @returns decrypted content + * @note this method is a wrapper for combining other crypt class methods + */ + public static function keyDecryptKeyfile( $encryptedData, $encryptedKey, $privateKey ) { + + // Decrypt keyfile + $decryptedKey = self::keyDecrypt( $encryptedKey, $privateKey ); + + // Decrypt encrypted file + $decryptedData = self::symmetricDecryptFileContent( $encryptedData, $decryptedKey ); + + return $decryptedData; + + } /** * @brief Generate a pseudo random 1024kb ASCII key @@ -392,7 +427,7 @@ class Crypt { // $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); // Generate key - if ( $key = base64_encode( openssl_random_pseudo_bytes( 768000, $strong ) ) ) { + if ( $key = base64_encode( openssl_random_pseudo_bytes( 183, $strong ) ) ) { if ( !$strong ) { diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 10b673f31a..8d81c97cfa 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -41,6 +41,19 @@ class Keymanager { return $view->file_get_contents( '/' . $user.'.private.key' ); } + + /** + * @brief retrieve public key for a specified user + * + * @return string public key or false + */ + public static function getPublicKey() { + + $user = \OCP\User::getUser(); + $view = new \OC_FilesystemView( '/public-keys/' ); + return $view->file_get_contents( '/' . $user . '.public.key' ); + + } /** * @brief retrieve a list of the public key from all users with access to the file @@ -94,22 +107,26 @@ class Keymanager { * @return string file key or false */ public static function getFileKey( $path ) { - + trigger_error("div ".$path); $keypath = ltrim( $path, '/' ); $user = \OCP\User::getUser(); // update $keypath and $user if path point to a file shared by someone else $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); + $result = $query->execute( array ('/'.$user.'/files/'.$keypath, $user)); - if ($row = $result->fetchRow()){ + + if ($row = $result->fetchRow()) { + $keypath = $row['source']; - $keypath_parts=explode('/',$keypath); + $keypath_parts = explode( '/', $keypath ); $user = $keypath_parts[1]; - $keypath = str_replace('/'.$user.'/files/', '', $keypath); + $keypath = str_replace( '/' . $user . '/files/', '', $keypath ); + } $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); - return $view->file_get_contents($keypath.'.key'); + return $view->file_get_contents( $keypath . '.key' ); } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 85b5c868f3..51ed889d12 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -103,11 +103,14 @@ class Proxy extends \OC_FileProxy { // Set the filesize for userland, before encrypting $size = strlen( $data ); + // Disable encryption proxy to prevent recursive calls + \OC_FileProxy::$enabled = false; + // Encrypt plain data and fetch key - $encrypted = Crypt::symmetricEncryptFileContentKeyfile( $data, $_SESSION['enckey'] ); + $encrypted = Crypt::keyEncryptKeyfile( $data, Keymanager::getPublicKey() ); // Replace plain content with encrypted content by reference - $data = $encrypted['encrypted']; + $data = $encrypted['data']; $filePath = explode( '/', $path ); @@ -119,11 +122,13 @@ class Proxy extends \OC_FileProxy { $view = new \OC_FilesystemView( '/' . \OCP\USER::getUser() . '/files_encryption/keyfiles' ); // Save keyfile for newly encrypted file in parallel directory tree - Keymanager::setFileKey( \OCP\USER::getUser(), $filePath, $encrypted['key'], $view, '\OC_DB', '\OC_FileProxy' ); + Keymanager::setFileKey( $filePath, $encrypted['key'], $view, '\OC_DB' ); // Update the file cache with file info \OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); + \OC_FileProxy::$enabled = true; + } } } @@ -138,14 +143,18 @@ class Proxy extends \OC_FileProxy { $filePath = '/' . implode( '/', $filePath ); - trigger_error( "CAT " . $filePath); - $cached = \OC_FileCache_Cached::get( $path, '' ); - // Get keyfile for encrypted file - $keyFile = Keymanager::getFileKey( \OCP\USER::getUser(), $filePath ); + // Disable encryption proxy to prevent recursive calls + \OC_FileProxy::$enabled = false; - $data = Crypt::symmetricDecryptFileContent( $data, $keyFile ); + $keyFile = Keymanager::getFileKey( $filePath ); + + $privateKey = Keymanager::getPrivateKey(); + + $data = Crypt::keyDecryptKeyfile( $data, $keyFile, $privateKey ); + + \OC_FileProxy::$enabled = true; } diff --git a/apps/files_encryption/tests/encryption.php b/apps/files_encryption/tests/crypt.php similarity index 80% rename from apps/files_encryption/tests/encryption.php rename to apps/files_encryption/tests/crypt.php index ed3b65b179..b6dc0f40aa 100644 --- a/apps/files_encryption/tests/encryption.php +++ b/apps/files_encryption/tests/crypt.php @@ -7,11 +7,11 @@ * See the COPYING-README file. */ -require realpath( dirname(__FILE__).'/../lib/crypt.php' ); -require realpath( dirname(__FILE__).'/../lib/util.php' ); +require_once realpath( dirname(__FILE__).'/../lib/crypt.php' ); +require_once realpath( dirname(__FILE__).'/../lib/util.php' ); //require realpath( dirname(__FILE__).'/../../../lib/filecache.php' ); -class Test_Encryption extends UnitTestCase { +class Test_Crypt extends UnitTestCase { function setUp() { @@ -32,7 +32,7 @@ class Test_Encryption extends UnitTestCase { $this->assertTrue( $key ); - $this->assertTrue( strlen( $key ) > 1000 ); + $this->assertTrue( strlen( $key ) > 16 ); } @@ -137,6 +137,46 @@ class Test_Encryption extends UnitTestCase { $this->assertEqual( $this->data, $decrypt ); } + + function testKeyEncrypt() { + + // Generate keypair + $pair1 = OCA_Encryption\Crypt::createKeypair(); + + // Encrypt data + $crypted = OCA_Encryption\Crypt::keyEncrypt( $this->data, $pair1['publicKey'] ); + + $this->assertNotEqual( $this->data, $crypted ); + + // Decrypt data + $decrypt = OCA_Encryption\Crypt::keyDecrypt( $crypted, $pair1['privateKey'] ); + + $this->assertEqual( $this->data, $decrypt ); + + } + + function testKeyEncryptKeyfile() { + + # TODO: Don't repeat encryption from previous tests, use PHPUnit test interdependency instead + + // Generate keypair + $pair1 = OCA_Encryption\Crypt::createKeypair(); + + // Encrypt plain data, generate keyfile & encrypted file + $cryptedData = OCA_Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->data ); + + // Encrypt keyfile + $cryptedKey = OCA_Encryption\Crypt::keyEncrypt( $cryptedData['key'], $pair1['publicKey'] ); + + // Decrypt keyfile + $decryptKey = OCA_Encryption\Crypt::keyDecrypt( $cryptedKey, $pair1['privateKey'] ); + + // Decrypt encrypted file + $decryptData = OCA_Encryption\Crypt::symmetricDecryptFileContent( $cryptedData['encrypted'], $decryptKey ); + + $this->assertEqual( $this->data, $decryptData ); + + } // function testEncryption(){ // From 92ec88c7bc1e252a3f5071e3bd59a24d02637f12 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 15 Aug 2012 09:54:21 +0200 Subject: [PATCH 055/315] move chane password code from keymanager.php to crypt.php --- apps/files_encryption/lib/crypt.php | 22 +++++++--------------- apps/files_encryption/lib/keymanager.php | 8 +------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index f868028be9..07230fe8a2 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -447,26 +447,18 @@ class Crypt { } public static function changekeypasscode($oldPassword, $newPassword) { + if(\OCP\User::isLoggedIn()){ - $username = \OCP\USER::getUser(); - $view = new \OC_FilesystemView('/'.$username); - - // read old key $key = Keymanager::getPrivateKey(); - - // decrypt key with old passcode - if ( ($key = self::decrypt($key, $oldPassword)) ) { - // encrypt again with new passcode - $key = self::encrypt($key, $newPassword); - - // store the new key - return Keymanager::setPrivateKey($key); - } else { - return false; + if ( ($key = Crypt::symmetricDecryptFileContent($key,$oldpasswd)) ) { + if ( ($key = Crypt::symmetricEncryptFileContent($key, $newpasswd)) ) { + Keymanager::setPrivateKey($key); + return true; + } } } + return false; } - } ?> \ No newline at end of file diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 8d81c97cfa..1ffeff9928 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -219,13 +219,7 @@ class Keymanager { public static function changePasswd($oldpasswd, $newpasswd) { if ( \OCP\User::checkPassword(\OCP\User::getUser(), $newpasswd) ) { - $key = Keymanager::getPrivateKey(); - if ( ($key = Crypt::symmetricDecryptFileContent($key,$oldpasswd)) ) { - if ( ($key = Crypt::symmetricEncryptFileContent($key, $newpasswd)) ) { - Keymanager::setPrivateKey($key); - return true; - } - } + return Crypt::changekeypasscode($oldpasswd, $newpasswd); } return false; From d039f11905658f2642d84f4054abde0c3b920ea8 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 15 Aug 2012 13:18:11 +0200 Subject: [PATCH 056/315] provide ocs calls and keymanager functions to get/set both keys (private, public) of a user together --- apps/files_encryption/lib/keymanager.php | 27 ++++++++++++ lib/ocs.php | 53 ++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 1ffeff9928..ea6e4872d4 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -55,6 +55,20 @@ class Keymanager { } + /** + * @brief retrieve both keys from a user (private and public) + * + * @return string private key or false + */ + public static function getUserKeys() { + + return array( + 'privatekey' => self::getPrivateKey(), + 'publickey' => self::getPublicKey(), + ); + + } + /** * @brief retrieve a list of the public key from all users with access to the file * @@ -145,6 +159,19 @@ class Keymanager { } + /** + * @brief store private keys from the user + * + * @param string privatekey + * @param string publickey + * @return bool true/false + */ + public static function setUserKeys($privatekey, $publickey) { + + return (self::setPrivateKey($privatekey) && self::setPublicKey($publickey)); + + } + /** * @brief store public key of the user diff --git a/lib/ocs.php b/lib/ocs.php index 5d4e19c0c4..423e1752da 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -187,6 +187,16 @@ class OC_OCS { $key = self::readData('post', 'key', 'string'); OC_OCS::privateKeySet($format, $key); + // keygetuser + }elseif(($method=='get') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='cloud') and ($ex[$paracount-2] == 'userkeys')){ + OC_OCS::userKeysGet($format); + + //keysetuser + }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='cloud') and ($ex[$paracount-2] == 'userkeys')){ + $privatekey = self::readData('post', 'privatekey', 'string'); + $publickey = self::readData('post', 'publickey', 'string'); + OC_OCS::userKeysSet($format, $privatekey, $publickey); + // keygetfiles }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'file') and ($ex[$paracount-2] == 'filekey')){ $file = urldecode($ex[$paracount-3]); @@ -744,6 +754,49 @@ class OC_OCS { } } + /** + * get both user keys (private and public) + * @param string $format + * @return string xml/json + */ + private static function userKeysGet($format) { + $login=OC_OCS::checkpassword(); + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') { + $keys = OCA_Encryption\Keymanager::getUserKeys(); + if ($keys['privatekey'] && $keys['publickey']) { + $xml=array(); + $xml['privatekey']=$keys['privatekey']; + $xml['publickey']=$keys['publickey']; + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + } else { + echo self::generateXml('', 'fail', 404, 'Keys not found on the server'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled'); + } + } + + /** + * set both user keys (private and public) + * @param string $format + * @param string $privatekey + * @param string @publickey + * @return string xml/json + */ + private static function userKeysSet($format, $privatekey, $publickey) { + $login=OC_OCS::checkpassword(); + if(OC_App::isEnabled('files_encryption') && OCA_Encryption\Crypt::mode() === 'client') { + if (($key = OCA_Encryption\Keymanager::setUserKeys($privatekey, $publickey))) { + echo self::generateXml('', 'ok', 100, ''); + } else { + echo self::generateXml('', 'fail', 404, 'could not add your keys to the key storage'); + } + } else { + echo self::generateXml('', 'fail', 300, 'Client side encryption not enabled'); + } + } + /** * get the encryption key of a file * @param string $format From ea236e83d73067a8df1ee694011dca979ca60507 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 15 Aug 2012 14:01:43 +0100 Subject: [PATCH 057/315] added first version of keymanager PHPUnit test files --- apps/files_encryption/tests/keymanager.php | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 apps/files_encryption/tests/keymanager.php diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php new file mode 100644 index 0000000000..e2cc51a223 --- /dev/null +++ b/apps/files_encryption/tests/keymanager.php @@ -0,0 +1,43 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA_Encryption; + +require_once "PHPUnit/Framework/TestCase.php"; +require_once realpath( dirname(__FILE__).'/../../../lib/base.php' ); + +class Test_Keymanager extends \PHPUnit_Framework_TestCase { + + function setUp() { + + // set content for encrypting / decrypting in tests + $this->user = 'admin'; + $this->view = new \OC_FilesystemView( '' ); + + // Disable encryption proxy to prevent recursive calls + \OC_FileProxy::$enabled = false; + + } + + function tearDown(){ + + \OC_FileProxy::$enabled = false; + + } + + function testGetPrivateKey() { + + $key = Keymanager::getPrivateKey( $this->user, $this->view ); + + $this->assertEquals( 2302, strlen( $key ) ); + + $this->assertTrue( substr( $key, 27 ) == '-----BEGIN PRIVATE KEY-----' ); + + } + +} From d725d072194f82ea575068f826b7f365530ab162 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 15 Aug 2012 14:13:03 +0100 Subject: [PATCH 058/315] added two (currently passing) unit tests --- apps/files_encryption/tests/keymanager.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php index e2cc51a223..51b49c5da5 100644 --- a/apps/files_encryption/tests/keymanager.php +++ b/apps/files_encryption/tests/keymanager.php @@ -17,6 +17,7 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase { // set content for encrypting / decrypting in tests $this->user = 'admin'; + $this->passphrase = 'admin'; $this->view = new \OC_FilesystemView( '' ); // Disable encryption proxy to prevent recursive calls @@ -26,17 +27,27 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase { function tearDown(){ - \OC_FileProxy::$enabled = false; + \OC_FileProxy::$enabled = true; } - function testGetPrivateKey() { + function testGetEncryptedPrivateKey() { $key = Keymanager::getPrivateKey( $this->user, $this->view ); $this->assertEquals( 2302, strlen( $key ) ); + + } + + function testGetDecryptedPrivateKey() { + + $key = Keymanager::getPrivateKey( $this->user, $this->view ); - $this->assertTrue( substr( $key, 27 ) == '-----BEGIN PRIVATE KEY-----' ); + $decrypted = Crypt::symmetricDecryptFileContent( $key, $this->passphrase ); + + $this->assertEquals( 1708, strlen( $decrypted ) ); + + $this->assertEquals( '-----BEGIN PRIVATE KEY-----', substr( $decrypted, 0, 27 ) ); } From b883bb6b42ab64792fa6d9c299dd2aa0f652fb3a Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 15 Aug 2012 14:52:03 +0100 Subject: [PATCH 059/315] Converted test to PHPUnit format --- apps/files_encryption/tests/crypt.php | 91 +++++++++++++-------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index b6dc0f40aa..2802f32a58 100644 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -7,11 +7,12 @@ * See the COPYING-README file. */ -require_once realpath( dirname(__FILE__).'/../lib/crypt.php' ); -require_once realpath( dirname(__FILE__).'/../lib/util.php' ); -//require realpath( dirname(__FILE__).'/../../../lib/filecache.php' ); +namespace OCA_Encryption; -class Test_Crypt extends UnitTestCase { +require_once "PHPUnit/Framework/TestCase.php"; +require_once realpath( dirname(__FILE__).'/../../../lib/base.php' ); + +class Test_Crypt extends \PHPUnit_Framework_TestCase { function setUp() { @@ -28,9 +29,7 @@ class Test_Crypt extends UnitTestCase { # TODO: use more accurate (larger) string length for test confirmation - $key = OCA_Encryption\Crypt::generateKey(); - - $this->assertTrue( $key ); + $key = Crypt::generateKey(); $this->assertTrue( strlen( $key ) > 16 ); @@ -38,9 +37,7 @@ class Test_Crypt extends UnitTestCase { function testGenerateIv() { - $iv = OCA_Encryption\Crypt::generateIv(); - - $this->assertTrue( $iv ); + $iv = Crypt::generateIv(); $this->assertTrue( strlen( $iv ) == 16 ); @@ -52,9 +49,9 @@ class Test_Crypt extends UnitTestCase { $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht - $crypted = OCA_Encryption\Crypt::encrypt( $this->data, $iv, 'hat' ); + $crypted = Crypt::encrypt( $this->data, $iv, 'hat' ); - $this->assertNotEqual( $this->data, $crypted ); + $this->assertNotEquals( $this->data, $crypted ); } @@ -64,11 +61,11 @@ class Test_Crypt extends UnitTestCase { $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht - $crypted = OCA_Encryption\Crypt::encrypt( $this->data, $iv, 'hat' ); + $crypted = Crypt::encrypt( $this->data, $iv, 'hat' ); - $decrypt = OCA_Encryption\Crypt::decrypt( $crypted, $iv, 'hat' ); + $decrypt = Crypt::decrypt( $crypted, $iv, 'hat' ); - $this->assertEqual( $this->data, $decrypt ); + $this->assertEquals( $this->data, $decrypt ); } @@ -76,14 +73,14 @@ class Test_Crypt extends UnitTestCase { # TODO: search in keyfile for actual content as IV will ensure this test always passes - $keyfileContent = OCA_Encryption\Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); + $keyfileContent = Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); - $this->assertNotEqual( $this->data, $keyfileContent ); + $this->assertNotEquals( $this->data, $keyfileContent ); - $decrypt = OCA_Encryption\Crypt::symmetricDecryptFileContent( $keyfileContent, 'hat' ); + $decrypt = Crypt::symmetricDecryptFileContent( $keyfileContent, 'hat' ); - $this->assertEqual( $this->data, $decrypt ); + $this->assertEquals( $this->data, $decrypt ); } @@ -91,26 +88,26 @@ class Test_Crypt extends UnitTestCase { # TODO: search in keyfile for actual content as IV will ensure this test always passes - $crypted = OCA_Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->data ); + $crypted = Crypt::symmetricEncryptFileContentKeyfile( $this->data ); - $this->assertNotEqual( $this->data, $crypted['encrypted'] ); + $this->assertNotEquals( $this->data, $crypted['encrypted'] ); - $decrypt = OCA_Encryption\Crypt::symmetricDecryptFileContent( $crypted['encrypted'], $crypted['key'] ); + $decrypt = Crypt::symmetricDecryptFileContent( $crypted['encrypted'], $crypted['key'] ); - $this->assertEqual( $this->data, $decrypt ); + $this->assertEquals( $this->data, $decrypt ); } function testIsEncryptedContent() { - $this->assertFalse( OCA_Encryption\Crypt::isEncryptedContent( $this->data ) ); + $this->assertFalse( Crypt::isEncryptedContent( $this->data ) ); - $this->assertFalse( OCA_Encryption\Crypt::isEncryptedContent( $this->legacyEncryptedData ) ); + $this->assertFalse( Crypt::isEncryptedContent( $this->legacyEncryptedData ) ); - $keyfileContent = OCA_Encryption\Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); + $keyfileContent = Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); - $this->assertTrue( OCA_Encryption\Crypt::isEncryptedContent( $keyfileContent ) ); + $this->assertTrue( Crypt::isEncryptedContent( $keyfileContent ) ); } @@ -118,40 +115,40 @@ class Test_Crypt extends UnitTestCase { # TODO: search in keyfile for actual content as IV will ensure this test always passes - $pair1 = OCA_Encryption\Crypt::createKeypair(); + $pair1 = Crypt::createKeypair(); - $this->assertEqual( 2, count( $pair1 ) ); + $this->assertEquals( 2, count( $pair1 ) ); $this->assertTrue( strlen( $pair1['publicKey'] ) > 1 ); $this->assertTrue( strlen( $pair1['privateKey'] ) > 1 ); - $crypted = OCA_Encryption\Crypt::multiKeyEncrypt( $this->data, array( $pair1['publicKey'] ) ); + $crypted = Crypt::multiKeyEncrypt( $this->data, array( $pair1['publicKey'] ) ); - $this->assertNotEqual( $this->data, $crypted['encrypted'] ); + $this->assertNotEquals( $this->data, $crypted['encrypted'] ); - $decrypt = OCA_Encryption\Crypt::multiKeyDecrypt( $crypted['encrypted'], $crypted['keys'][0], $pair1['privateKey'] ); + $decrypt = Crypt::multiKeyDecrypt( $crypted['encrypted'], $crypted['keys'][0], $pair1['privateKey'] ); - $this->assertEqual( $this->data, $decrypt ); + $this->assertEquals( $this->data, $decrypt ); } function testKeyEncrypt() { // Generate keypair - $pair1 = OCA_Encryption\Crypt::createKeypair(); + $pair1 = Crypt::createKeypair(); // Encrypt data - $crypted = OCA_Encryption\Crypt::keyEncrypt( $this->data, $pair1['publicKey'] ); + $crypted = Crypt::keyEncrypt( $this->data, $pair1['publicKey'] ); - $this->assertNotEqual( $this->data, $crypted ); + $this->assertNotEquals( $this->data, $crypted ); // Decrypt data - $decrypt = OCA_Encryption\Crypt::keyDecrypt( $crypted, $pair1['privateKey'] ); + $decrypt = Crypt::keyDecrypt( $crypted, $pair1['privateKey'] ); - $this->assertEqual( $this->data, $decrypt ); + $this->assertEquals( $this->data, $decrypt ); } @@ -160,21 +157,21 @@ class Test_Crypt extends UnitTestCase { # TODO: Don't repeat encryption from previous tests, use PHPUnit test interdependency instead // Generate keypair - $pair1 = OCA_Encryption\Crypt::createKeypair(); + $pair1 = Crypt::createKeypair(); // Encrypt plain data, generate keyfile & encrypted file - $cryptedData = OCA_Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->data ); + $cryptedData = Crypt::symmetricEncryptFileContentKeyfile( $this->data ); // Encrypt keyfile - $cryptedKey = OCA_Encryption\Crypt::keyEncrypt( $cryptedData['key'], $pair1['publicKey'] ); + $cryptedKey = Crypt::keyEncrypt( $cryptedData['key'], $pair1['publicKey'] ); // Decrypt keyfile - $decryptKey = OCA_Encryption\Crypt::keyDecrypt( $cryptedKey, $pair1['privateKey'] ); + $decryptKey = Crypt::keyDecrypt( $cryptedKey, $pair1['privateKey'] ); // Decrypt encrypted file - $decryptData = OCA_Encryption\Crypt::symmetricDecryptFileContent( $cryptedData['encrypted'], $decryptKey ); + $decryptData = Crypt::symmetricDecryptFileContent( $cryptedData['encrypted'], $decryptKey ); - $this->assertEqual( $this->data, $decryptData ); + $this->assertEquals( $this->data, $decryptData ); } @@ -186,7 +183,7 @@ class Test_Crypt extends UnitTestCase { // $encrypted=OC_Crypt::encrypt($source,$key); // $decrypted=OC_Crypt::decrypt($encrypted,$key); // $decrypted=rtrim($decrypted, "\0"); -// $this->assertNotEqual($encrypted,$source); +// $this->assertNotEquals($encrypted,$source); // $this->assertEqual($decrypted,$source); // // $chunk=substr($source,0,8192); @@ -198,14 +195,14 @@ class Test_Crypt extends UnitTestCase { // // $encrypted=OC_Crypt::blockEncrypt($source,$key); // $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); -// $this->assertNotEqual($encrypted,$source); +// $this->assertNotEquals($encrypted,$source); // $this->assertEqual($decrypted,$source); // // $tmpFileEncrypted=OCP\Files::tmpFile(); // OC_Crypt::encryptfile($file,$tmpFileEncrypted,$key); // $encrypted=file_get_contents($tmpFileEncrypted); // $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); -// $this->assertNotEqual($encrypted,$source); +// $this->assertNotEquals($encrypted,$source); // $this->assertEqual($decrypted,$source); // // $tmpFileDecrypted=OCP\Files::tmpFile(); From f11f524dfa17071dbabb2f950680966867f262a6 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 15 Aug 2012 18:49:53 +0100 Subject: [PATCH 060/315] working on streaming decrypted content applied some dependency injection to keymanager.php --- apps/files_encryption/hooks/hooks.php | 8 +++++++- apps/files_encryption/lib/keymanager.php | 10 +++++----- apps/files_encryption/lib/proxy.php | 14 ++++++++++---- apps/files_encryption/lib/util.php | 4 ++-- apps/files_encryption/tests/keymanager.php | 1 + 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index e23e3a09d4..b37c974b9c 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -39,6 +39,8 @@ class Hooks { if ( Crypt::mode( $params['uid'] ) == 'server' ) { + # TODO: use lots of dependency injection here + $view = new \OC_FilesystemView( '/' ); $util = new Util( $view, $params['uid'] ); @@ -49,8 +51,12 @@ class Hooks { } - $encryptedKey = Keymanager::getPrivateKey( $params['uid'] ); + \OC_FileProxy::$enabled = false; + + $encryptedKey = Keymanager::getPrivateKey( $params['uid'], $view ); + \OC_FileProxy::$enabled = true; + $_SESSION['enckey'] = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); } diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index ea6e4872d4..b06226397e 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -30,14 +30,14 @@ class Keymanager { # TODO: make all dependencies (including static classes) explicit, such as ocfsview objects, by adding them as method arguments (dependency injection) /** - * @brief retrieve private key from a user + * @brief retrieve the ENCRYPTED private key from a user * * @return string private key or false + * @note the key returned by this method must be decrypted before use */ - public static function getPrivateKey() { + public static function getPrivateKey( $user, $view ) { - $user = \OCP\User::getUser(); - $view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' ); + $view->chroot( '/' . $user . '/' . 'files_encryption' ); return $view->file_get_contents( '/' . $user.'.private.key' ); } @@ -121,7 +121,7 @@ class Keymanager { * @return string file key or false */ public static function getFileKey( $path ) { - trigger_error("div ".$path); + $keypath = ltrim( $path, '/' ); $user = \OCP\User::getUser(); diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 51ed889d12..5b0369bde9 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -135,6 +135,8 @@ class Proxy extends \OC_FileProxy { public function postFile_get_contents( $path, $data ) { + # TODO: Use dependency injection to add required args for view and user etc. to this method + if ( Crypt::mode() == 'server' && Crypt::isEncryptedContent( $data ) ) { $filePath = explode( '/', $path ); @@ -150,9 +152,7 @@ class Proxy extends \OC_FileProxy { $keyFile = Keymanager::getFileKey( $filePath ); - $privateKey = Keymanager::getPrivateKey(); - - $data = Crypt::keyDecryptKeyfile( $data, $keyFile, $privateKey ); + $data = Crypt::keyDecryptKeyfile( $data, $keyFile, $_SESSION['enckey'] ); \OC_FileProxy::$enabled = true; @@ -175,9 +175,15 @@ class Proxy extends \OC_FileProxy { // If file is encrypted, decrypt using crypto protocol if ( Crypt::mode() == 'server' && Crypt::isEncryptedContent( $path ) ) { + $keyFile = Keymanager::getFileKey( $filePath ); + + $tmp = tmpfile(); + + file_put_contents( $tmp, Crypt::keyDecryptKeyfile( $result, $keyFile, $_SESSION['enckey'] ) ); + fclose ( $result ); - $result = fopen( 'crypt://'.$path, $meta['mode'] ); + $result = fopen( $tmp ); } elseif ( self::shouldEncrypt( $path ) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 609f787124..b919c56a2e 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -222,9 +222,9 @@ class Util { } - public function encryptAll( OC_FilesystemView $view ) { + public function encryptAll( $directory ) { - $plainFiles = $this->findPlainFiles( $view ); + $plainFiles = $this->findFiles( $this->view, 'plain' ); if ( $this->encryptFiles( $plainFiles ) ) { diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php index 51b49c5da5..e0ce7a1d6a 100644 --- a/apps/files_encryption/tests/keymanager.php +++ b/apps/files_encryption/tests/keymanager.php @@ -43,6 +43,7 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase { $key = Keymanager::getPrivateKey( $this->user, $this->view ); + # TODO: replace call to Crypt with a mock object? $decrypted = Crypt::symmetricDecryptFileContent( $key, $this->passphrase ); $this->assertEquals( 1708, strlen( $decrypted ) ); From 293a0f4d3229ab6737b3625d7ceb0718ef6dea00 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Thu, 16 Aug 2012 19:18:18 +0100 Subject: [PATCH 061/315] Started rewrite of cryptstream class (renamed to stream) Added unit tests Fixed decryption of user private key at login Added functionality to keymanager --- apps/files_encryption/appinfo/app.php | 4 +- apps/files_encryption/lib/crypt.php | 41 ++++ apps/files_encryption/lib/cryptstream.php | 208 ----------------- apps/files_encryption/lib/keymanager.php | 9 +- apps/files_encryption/lib/stream.php | 264 ++++++++++++++++++++++ apps/files_encryption/lib/util.php | 2 +- apps/files_encryption/tests/crypt.php | 50 +++- 7 files changed, 361 insertions(+), 217 deletions(-) delete mode 100644 apps/files_encryption/lib/cryptstream.php create mode 100644 apps/files_encryption/lib/stream.php diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 4fd9c37ed3..dd95a1f094 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -4,7 +4,7 @@ OC::$CLASSPATH['OCA_Encryption\Crypt'] = 'apps/files_encryption/lib/crypt.php'; OC::$CLASSPATH['OCA_Encryption\Hooks'] = 'apps/files_encryption/hooks/hooks.php'; OC::$CLASSPATH['OCA_Encryption\Util'] = 'apps/files_encryption/lib/util.php'; OC::$CLASSPATH['OCA_Encryption\Keymanager'] = 'apps/files_encryption/lib/keymanager.php'; -OC::$CLASSPATH['OC_CryptStream'] = 'apps/files_encryption/lib/cryptstream.php'; +OC::$CLASSPATH['OCA_Encryption\Stream'] = 'apps/files_encryption/lib/stream.php'; OC::$CLASSPATH['OCA_Encryption\Proxy'] = 'apps/files_encryption/lib/proxy.php'; OC_FileProxy::register(new OCA_Encryption\Proxy()); @@ -12,7 +12,7 @@ OC_FileProxy::register(new OCA_Encryption\Proxy()); OCP\Util::connectHook('OC_User','post_login','OCA_Encryption\Hooks','login'); OCP\Util::connectHook('OC_Webdav_Properties', 'update', 'OCA_Encryption\Hooks', 'updateKeyfile'); -stream_wrapper_register('crypt','OC_CryptStream'); +stream_wrapper_register( 'crypt', 'OCA_Encryption\Stream'); if( !isset( $_SESSION['enckey'] ) && OCP\User::isLoggedIn() && OCA_Encryption\Crypt::mode() == 'server' ) { diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 07230fe8a2..fa7287a736 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -391,6 +391,47 @@ class Crypt { } + /** + * @brief Symmetrically encrypt a file by combining encrypted component data blocks + */ + public static function symmetricBlockEncryptFileContent( $plainContent, $key ) { + + $crypted = ''; + + while( strlen( $plainContent ) ) { + + // Encrypt a chunk of unencrypted data and add it to the rest + $crypted .= self::symmetricEncryptFileContent( substr( $plainContent, 0, 8192 ), $key ); + + // Remove the data already encrypted from remaining unencrypted data + $plainContent = substr( $plainContent, 8192 ); + + } + + return $crypted; + + } + + + /** + * @brief Symmetrically decrypt a file by combining encrypted component data blocks + */ + public static function symmetricBlockDecryptFileContent( $crypted, $key ) { + + $decrypted = ''; + + while( strlen( $crypted ) ) { + + $decrypted .= self::symmetricDecryptFileContent( substr( $crypted, 0, 8192 ), $key ); + + $crypted = substr( $crypted, 8192 ); + + } + + return rtrim( $decrypted, "\0" ); + + } + /** * @brief Generate a pseudo random 1024kb ASCII key * @returns $key Generated key diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php deleted file mode 100644 index 8c61c933cf..0000000000 --- a/apps/files_encryption/lib/cryptstream.php +++ /dev/null @@ -1,208 +0,0 @@ -. - * - */ - -/** - * transparently encrypted filestream - * - * you can use it as wrapper around an existing stream by setting OC_CryptStream::$sourceStreams['foo']=array('path'=>$path,'stream'=>$stream) - * and then fopen('crypt://streams/foo'); - */ - -class OC_CryptStream{ - public static $sourceStreams = array(); - private $source; - private $path; - private $readBuffer; // For streams that dont support seeking - private $meta = array(); // Header / meta for source stream - private $count; - private $writeCache; - private $size; - private static $rootView; - - public function stream_open($path, $mode, $options, &$opened_path){ - if(!self::$rootView){ - self::$rootView=new OC_FilesystemView(''); - } - $path=str_replace('crypt://','',$path); - if(dirname($path)=='streams' and isset(self::$sourceStreams[basename($path)])){ - $this->source=self::$sourceStreams[basename($path)]['stream']; - $this->path=self::$sourceStreams[basename($path)]['path']; - $this->size=self::$sourceStreams[basename($path)]['size']; - }else{ - $this->path=$path; - if($mode=='w' or $mode=='w+' or $mode=='wb' or $mode=='wb+'){ - $this->size=0; - }else{ - $this->size=self::$rootView->filesize($path,$mode); - } - OC_FileProxy::$enabled=false;//disable fileproxies so we can open the source file - $this->source=self::$rootView->fopen($path,$mode); - OC_FileProxy::$enabled=true; - if(!is_resource($this->source)){ - OCP\Util::writeLog('files_encryption','failed to open '.$path,OCP\Util::ERROR); - } - } - if(is_resource($this->source)){ - $this->meta=stream_get_meta_data($this->source); - } - return is_resource($this->source); - } - - public function stream_seek($offset, $whence=SEEK_SET){ - $this->flush(); - fseek($this->source,$offset,$whence); - } - - public function stream_tell(){ - return ftell($this->source); - } - - public function stream_read($count){ - //$count will always be 8192 https://bugs.php.net/bug.php?id=21641 - //This makes this function a lot simpler but will breake everything the moment it's fixed - $this->writeCache=''; - if($count!=8192){ - OCP\Util::writeLog('files_encryption','php bug 21641 no longer holds, decryption will not work',OCP\Util::FATAL); - die(); - } - $pos=ftell($this->source); - $data=fread($this->source,8192); - if(strlen($data)){ - $result=OC_Crypt::decrypt($data); - }else{ - $result=''; - } - $length=$this->size-$pos; - if($length<8192){ - $result=substr($result,0,$length); - } - return $result; - } - - public function stream_write( $data ){ - - $length = strlen( $data ); - - $written = 0; - - $currentPos = ftell( $this->source ); - - if( $this->writeCache ){ - - $data = $this->writeCache.$data; - - $this->writeCache = ''; - - } - - if( $currentPos%8192 != 0 ){ - - //make sure we always start on a block start - - fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); - - $encryptedBlock = fread( $this->source,8192 ); - - fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); - - $block = OC_Crypt::decrypt( $encryptedBlock ); - - $data = substr( $block,0,$currentPos%8192 ).$data; - - fseek( $this->source,-( $currentPos%8192 ),SEEK_CUR ); - - } - - $currentPos = ftell( $this->source ); - - while( $remainingLength = strlen( $data )>0 ){ - - if( $remainingLength<8192 ){ - - $this->writeCache = $data; - - $data = ''; - - }else{ - - $encrypted = OC_Crypt::encrypt( substr( $data,0,8192 ) ); - - fwrite( $this->source,$encrypted ); - - $data = substr( $data,8192 ); - - } - - } - - $this->size = max( $this->size,$currentPos+$length ); - - return $length; - - } - - - public function stream_set_option($option,$arg1,$arg2){ - switch($option){ - case STREAM_OPTION_BLOCKING: - stream_set_blocking($this->source,$arg1); - break; - case STREAM_OPTION_READ_TIMEOUT: - stream_set_timeout($this->source,$arg1,$arg2); - break; - case STREAM_OPTION_WRITE_BUFFER: - stream_set_write_buffer($this->source,$arg1,$arg2); - } - } - - public function stream_stat(){ - return fstat($this->source); - } - - public function stream_lock($mode){ - flock($this->source,$mode); - } - - public function stream_flush(){ - return fflush($this->source); - } - - public function stream_eof(){ - return feof($this->source); - } - - private function flush(){ - if($this->writeCache){ - $encrypted=OC_Crypt::encrypt($this->writeCache); - fwrite($this->source,$encrypted); - $this->writeCache=''; - } - } - - public function stream_close(){ - $this->flush(); - if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){ - OC_FileCache::put($this->path,array('encrypted'=>true,'size'=>$this->size),''); - } - return fclose($this->source); - } -} diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index b06226397e..26101b8356 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -120,10 +120,10 @@ class Keymanager { * @param string file name * @return string file key or false */ - public static function getFileKey( $path ) { + public static function getFileKey( $path, $staticUserClass = 'OCP\User' ) { $keypath = ltrim( $path, '/' ); - $user = \OCP\User::getUser(); + $user = $staticUserClass::getUser(); // update $keypath and $user if path point to a file shared by someone else $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); @@ -140,6 +140,7 @@ class Keymanager { } $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); + return $view->file_get_contents( $keypath . '.key' ); } @@ -227,9 +228,11 @@ class Keymanager { $path_parts = pathinfo( $targetpath ); if (!$view) { - $view = new \OC_FilesystemView( '/' . $user . '/files_encryption/keyfiles' ); + $view = new \OC_FilesystemView( '/' ); } + $view->chroot( '/' . $user . '/files_encryption/keyfiles' ); + if ( !$view->file_exists( $path_parts['dirname'] ) ) $view->mkdir( $path_parts['dirname'] ); return $view->file_put_contents( '/' . $targetpath . '.key', $key ); diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php new file mode 100644 index 0000000000..bdcfdfd73a --- /dev/null +++ b/apps/files_encryption/lib/stream.php @@ -0,0 +1,264 @@ +. + * + */ + +/** + * transparently encrypted filestream + * + * you can use it as wrapper around an existing stream by setting CryptStream::$sourceStreams['foo']=array('path'=>$path,'stream'=>$stream) + * and then fopen('crypt://streams/foo'); + */ + +namespace OCA_Encryption; + +class Stream { + + public static $sourceStreams = array(); + private $source; + private $path; + private $readBuffer; // For streams that dont support seeking + private $meta = array(); // Header / meta for source stream + private $count; + private $writeCache; + private $size; + private static $view; + + public function stream_open( $path, $mode, $options, &$opened_path ) { + + // Get access to filesystem via filesystemview object + if ( !self::$view ) { + + self::$view = new \OC_FilesystemView( '' ); + + } + + // Get the bare file path + $path = str_replace( 'crypt://', '', $path ); + + if ( + dirname( $path ) == 'streams' + and isset( self::$sourceStreams[basename( $path )] ) + ) { + + $this->source = self::$sourceStreams[basename( $path )]['stream']; + + $this->path = self::$sourceStreams[basename( $path )]['path']; + + $this->size = self::$sourceStreams[basename( $path )]['size']; + + } else { + + if ( + $mode == 'w' + or $mode == 'w+' + or $mode == 'wb' + or $mode == 'wb+' + ) { + + $this->size = 0; + + } else { + + $this->size = self::$view->filesize( $path, $mode ); + + } + + // Disable fileproxies so we can open the source file without recursive encryption + \OC_FileProxy::$enabled = false; + + $this->source = self::$view->fopen( $path, $mode ); + + \OC_FileProxy::$enabled = true; + + if ( !is_resource( $this->source ) ) { + + \OCP\Util::writeLog( 'files_encryption','failed to open '.$path,OCP\Util::ERROR ); + + } + + } + + if ( is_resource( $this->source ) ) { + + $this->meta = stream_get_meta_data( $this->source ); + + } + + return is_resource( $this->source ); + + } + + public function stream_seek($offset, $whence=SEEK_SET) { + $this->flush(); + fseek($this->source,$offset,$whence); + } + + public function stream_tell() { + return ftell($this->source); + } + + public function stream_read($count) { + //$count will always be 8192 https://bugs.php.net/bug.php?id=21641 + //This makes this function a lot simpler but will breake everything the moment it's fixed + $this->writeCache=''; + if ($count!=8192) { + OCP\Util::writeLog('files_encryption','php bug 21641 no longer holds, decryption will not work',OCP\Util::FATAL); + die(); + } + $pos=ftell($this->source); + $data=fread($this->source,8192); + if (strlen($data)) { + $result=Crypt::decrypt($data); + }else{ + $result=''; + } + $length=$this->size-$pos; + if ($length<8192) { + $result=substr($result,0,$length); + } + return $result; + } + + /** + * @brief + */ + public function stream_write( $data ) { + + $length = strlen( $data ); + + $written = 0; + + $currentPos = ftell( $this->source ); + + # TODO: Move this user call out of here - it belongs elsewhere + $user = \OCP\User::getUser(); + + if ( self::$view->file_exists( $this->path . $user ) ) { + + $key = Keymanager::getFileKey( $this->path . $user ); + + } else { + + $key = Crypt::generateKey(); + + Keymanager::setFileKey( $path, $key, new \OC_FilesystemView ); + + } + + if ( $this->writeCache ) { + + $data = $this->writeCache . $data; + + $this->writeCache = ''; + + } + + // Make sure we always start on a block start + if ( $currentPos % 8192 != 0 ) { + + fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); + + $encryptedBlock = fread( $this->source, 8192 ); + + fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); + + $block = Crypt::symmetricDecryptFileContent( $encryptedBlock, $key ); + + $data = substr( $block, 0, $currentPos % 8192 ) . $data; + + fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); + + } + + $currentPos = ftell( $this->source ); + + while( $remainingLength = strlen( $data )>0 ) { + + if ( $remainingLength<8192 ) { + + $this->writeCache = $data; + + $data = ''; + + } else { + + $encrypted = Crypt::symmetricBlockEncryptFileContent( $data, $key ); + + fwrite( $this->source . $user, $encrypted ); + + $data = substr( $data,8192 ); + + } + + } + + $this->size = max( $this->size, $currentPos + $length ); + + return $length; + + } + + + public function stream_set_option($option,$arg1,$arg2) { + switch($option) { + case STREAM_OPTION_BLOCKING: + stream_set_blocking($this->source,$arg1); + break; + case STREAM_OPTION_READ_TIMEOUT: + stream_set_timeout($this->source,$arg1,$arg2); + break; + case STREAM_OPTION_WRITE_BUFFER: + stream_set_write_buffer($this->source,$arg1,$arg2); + } + } + + public function stream_stat() { + return fstat($this->source); + } + + public function stream_lock($mode) { + flock($this->source,$mode); + } + + public function stream_flush() { + return fflush($this->source); + } + + public function stream_eof() { + return feof($this->source); + } + + private function flush() { + if ($this->writeCache) { + $encrypted=Crypt::encrypt($this->writeCache); + fwrite($this->source,$encrypted); + $this->writeCache=''; + } + } + + public function stream_close() { + $this->flush(); + if ($this->meta['mode']!='r' and $this->meta['mode']!='rb') { + OC_FileCache::put($this->path,array('encrypted'=>true,'size'=>$this->size),''); + } + return fclose($this->source); + } +} diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index b919c56a2e..eab5b5edf5 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -46,7 +46,7 @@ class Util { # DONE: add method to decrypt legacy encrypted data # DONE: fix / test the crypt stream proxy class - # TODO: replace cryptstream wrapper with stream_socket_enable_crypto, or fix it to use new crypt class methods + # TODO: replace cryptstream wrapper new AES based system # TODO: add support for optional recovery user in case of lost passphrase / keys # TODO: add admin optional required long passphrase for users # TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc. diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index 2802f32a58..ef453ab90d 100644 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -21,6 +21,8 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' ); $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' ); + //stream_wrapper_register( 'crypt', 'OCA_Encryption\Stream' ); + } function tearDown(){} @@ -73,16 +75,58 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { # TODO: search in keyfile for actual content as IV will ensure this test always passes - $keyfileContent = Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); + $crypted = Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); - $this->assertNotEquals( $this->data, $keyfileContent ); + $this->assertNotEquals( $this->data, $crypted ); - $decrypt = Crypt::symmetricDecryptFileContent( $keyfileContent, 'hat' ); + $decrypt = Crypt::symmetricDecryptFileContent( $crypted, 'hat' ); $this->assertEquals( $this->data, $decrypt ); } + + function testSymmetricBlockEncryptFileContent() { + + $crypted = Crypt::symmetricBlockEncryptFileContent( $this->data, 'hat' ); + + $this->assertNotEquals( $this->data, $crypted ); + + + $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, 'hat' ); + + $this->assertEquals( $this->data, $decrypt ); + + } + +// function testSymmetricBlockStreamEncryptFileContent() { +// +// $crypted = Crypt::symmetricBlockEncryptFileContent( $this->data, 'hat' ); +// +// $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $crypted ); +// +// // Test that data was successfully written +// $this->assertTrue( $cryptedFile ); +// +// $retreivedCryptedFile = file_get_contents( '/blockEncrypt' ); +// +// $this->assertNotEquals( $this->data, $retreivedCryptedFile ); +// +// } + + function testSymmetricBlockStreamDecryptFileContent() { + + \OC_User::setUserId( 'admin' ); + + $crypted = Crypt::symmetricBlockEncryptFileContent( $this->data, 'hat' ); + + $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $crypted ); + + $retreivedCryptedFile = file_get_contents( 'crypt://' . '/blockEncrypt' ); + + $this->assertEquals( $this->data, $retreivedCryptedFile ); + + } function testSymmetricEncryptFileContentKeyfile() { From 32ee3de9188a2373d5629ae2e00dcbe2cbe33e29 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Thu, 23 Aug 2012 16:43:10 +0100 Subject: [PATCH 062/315] Extensive work on crypto stream wrapper implementation --- apps/files_encryption/lib/crypt.php | 35 +++-- apps/files_encryption/lib/keymanager.php | 44 ++++--- apps/files_encryption/lib/stream.php | 115 +++++++++++----- apps/files_encryption/tests/crypt.php | 146 ++++++++++++++------- apps/files_encryption/tests/keymanager.php | 21 ++- 5 files changed, 261 insertions(+), 100 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index fa7287a736..25ba906deb 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -177,6 +177,14 @@ class Crypt { } + public static function concatIv ( $content, $iv ) { + + $combined = $content . '00iv00' . $iv; + + return $combined; + + } + /** * @brief Symmetrically encrypts a string and returns keyfile content * @param $plainContent content to be encrypted in keyfile @@ -197,7 +205,7 @@ class Crypt { if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { // Combine content to encrypt with IV identifier and actual IV - $combinedKeyfile = $encryptedContent . '00iv00' . $iv; + $combinedKeyfile = self::concatIv( $encryptedContent, $iv ); return $combinedKeyfile; @@ -398,13 +406,17 @@ class Crypt { $crypted = ''; - while( strlen( $plainContent ) ) { + $remaining = $plainContent; + + while( strlen( $remaining ) ) { // Encrypt a chunk of unencrypted data and add it to the rest - $crypted .= self::symmetricEncryptFileContent( substr( $plainContent, 0, 8192 ), $key ); + $block = self::symmetricEncryptFileContent( substr( $remaining, 0, 8192 ), $key ); + + $crypted .= $block; // Remove the data already encrypted from remaining unencrypted data - $plainContent = substr( $plainContent, 8192 ); + $remaining = substr( $remaining, 8192 ); } @@ -418,17 +430,24 @@ class Crypt { */ public static function symmetricBlockDecryptFileContent( $crypted, $key ) { + //echo "\n\n\nfags \$crypted = $crypted\n\n\n"; + $decrypted = ''; - while( strlen( $crypted ) ) { + $remaining = $crypted; - $decrypted .= self::symmetricDecryptFileContent( substr( $crypted, 0, 8192 ), $key ); + while( strlen( $remaining ) ) { + + // Encrypt a chunk of unencrypted data and add it to the rest + // 10946 is the length of a 8192 string once it has been encrypted + $decrypted .= self::symmetricDecryptFileContent( substr( $remaining, 0, 10946 ), $key ); - $crypted = substr( $crypted, 8192 ); + // Remove the data already encrypted from remaining unencrypted data + $remaining = substr( $remaining, 10946 ); } - return rtrim( $decrypted, "\0" ); + return $decrypted; } diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 26101b8356..525943f13d 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -197,45 +197,57 @@ class Keymanager { */ public static function setFileKey( $path, $key, $view = Null, $dbClassName = '\OC_DB') { - $targetpath = ltrim( $path, '/' ); + $targetPath = ltrim( $path, '/' ); $user = \OCP\User::getUser(); // update $keytarget and $user if key belongs to a file shared by someone else $query = $dbClassName::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); - $result = $query->execute( array ( '/'.$user.'/files/'.$targetpath, $user ) ); + $result = $query->execute( array ( '/'.$user.'/files/'.$targetPath, $user ) ); if ( $row = $result->fetchRow( ) ) { - $targetpath = $row['source']; + $targetPath = $row['source']; - $targetpath_parts=explode( '/',$targetpath ); + $targetPath_parts = explode( '/', $targetPath ); - $user = $targetpath_parts[1]; + $user = $targetPath_parts[1]; - $rootview = new \OC_FilesystemView( '/'); - if (!$rootview->is_writable($targetpath)) { - \OC_Log::write( 'Encryption library', "File Key not updated because you don't have write access for the corresponding file" , \OC_Log::ERROR ); - return false; - } + $rootview = new \OC_FilesystemView( '/' ); - $targetpath = str_replace( '/'.$user.'/files/', '', $targetpath ); + if ( ! $rootview->is_writable( $targetPath ) ) { + + \OC_Log::write( 'Encryption library', "File Key not updated because you don't have write access for the corresponding file", \OC_Log::ERROR ); + + return false; + + } + + $targetPath = str_replace( '/'.$user.'/files/', '', $targetPath ); //TODO: check for write permission on shared file once the new sharing API is in place } - $path_parts = pathinfo( $targetpath ); - - if (!$view) { + $path_parts = pathinfo( $targetPath ); + + if ( !$view ) { + $view = new \OC_FilesystemView( '/' ); + } $view->chroot( '/' . $user . '/files_encryption/keyfiles' ); - if ( !$view->file_exists( $path_parts['dirname'] ) ) $view->mkdir( $path_parts['dirname'] ); + // If the file resides within a subdirectory, create it + if ( ! $view->file_exists( $path_parts['dirname'] ) ) { - return $view->file_put_contents( '/' . $targetpath . '.key', $key ); + $view->mkdir( $path_parts['dirname'] ); + + } + + // Save the keyfile in parallel directory + return $view->file_put_contents( '/' . $targetPath . '.key', $key ); } diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index bdcfdfd73a..d1ab25a019 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -34,11 +34,13 @@ class Stream { public static $sourceStreams = array(); private $source; private $path; + private $rawPath; // The raw path received by stream_open private $readBuffer; // For streams that dont support seeking private $meta = array(); // Header / meta for source stream private $count; private $writeCache; private $size; + private $keyfile; private static $view; public function stream_open( $path, $mode, $options, &$opened_path ) { @@ -52,7 +54,9 @@ class Stream { // Get the bare file path $path = str_replace( 'crypt://', '', $path ); - + + $this->rawPath = $path; + if ( dirname( $path ) == 'streams' and isset( self::$sourceStreams[basename( $path )] ) @@ -115,33 +119,77 @@ class Stream { return ftell($this->source); } - public function stream_read($count) { - //$count will always be 8192 https://bugs.php.net/bug.php?id=21641 - //This makes this function a lot simpler but will breake everything the moment it's fixed - $this->writeCache=''; - if ($count!=8192) { - OCP\Util::writeLog('files_encryption','php bug 21641 no longer holds, decryption will not work',OCP\Util::FATAL); + public function stream_read( $count ) { + + $this->writeCache = ''; + + if ( $count != 8192 ) { + + // $count will always be 8192 https://bugs.php.net/bug.php?id=21641 + // This makes this function a lot simpler, but will break this class if the above 'bug' gets 'fixed' + \OCP\Util::writeLog( 'files_encryption', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', OCP\Util::FATAL ); + die(); + } - $pos=ftell($this->source); - $data=fread($this->source,8192); - if (strlen($data)) { - $result=Crypt::decrypt($data); - }else{ - $result=''; + + $pos = ftell( $this->source ); + + $data = fread( $this->source, 8192 ); + + if ( strlen( $data ) ) { + + $result = Crypt::symmetricDecryptFileContent( $data, $this->keyfile ); + + } else { + + $result = ''; + } - $length=$this->size-$pos; - if ($length<8192) { - $result=substr($result,0,$length); + + $length = $this->size - $pos; + + if ( $length < 8192 ) { + + $result = substr( $result, 0, $length ); + } + return $result; + + } + + /** + * @brief Get the keyfile for the current file, generate one if necessary + */ + public function getKey() { + + # TODO: Move this user call out of here - it belongs elsewhere + $user = \OCP\User::getUser(); + + if ( self::$view->file_exists( $this->rawPath . $user ) ) { + + // If the data is to be written to an existing file, fetch its keyfile + $this->keyfile = Keymanager::getFileKey( $this->rawPath . $user ); + + } else { + + // If the data is to be written to a new file, generate a new keyfile + $this->keyfile = Crypt::generateKey(); + + } + } /** * @brief */ public function stream_write( $data ) { - + + # TODO: Find a way to get path of file in order to know where to save its parallel keyfile + + \OC_FileProxy::$enabled = false; + $length = strlen( $data ); $written = 0; @@ -151,15 +199,13 @@ class Stream { # TODO: Move this user call out of here - it belongs elsewhere $user = \OCP\User::getUser(); - if ( self::$view->file_exists( $this->path . $user ) ) { + // Set keyfile property for file in question + $this->getKey(); - $key = Keymanager::getFileKey( $this->path . $user ); + if ( ! self::$view->file_exists( $this->rawPath . $user ) ) { - } else { - - $key = Crypt::generateKey(); - - Keymanager::setFileKey( $path, $key, new \OC_FilesystemView ); + // Save keyfile in parallel directory structure + Keymanager::setFileKey( $this->rawPath, $this->keyfile, new \OC_FilesystemView( '/' ) ); } @@ -180,7 +226,7 @@ class Stream { fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); - $block = Crypt::symmetricDecryptFileContent( $encryptedBlock, $key ); + $block = Crypt::symmetricDecryptFileContent( $encryptedBlock, $this->keyfile ); $data = substr( $block, 0, $currentPos % 8192 ) . $data; @@ -190,9 +236,9 @@ class Stream { $currentPos = ftell( $this->source ); - while( $remainingLength = strlen( $data )>0 ) { + while( $remainingLength = strlen( $data ) > 0 ) { - if ( $remainingLength<8192 ) { + if ( $remainingLength < 8192 ) { $this->writeCache = $data; @@ -200,9 +246,11 @@ class Stream { } else { - $encrypted = Crypt::symmetricBlockEncryptFileContent( $data, $key ); + $encrypted = Crypt::symmetricBlockEncryptFileContent( $data, $this->keyfile ); - fwrite( $this->source . $user, $encrypted ); + //$encrypted = $data; + + fwrite( $this->source, $encrypted ); $data = substr( $data,8192 ); @@ -255,10 +303,17 @@ class Stream { } public function stream_close() { + $this->flush(); + if ($this->meta['mode']!='r' and $this->meta['mode']!='rb') { - OC_FileCache::put($this->path,array('encrypted'=>true,'size'=>$this->size),''); + + \OC_FileCache::put($this->path,array('encrypted'=>true,'size'=>$this->size),''); + } + return fclose($this->source); + } + } diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index ef453ab90d..78f5f74fbf 100644 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -17,9 +17,13 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { function setUp() { // set content for encrypting / decrypting in tests - $this->data = realpath( dirname(__FILE__).'/../lib/crypt.php' ); + $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) ); + $this->dataShort = 'hats'; + $this->dataUrl = realpath( dirname(__FILE__).'/../lib/crypt.php' ); $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' ); $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' ); + + $this->view = new \OC_FilesystemView( '/' ); //stream_wrapper_register( 'crypt', 'OCA_Encryption\Stream' ); @@ -51,9 +55,9 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht - $crypted = Crypt::encrypt( $this->data, $iv, 'hat' ); + $crypted = Crypt::encrypt( $this->dataUrl, $iv, 'hat' ); - $this->assertNotEquals( $this->data, $crypted ); + $this->assertNotEquals( $this->dataUrl, $crypted ); } @@ -63,11 +67,11 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $iv = substr( base64_encode( $random ), 0, -4 ); // i.e. E5IG033j+mRNKrht - $crypted = Crypt::encrypt( $this->data, $iv, 'hat' ); + $crypted = Crypt::encrypt( $this->dataUrl, $iv, 'hat' ); $decrypt = Crypt::decrypt( $crypted, $iv, 'hat' ); - $this->assertEquals( $this->data, $decrypt ); + $this->assertEquals( $this->dataUrl, $decrypt ); } @@ -75,81 +79,133 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { # TODO: search in keyfile for actual content as IV will ensure this test always passes - $crypted = Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); + $crypted = Crypt::symmetricEncryptFileContent( $this->dataUrl, 'hat' ); - $this->assertNotEquals( $this->data, $crypted ); + $this->assertNotEquals( $this->dataUrl, $crypted ); $decrypt = Crypt::symmetricDecryptFileContent( $crypted, 'hat' ); - $this->assertEquals( $this->data, $decrypt ); + $this->assertEquals( $this->dataUrl, $decrypt ); } - function testSymmetricBlockEncryptFileContent() { + function testSymmetricBlockEncryptShortFileContent() { - $crypted = Crypt::symmetricBlockEncryptFileContent( $this->data, 'hat' ); - - $this->assertNotEquals( $this->data, $crypted ); + $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/sscceEncrypt-1345649062.key' ); + + $crypted = Crypt::symmetricBlockEncryptFileContent( $this->dataShort, $key ); + + $this->assertNotEquals( $this->dataShort, $crypted ); - $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, 'hat' ); + $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, $key ); - $this->assertEquals( $this->data, $decrypt ); + $this->assertEquals( $this->dataShort, $decrypt ); + + } + + function testSymmetricBlockEncryptLongFileContent() { + + $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/sscceEncrypt-1345649062.key' ); + + $crypted = Crypt::symmetricBlockEncryptFileContent( substr( $this->dataLong, 0, 6500 ), $key ); + + $this->assertNotEquals( $this->dataLong, $crypted ); + + //echo "\n\nCAT ".substr( $this->dataLong, 0, 7000 ); + + $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, $key ); + + $this->assertEquals( substr( $this->dataLong, 0, 6500 + + ), $decrypt ); } // function testSymmetricBlockStreamEncryptFileContent() { // -// $crypted = Crypt::symmetricBlockEncryptFileContent( $this->data, 'hat' ); +// \OC_User::setUserId( 'admin' ); // -// $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $crypted ); +// // Disable encryption proxy to prevent unwanted en/decryption +// \OC_FileProxy::$enabled = false; +// +// $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $this->dataUrl ); // // // Test that data was successfully written -// $this->assertTrue( $cryptedFile ); +// $this->assertTrue( is_int( $cryptedFile ) ); // -// $retreivedCryptedFile = file_get_contents( '/blockEncrypt' ); +// // Disable encryption proxy to prevent unwanted en/decryption +// \OC_FileProxy::$enabled = false; // -// $this->assertNotEquals( $this->data, $retreivedCryptedFile ); +// +// +// // Get file contents without using any wrapper to get it's actual contents on disk +// $retreivedCryptedFile = $this->view->file_get_contents( '/blockEncrypt' ); +// +// echo "\n\n\$retreivedCryptedFile = !! $retreivedCryptedFile !!"; +// +// $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/files_encryption/keyfiles/tmp/testSetFileKey.key' ); +// +// echo "\n\n\$key = !! $key !!"; +// +// $manualDecrypt = Crypt::symmetricDecryptFileContent( $retreivedCryptedFile, $key ); +// +// echo "\n\n\$manualDecrypt = !! $manualDecrypt !!"; +// +// // Check that the file was encrypted before being written to disk +// $this->assertNotEquals( $this->dataUrl, $retreivedCryptedFile ); +// +// $decrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key); +// +// $this->assertEquals( $this->dataUrl, $decrypt ); // // } - function testSymmetricBlockStreamDecryptFileContent() { - - \OC_User::setUserId( 'admin' ); - - $crypted = Crypt::symmetricBlockEncryptFileContent( $this->data, 'hat' ); - - $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $crypted ); - - $retreivedCryptedFile = file_get_contents( 'crypt://' . '/blockEncrypt' ); - - $this->assertEquals( $this->data, $retreivedCryptedFile ); - - } +// function testSymmetricBlockStreamDecryptFileContent() { +// +// \OC_User::setUserId( 'admin' ); +// +// // Disable encryption proxy to prevent unwanted en/decryption +// \OC_FileProxy::$enabled = false; +// +// $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $this->dataUrl ); +// +// // Disable encryption proxy to prevent unwanted en/decryption +// \OC_FileProxy::$enabled = false; +// +// echo "\n\n\$cryptedFile = " . $this->view->file_get_contents( '/blockEncrypt' ); +// +// $retreivedCryptedFile = file_get_contents( 'crypt://' . '/blockEncrypt' ); +// +// $this->assertEquals( $this->dataUrl, $retreivedCryptedFile ); +// +// \OC_FileProxy::$enabled = false; +// +// } function testSymmetricEncryptFileContentKeyfile() { # TODO: search in keyfile for actual content as IV will ensure this test always passes - $crypted = Crypt::symmetricEncryptFileContentKeyfile( $this->data ); + $crypted = Crypt::symmetricEncryptFileContentKeyfile( $this->dataUrl ); - $this->assertNotEquals( $this->data, $crypted['encrypted'] ); + $this->assertNotEquals( $this->dataUrl, $crypted['encrypted'] ); $decrypt = Crypt::symmetricDecryptFileContent( $crypted['encrypted'], $crypted['key'] ); - $this->assertEquals( $this->data, $decrypt ); + $this->assertEquals( $this->dataUrl, $decrypt ); } function testIsEncryptedContent() { - $this->assertFalse( Crypt::isEncryptedContent( $this->data ) ); + $this->assertFalse( Crypt::isEncryptedContent( $this->dataUrl ) ); $this->assertFalse( Crypt::isEncryptedContent( $this->legacyEncryptedData ) ); - $keyfileContent = Crypt::symmetricEncryptFileContent( $this->data, 'hat' ); + $keyfileContent = Crypt::symmetricEncryptFileContent( $this->dataUrl, 'hat' ); $this->assertTrue( Crypt::isEncryptedContent( $keyfileContent ) ); @@ -168,14 +224,14 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $this->assertTrue( strlen( $pair1['privateKey'] ) > 1 ); - $crypted = Crypt::multiKeyEncrypt( $this->data, array( $pair1['publicKey'] ) ); + $crypted = Crypt::multiKeyEncrypt( $this->dataUrl, array( $pair1['publicKey'] ) ); - $this->assertNotEquals( $this->data, $crypted['encrypted'] ); + $this->assertNotEquals( $this->dataUrl, $crypted['encrypted'] ); $decrypt = Crypt::multiKeyDecrypt( $crypted['encrypted'], $crypted['keys'][0], $pair1['privateKey'] ); - $this->assertEquals( $this->data, $decrypt ); + $this->assertEquals( $this->dataUrl, $decrypt ); } @@ -185,14 +241,14 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $pair1 = Crypt::createKeypair(); // Encrypt data - $crypted = Crypt::keyEncrypt( $this->data, $pair1['publicKey'] ); + $crypted = Crypt::keyEncrypt( $this->dataUrl, $pair1['publicKey'] ); - $this->assertNotEquals( $this->data, $crypted ); + $this->assertNotEquals( $this->dataUrl, $crypted ); // Decrypt data $decrypt = Crypt::keyDecrypt( $crypted, $pair1['privateKey'] ); - $this->assertEquals( $this->data, $decrypt ); + $this->assertEquals( $this->dataUrl, $decrypt ); } @@ -204,7 +260,7 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $pair1 = Crypt::createKeypair(); // Encrypt plain data, generate keyfile & encrypted file - $cryptedData = Crypt::symmetricEncryptFileContentKeyfile( $this->data ); + $cryptedData = Crypt::symmetricEncryptFileContentKeyfile( $this->dataUrl ); // Encrypt keyfile $cryptedKey = Crypt::keyEncrypt( $cryptedData['key'], $pair1['publicKey'] ); @@ -215,7 +271,7 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { // Decrypt encrypted file $decryptData = Crypt::symmetricDecryptFileContent( $cryptedData['encrypted'], $decryptKey ); - $this->assertEquals( $this->data, $decryptData ); + $this->assertEquals( $this->dataUrl, $decryptData ); } diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php index e0ce7a1d6a..a6b425bafa 100644 --- a/apps/files_encryption/tests/keymanager.php +++ b/apps/files_encryption/tests/keymanager.php @@ -15,7 +15,8 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase { function setUp() { - // set content for encrypting / decrypting in tests + // Set data for use in tests + $this->data = realpath( dirname(__FILE__).'/../lib/crypt.php' ); $this->user = 'admin'; $this->passphrase = 'admin'; $this->view = new \OC_FilesystemView( '' ); @@ -39,6 +40,22 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase { } + function testSetFileKey() { + + # NOTE: This cannot be tested until we are able to break out of the FileSystemView data directory root + +// $key = Crypt::symmetricEncryptFileContentKeyfile( $this->data, 'hat' ); +// +// $tmpPath = sys_get_temp_dir(). '/' . 'testSetFileKey'; +// +// $view = new \OC_FilesystemView( '/tmp/' ); +// +// //$view = new \OC_FilesystemView( '/' . $this->user . '/files_encryption/keyfiles' ); +// +// Keymanager::setFileKey( $tmpPath, $key['key'], $view ); + + } + function testGetDecryptedPrivateKey() { $key = Keymanager::getPrivateKey( $this->user, $this->view ); @@ -52,4 +69,6 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase { } + + } From e3ac15bad34697d1d2f797a4d6341e5ad6db3464 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Thu, 23 Aug 2012 19:19:39 +0100 Subject: [PATCH 063/315] development snapshot --- apps/files_encryption/lib/crypt.php | 24 ++++++- apps/files_encryption/lib/stream.php | 87 +++++++++++++------------ apps/files_encryption/tests/crypt.php | 94 +++++++++++++++------------ 3 files changed, 121 insertions(+), 84 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 25ba906deb..f1e747f111 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -161,7 +161,7 @@ class Crypt { * @returns decrypted file */ public static function decrypt( $encryptedContent, $iv, $passphrase ) { - + echo "\n\nJET \$passphrase = $passphrase , \$iv = $iv\n\n"; if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { return $plainContent; @@ -408,18 +408,30 @@ class Crypt { $remaining = $plainContent; + $testarray = array(); + while( strlen( $remaining ) ) { + //echo "\n\n\$block = ".substr( $remaining, 0, 8192 ); + // Encrypt a chunk of unencrypted data and add it to the rest $block = self::symmetricEncryptFileContent( substr( $remaining, 0, 8192 ), $key ); $crypted .= $block; + $testarray[] = $block; + // Remove the data already encrypted from remaining unencrypted data $remaining = substr( $remaining, 8192 ); } + //echo "hags "; + + //echo "\n\n\n\$crypted = $crypted\n\n\n"; + + //print_r($testarray); + return $crypted; } @@ -430,13 +442,17 @@ class Crypt { */ public static function symmetricBlockDecryptFileContent( $crypted, $key ) { - //echo "\n\n\nfags \$crypted = $crypted\n\n\n"; + echo "\n\n\nfags \$crypted = $crypted\n\n\n"; $decrypted = ''; $remaining = $crypted; + $testarray = array(); + while( strlen( $remaining ) ) { + + $testarray[] = substr( $remaining, 0, 10946 ); // Encrypt a chunk of unencrypted data and add it to the rest // 10946 is the length of a 8192 string once it has been encrypted @@ -447,6 +463,10 @@ class Crypt { } + echo "nags "; + + print_r($testarray); + return $decrypted; } diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index d1ab25a019..4fa266ce8c 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -182,7 +182,7 @@ class Stream { } /** - * @brief + * @brief Write write plan data as encrypted data */ public function stream_write( $data ) { @@ -208,55 +208,60 @@ class Stream { Keymanager::setFileKey( $this->rawPath, $this->keyfile, new \OC_FilesystemView( '/' ) ); } - - if ( $this->writeCache ) { - - $data = $this->writeCache . $data; - - $this->writeCache = ''; - - } - // Make sure we always start on a block start - if ( $currentPos % 8192 != 0 ) { - - fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); - - $encryptedBlock = fread( $this->source, 8192 ); - - fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); - - $block = Crypt::symmetricDecryptFileContent( $encryptedBlock, $this->keyfile ); - - $data = substr( $block, 0, $currentPos % 8192 ) . $data; - - fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); - - } - - $currentPos = ftell( $this->source ); - - while( $remainingLength = strlen( $data ) > 0 ) { - - if ( $remainingLength < 8192 ) { - - $this->writeCache = $data; - - $data = ''; - - } else { +// // Set $data to contents of writeCache +// // Concat writeCache to start of $data +// if ( $this->writeCache ) { +// +// $data = $this->writeCache . $data; +// +// $this->writeCache = ''; +// +// } + +// // Make sure we always start on a block start +// if ( 0 != ( $currentPos % 8192 ) ) { // If we're not at the end of file yet (in the final chunk), if there will be no bytes left to read after the current chunk +// +// fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); +// +// $encryptedBlock = fread( $this->source, 8192 ); +// +// fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); +// +// $block = Crypt::symmetricDecryptFileContent( $encryptedBlock, $this->keyfile ); +// +// $x = substr( $block, 0, $currentPos % 8192 ); +// +// $data = $x . $data; +// +// fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); +// +// } +// $currentPos = ftell( $this->source ); +// +// while( $remainingLength = strlen( $data ) > 0 ) { +// +// // Set writeCache to contents of $data +// if ( $remainingLength < 8192 ) { +// +// $this->writeCache = $data; +// +// $data = ''; +// +// } else { + $encrypted = Crypt::symmetricBlockEncryptFileContent( $data, $this->keyfile ); //$encrypted = $data; fwrite( $this->source, $encrypted ); - $data = substr( $data,8192 ); + $data = substr( $data, 8192 ); - } - - } +// } +// +// } $this->size = max( $this->size, $currentPos + $length ); diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index 78f5f74fbf..8be1565a43 100644 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -25,8 +25,6 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $this->view = new \OC_FilesystemView( '/' ); - //stream_wrapper_register( 'crypt', 'OCA_Encryption\Stream' ); - } function tearDown(){} @@ -109,58 +107,72 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/sscceEncrypt-1345649062.key' ); - $crypted = Crypt::symmetricBlockEncryptFileContent( substr( $this->dataLong, 0, 6500 ), $key ); + $crypted = Crypt::symmetricBlockEncryptFileContent( $this->dataLong, $key ); $this->assertNotEquals( $this->dataLong, $crypted ); - //echo "\n\nCAT ".substr( $this->dataLong, 0, 7000 ); $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, $key ); - $this->assertEquals( substr( $this->dataLong, 0, 6500 - - ), $decrypt ); + $this->assertEquals( $this->dataLong, $decrypt ); } -// function testSymmetricBlockStreamEncryptFileContent() { -// -// \OC_User::setUserId( 'admin' ); -// -// // Disable encryption proxy to prevent unwanted en/decryption -// \OC_FileProxy::$enabled = false; -// -// $cryptedFile = file_put_contents( 'crypt://' . '/blockEncrypt', $this->dataUrl ); -// -// // Test that data was successfully written -// $this->assertTrue( is_int( $cryptedFile ) ); -// -// // Disable encryption proxy to prevent unwanted en/decryption -// \OC_FileProxy::$enabled = false; -// -// -// -// // Get file contents without using any wrapper to get it's actual contents on disk -// $retreivedCryptedFile = $this->view->file_get_contents( '/blockEncrypt' ); -// -// echo "\n\n\$retreivedCryptedFile = !! $retreivedCryptedFile !!"; -// -// $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/files_encryption/keyfiles/tmp/testSetFileKey.key' ); -// -// echo "\n\n\$key = !! $key !!"; -// -// $manualDecrypt = Crypt::symmetricDecryptFileContent( $retreivedCryptedFile, $key ); -// -// echo "\n\n\$manualDecrypt = !! $manualDecrypt !!"; -// + function testSymmetricStreamEncryptShortFileContent() { + + \OC_User::setUserId( 'admin' ); + + $filename = 'flockEncrypt'; + + $cryptedFile = file_put_contents( 'crypt://' . '/' . $filename, $this->dataShort ); + + // Test that data was successfully written + $this->assertTrue( is_int( $cryptedFile ) ); + + + // Get file contents without using any wrapper to get it's actual contents on disk + $retreivedCryptedFile = $this->view->file_get_contents( '/'. $filename ); + + // Check that the file was encrypted before being written to disk + $this->assertNotEquals( $this->dataShort, $retreivedCryptedFile ); + + + $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/' . $filename . '.key' ); + + $manualDecrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key ); + + $this->assertEquals( $this->dataShort, $manualDecrypt ); + + } + + function testSymmetricStreamEncryptLongFileContent() { + + \OC_User::setUserId( 'admin' ); + + $filename = 'clockEncrypt'; + + $cryptedFile = file_put_contents( 'crypt://' . '/' . $filename, $this->dataLong ); + + // Test that data was successfully written + $this->assertTrue( is_int( $cryptedFile ) ); + + + // Get file contents without using any wrapper to get it's actual contents on disk + $retreivedCryptedFile = $this->view->file_get_contents( '/'. $filename ); + + echo "\n\nsock $retreivedCryptedFile\n\n"; + // // Check that the file was encrypted before being written to disk -// $this->assertNotEquals( $this->dataUrl, $retreivedCryptedFile ); +// $this->assertNotEquals( $this->dataLong, $retreivedCryptedFile ); // -// $decrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key); // -// $this->assertEquals( $this->dataUrl, $decrypt ); +// $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/' . $filename . '.key' ); // -// } +// $manualDecrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key ); +// +// $this->assertEquals( $this->dataLong, $manualDecrypt ); + + } // function testSymmetricBlockStreamDecryptFileContent() { // From 2e796b563fc534802e9278a969761c1ef9fde86e Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 27 Aug 2012 17:51:02 +0200 Subject: [PATCH 064/315] urldecode private- and public-key --- lib/ocs.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ocs.php b/lib/ocs.php index 423e1752da..1b9207feaa 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -193,8 +193,8 @@ class OC_OCS { //keysetuser }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='cloud') and ($ex[$paracount-2] == 'userkeys')){ - $privatekey = self::readData('post', 'privatekey', 'string'); - $publickey = self::readData('post', 'publickey', 'string'); + $privatekey = urldecode(self::readData('post', 'privatekey', 'string')); + $publickey = urldecode(self::readData('post', 'publickey', 'string')); OC_OCS::userKeysSet($format, $privatekey, $publickey); // keygetfiles From ed980674a6a225c30f747e8b8e8952ac182dcbae Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 11 Sep 2012 13:40:45 +0100 Subject: [PATCH 065/315] Development snapshot --- apps/files_encryption/hooks/hooks.php | 2 + apps/files_encryption/lib/crypt.php | 2 +- apps/files_encryption/lib/stream.php | 207 ++++++++++++++++--------- apps/files_encryption/tests/crypt.php | 31 ++-- apps/files_encryption/tests/stream.php | 142 +++++++++++++++++ 5 files changed, 301 insertions(+), 83 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index b37c974b9c..71b1b06080 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -57,6 +57,8 @@ class Hooks { \OC_FileProxy::$enabled = true; + # TODO: dont manually encrypt the private keyfile - use the config options of openssl_pkey_export instead for better mobile compatibility + $_SESSION['enckey'] = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); } diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index f1e747f111..bf5e1ab64f 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -161,7 +161,7 @@ class Crypt { * @returns decrypted file */ public static function decrypt( $encryptedContent, $iv, $passphrase ) { - echo "\n\nJET \$passphrase = $passphrase , \$iv = $iv\n\n"; + if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { return $plainContent; diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 4fa266ce8c..81346b8be3 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -32,14 +32,16 @@ namespace OCA_Encryption; class Stream { public static $sourceStreams = array(); - private $source; + + # TODO: make all below properties private again once unit testing is configured correctly + public $rawPath; // The raw path received by stream_open + private $handle; // Resource returned by fopen private $path; - private $rawPath; // The raw path received by stream_open private $readBuffer; // For streams that dont support seeking private $meta = array(); // Header / meta for source stream private $count; private $writeCache; - private $size; + public $size; private $keyfile; private static $view; @@ -61,8 +63,10 @@ class Stream { dirname( $path ) == 'streams' and isset( self::$sourceStreams[basename( $path )] ) ) { + + // Is this just for unit testing purposes? - $this->source = self::$sourceStreams[basename( $path )]['stream']; + $this->handle = self::$sourceStreams[basename( $path )]['stream']; $this->path = self::$sourceStreams[basename( $path )]['path']; @@ -81,18 +85,22 @@ class Stream { } else { - $this->size = self::$view->filesize( $path, $mode ); + //$this->size = self::$view->filesize( $path, $mode ); + $this->size = filesize( $path ); + } // Disable fileproxies so we can open the source file without recursive encryption \OC_FileProxy::$enabled = false; - $this->source = self::$view->fopen( $path, $mode ); + $this->handle = fopen( $path, $mode ); + + //$this->handle = self::$view->fopen( $path, $mode ); \OC_FileProxy::$enabled = true; - if ( !is_resource( $this->source ) ) { + if ( !is_resource( $this->handle ) ) { \OCP\Util::writeLog( 'files_encryption','failed to open '.$path,OCP\Util::ERROR ); @@ -100,27 +108,30 @@ class Stream { } - if ( is_resource( $this->source ) ) { + if ( is_resource( $this->handle ) ) { - $this->meta = stream_get_meta_data( $this->source ); + $this->meta = stream_get_meta_data( $this->handle ); } - return is_resource( $this->source ); + return is_resource( $this->handle ); } - public function stream_seek($offset, $whence=SEEK_SET) { + public function stream_seek( $offset, $whence = SEEK_SET ) { + $this->flush(); - fseek($this->source,$offset,$whence); + + fseek( $this->handle, $offset, $whence ); + } public function stream_tell() { - return ftell($this->source); + return ftell($this->handle); } public function stream_read( $count ) { - + $this->writeCache = ''; if ( $count != 8192 ) { @@ -133,27 +144,49 @@ class Stream { } - $pos = ftell( $this->source ); - - $data = fread( $this->source, 8192 ); - - if ( strlen( $data ) ) { +// $pos = ftell( $this->handle ); +// + $data = fread( $this->handle, 8192 ); + + //echo "\n\nPRE DECRYPTION = $data\n\n"; +// +// if ( strlen( $data ) ) { + + $this->getKey(); + + echo "\n\nGROWL {$this->keyfile}\n\n"; + + $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/tmp-1346255589.key' ); $result = Crypt::symmetricDecryptFileContent( $data, $this->keyfile ); + + echo "\n\n\n\n-----------------------------\n\nNEWS"; + + echo "\n\n\$data = $data"; + + echo "\n\n\$key = $key"; + + echo "\n\n\$result = $result"; + + echo "\n\n\n\n-----------------------------\n\n"; + + //trigger_error("CAT $result"); - } else { + + +// } else { +// +// $result = ''; +// +// } - $result = ''; - - } - - $length = $this->size - $pos; - - if ( $length < 8192 ) { - - $result = substr( $result, 0, $length ); - - } +// $length = $this->size - $pos; +// +// if ( $length < 8192 ) { +// +// $result = substr( $result, 0, $length ); +// +// } return $result; @@ -161,40 +194,45 @@ class Stream { /** * @brief Get the keyfile for the current file, generate one if necessary + * @param bool $generate if true, a new key will be generated if none can be found */ - public function getKey() { + public function getKey( $generate = true ) { # TODO: Move this user call out of here - it belongs elsewhere $user = \OCP\User::getUser(); - if ( self::$view->file_exists( $this->rawPath . $user ) ) { - + if ( self::$view->file_exists( $this->rawPath ) ) { + + # TODO: add error handling for when file exists but no keyfile + // If the data is to be written to an existing file, fetch its keyfile - $this->keyfile = Keymanager::getFileKey( $this->rawPath . $user ); + $this->keyfile = Keymanager::getFileKey( $this->rawPath ); } else { - // If the data is to be written to a new file, generate a new keyfile - $this->keyfile = Crypt::generateKey(); + if ( $generate ) { + + // If the data is to be written to a new file, generate a new keyfile + $this->keyfile = Crypt::generateKey(); + + } } } /** - * @brief Write write plan data as encrypted data + * @brief Take plain data destined to be written, encrypt it, and write it block by block */ public function stream_write( $data ) { - # TODO: Find a way to get path of file in order to know where to save its parallel keyfile - \OC_FileProxy::$enabled = false; $length = strlen( $data ); $written = 0; - $currentPos = ftell( $this->source ); + $currentPos = ftell( $this->handle ); # TODO: Move this user call out of here - it belongs elsewhere $user = \OCP\User::getUser(); @@ -208,25 +246,27 @@ class Stream { Keymanager::setFileKey( $this->rawPath, $this->keyfile, new \OC_FilesystemView( '/' ) ); } - -// // Set $data to contents of writeCache -// // Concat writeCache to start of $data + +// // If data exists in the writeCache // if ( $this->writeCache ) { -// +// +// trigger_error("write cache is set"); +// +// // Concat writeCache to start of $data // $data = $this->writeCache . $data; // // $this->writeCache = ''; // // } - +// // // Make sure we always start on a block start // if ( 0 != ( $currentPos % 8192 ) ) { // If we're not at the end of file yet (in the final chunk), if there will be no bytes left to read after the current chunk // -// fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); +// fseek( $this->handle, - ( $currentPos % 8192 ), SEEK_CUR ); // -// $encryptedBlock = fread( $this->source, 8192 ); +// $encryptedBlock = fread( $this->handle, 8192 ); // -// fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); +// fseek( $this->handle, - ( $currentPos % 8192 ), SEEK_CUR ); // // $block = Crypt::symmetricDecryptFileContent( $encryptedBlock, $this->keyfile ); // @@ -234,28 +274,36 @@ class Stream { // // $data = $x . $data; // -// fseek( $this->source, - ( $currentPos % 8192 ), SEEK_CUR ); +// fseek( $this->handle, - ( $currentPos % 8192 ), SEEK_CUR ); // // } - -// $currentPos = ftell( $this->source ); -// -// while( $remainingLength = strlen( $data ) > 0 ) { -// -// // Set writeCache to contents of $data +/* + $currentPos = ftell( $this->handle );*/ + +// // While there still remains somed data to be written +// while( strlen( $data ) > 0 ) { +// +// $remainingLength = strlen( $data ); +// +// // If data remaining to be written is less than the size of 1 block // if ( $remainingLength < 8192 ) { -// +// +// //trigger_error("remaining length < 8192"); +// +// // Set writeCache to contents of $data // $this->writeCache = $data; // // $data = ''; // // } else { - $encrypted = Crypt::symmetricBlockEncryptFileContent( $data, $this->keyfile ); + $encrypted = Crypt::symmetricEncryptFileContent( $data, $this->keyfile ); - //$encrypted = $data; + file_put_contents('/home/samtuke/tmp.txt', $encrypted); - fwrite( $this->source, $encrypted ); + //echo "\n\nFRESHLY ENCRYPTED = $encrypted\n\n"; + + fwrite( $this->handle, $encrypted ); $data = substr( $data, 8192 ); @@ -273,38 +321,53 @@ class Stream { public function stream_set_option($option,$arg1,$arg2) { switch($option) { case STREAM_OPTION_BLOCKING: - stream_set_blocking($this->source,$arg1); + stream_set_blocking($this->handle,$arg1); break; case STREAM_OPTION_READ_TIMEOUT: - stream_set_timeout($this->source,$arg1,$arg2); + stream_set_timeout($this->handle,$arg1,$arg2); break; case STREAM_OPTION_WRITE_BUFFER: - stream_set_write_buffer($this->source,$arg1,$arg2); + stream_set_write_buffer($this->handle,$arg1,$arg2); } } public function stream_stat() { - return fstat($this->source); + return fstat($this->handle); } public function stream_lock($mode) { - flock($this->source,$mode); + flock($this->handle,$mode); } public function stream_flush() { - return fflush($this->source); + + return fflush($this->handle); // Not a typo: http://php.net/manual/en/function.fflush.php + } public function stream_eof() { - return feof($this->source); + return feof($this->handle); } private function flush() { - if ($this->writeCache) { - $encrypted=Crypt::encrypt($this->writeCache); - fwrite($this->source,$encrypted); - $this->writeCache=''; + + if ( $this->writeCache ) { + + // Set keyfile property for file in question + $this->getKey(); + + //echo "\n\nFLUSH = {$this->writeCache}\n\n"; + + $encrypted = Crypt::symmetricBlockEncryptFileContent( $this->writeCache, $this->keyfile ); + + //echo "\n\nENCFLUSH = $encrypted\n\n"; + + fwrite( $this->handle, $encrypted ); + + $this->writeCache = ''; + } + } public function stream_close() { @@ -317,7 +380,7 @@ class Stream { } - return fclose($this->source); + return fclose($this->handle); } diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index 8be1565a43..81d262460b 100644 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -24,6 +24,8 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' ); $this->view = new \OC_FilesystemView( '/' ); + + \OC_User::setUserId( 'admin' ); } @@ -146,29 +148,38 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { } function testSymmetricStreamEncryptLongFileContent() { - - \OC_User::setUserId( 'admin' ); - $filename = 'clockEncrypt'; + $filename = 'tmp-'.time(); - $cryptedFile = file_put_contents( 'crypt://' . '/' . $filename, $this->dataLong ); + echo "\n\n\$filename = $filename\n\n"; + + $cryptedFile = file_put_contents( 'crypt://' . '/' . '/home/samtuke/owncloud/git/oc3/data/' . $filename, $this->dataLong.$this->dataLong ); // Test that data was successfully written $this->assertTrue( is_int( $cryptedFile ) ); // Get file contents without using any wrapper to get it's actual contents on disk - $retreivedCryptedFile = $this->view->file_get_contents( '/'. $filename ); + $retreivedCryptedFile = $this->view->file_get_contents( '/' . $filename ); + + //echo "\n\nsock $retreivedCryptedFile\n\n"; + + // Check that the file was encrypted before being written to disk + $this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile ); + + $autoDecrypted = file_get_contents( 'crypt:////home/samtuke/owncloud/git/oc3/data/' . $filename ); + + //file_get_contents('crypt:///home/samtuke/tmp-1346255589'); + + $this->assertEquals( $this->dataLong.$this->dataLong, $autoDecrypted ); - echo "\n\nsock $retreivedCryptedFile\n\n"; -// // Check that the file was encrypted before being written to disk -// $this->assertNotEquals( $this->dataLong, $retreivedCryptedFile ); -// -// // $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/' . $filename . '.key' ); // // $manualDecrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key ); +// +// echo "\n\n\n\n\n\n\n\n\n\n\$manualDecrypt = $manualDecrypt\n\n"; + // // $this->assertEquals( $this->dataLong, $manualDecrypt ); diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php index 4c78b2d7b0..0f65e49f9e 100644 --- a/apps/files_encryption/tests/stream.php +++ b/apps/files_encryption/tests/stream.php @@ -5,6 +5,148 @@ * later. * See the COPYING-README file. */ + +namespace OCA_Encryption; + +require_once "PHPUnit/Framework/TestCase.php"; +require_once realpath( dirname(__FILE__).'/../../../lib/base.php' ); + +class Test_Stream extends \PHPUnit_Framework_TestCase { + + function setUp() { + + $this->empty = ''; + + $this->stream = new Stream(); + + $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) ); + $this->dataShort = 'hats'; + + $this->emptyTmpFilePath = \OCP\Files::tmpFile(); + + $this->dataTmpFilePath = \OCP\Files::tmpFile(); + + file_put_contents( $this->dataTmpFilePath, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est." ); + + } + + function testStreamOpen() { + + $stream1 = new Stream(); + + $handle1 = $stream1->stream_open( $this->emptyTmpFilePath, 'wb', array(), $this->empty ); + + // Test that resource was returned successfully + $this->assertTrue( $handle1 ); + + // Test that file has correct size + $this->assertEquals( 0, $stream1->size ); + + // Test that path is correct + $this->assertEquals( $this->emptyTmpFilePath, $stream1->rawPath ); + + $stream2 = new Stream(); + + $handle2 = $stream2->stream_open( 'crypt://' . $this->emptyTmpFilePath, 'wb', array(), $this->empty ); + + // Test that protocol identifier is removed from path + $this->assertEquals( $this->emptyTmpFilePath, $stream2->rawPath ); + + // "Stat failed error" prevents this test from executing +// $stream3 = new Stream(); +// +// $handle3 = $stream3->stream_open( $this->dataTmpFilePath, 'r', array(), $this->empty ); +// +// $this->assertEquals( 0, $stream3->size ); + + } + + function testStreamWrite() { + + $stream1 = new Stream(); + + $handle1 = $stream1->stream_open( $this->emptyTmpFilePath, 'r+b', array(), $this->empty ); + + # what about the keymanager? there is no key for the newly created temporary file! + + $stream1->stream_write( $this->dataShort ); + + } + +// function getStream( $id, $mode, $size ) { +// +// if ( $id === '' ) { +// +// $id = uniqid(); +// } +// +// +// if ( !isset( $this->tmpFiles[$id] ) ) { +// +// // If tempfile with given name does not already exist, create it +// +// $file = OCP\Files::tmpFile(); +// +// $this->tmpFiles[$id] = $file; +// +// } else { +// +// $file = $this->tmpFiles[$id]; +// +// } +// +// $stream = fopen( $file, $mode ); +// +// Stream::$sourceStreams[$id] = array( 'path' => 'dummy' . $id, 'stream' => $stream, 'size' => $size ); +// +// return fopen( 'crypt://streams/'.$id, $mode ); +// +// } +// +// function testStream( ){ +// +// $stream = $this->getStream( 'test1', 'w', strlen( 'foobar' ) ); +// +// fwrite( $stream, 'foobar' ); +// +// fclose( $stream ); +// +// +// $stream = $this->getStream( 'test1', 'r', strlen( 'foobar' ) ); +// +// $data = fread( $stream, 6 ); +// +// fclose( $stream ); +// +// $this->assertEqual( 'foobar', $data ); +// +// +// $file = OC::$SERVERROOT.'/3rdparty/MDB2.php'; +// +// $source = fopen( $file, 'r' ); +// +// $target = $this->getStream( 'test2', 'w', 0 ); +// +// OCP\Files::streamCopy( $source, $target ); +// +// fclose( $target ); +// +// fclose( $source ); +// +// +// $stream = $this->getStream( 'test2', 'r', filesize( $file ) ); +// +// $data = stream_get_contents( $stream ); +// +// $original = file_get_contents( $file ); +// +// $this->assertEqual( strlen( $original ), strlen( $data ) ); +// +// $this->assertEqual( $original, $data ); +// +// } + +} // class Test_CryptStream extends UnitTestCase { // private $tmpFiles=array(); From 4da67b0a08272ecb6a99a04d6b16ba784f4791da Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 10 Oct 2012 18:40:59 +0100 Subject: [PATCH 066/315] Development snapshot; encryption stream wrapper now successfully writes files, and passes unit tests --- apps/files_encryption/lib/crypt.php | 6 +- apps/files_encryption/lib/keymanager.php | 33 ++++- apps/files_encryption/lib/stream.php | 126 ++++++++++++----- apps/files_encryption/tests/crypt.php | 164 +++++++++++++++++------ lib/filesystemview.php | 3 + 5 files changed, 255 insertions(+), 77 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index bf5e1ab64f..e805752137 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -441,8 +441,6 @@ class Crypt { * @brief Symmetrically decrypt a file by combining encrypted component data blocks */ public static function symmetricBlockDecryptFileContent( $crypted, $key ) { - - echo "\n\n\nfags \$crypted = $crypted\n\n\n"; $decrypted = ''; @@ -463,9 +461,7 @@ class Crypt { } - echo "nags "; - - print_r($testarray); + //print_r($testarray); return $decrypted; diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 525943f13d..9d5e170e7f 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -143,7 +143,38 @@ class Keymanager { return $view->file_get_contents( $keypath . '.key' ); - } + } + + /** + * @brief retrieve file encryption key + * + * @param string file name + * @return string file key or false + */ + public static function deleteFileKey( $path, $staticUserClass = 'OCP\User' ) { + + $keypath = ltrim( $path, '/' ); + $user = $staticUserClass::getUser(); + + // update $keypath and $user if path point to a file shared by someone else +// $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); +// +// $result = $query->execute( array ('/'.$user.'/files/'.$keypath, $user)); +// +// if ($row = $result->fetchRow()) { +// +// $keypath = $row['source']; +// $keypath_parts = explode( '/', $keypath ); +// $user = $keypath_parts[1]; +// $keypath = str_replace( '/' . $user . '/files/', '', $keypath ); +// +// } + + $view = new \OC_FilesystemView('/'.$user.'/files_encryption/keyfiles/'); + + return $view->unlink( $keypath . '.key' ); + + } /** * @brief store private key from the user diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 81346b8be3..96b754c1a8 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -3,7 +3,7 @@ * ownCloud * * @author Robin Appelman - * @copyright 2011 Robin Appelman icewind1991@gmail.com + * @copyright 2012 Sam Tuke samtuke@owncloud.com, 2011 Robin Appelman icewind1991@gmail.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -29,6 +29,11 @@ namespace OCA_Encryption; +/** + * @brief Provides 'crypt://' stream wrapper protocol. + * @note Paths used with this protocol MUST BE RELATIVE, due to limitations of OC_FilesystemView. crypt:///home/user/owncloud/data <- will put keyfiles in [owncloud]/data/user/files_encryption/keyfiles/home/user/owncloud/data and will not be accessible by other functions. + * @note Data read and written must always be 8192 bytes long, as this is the buffer size used internally by PHP. The encryption process makes the input data longer, and input is chunked into smaller pieces in order to result in a 8192 encrypted block size. + */ class Stream { public static $sourceStreams = array(); @@ -94,9 +99,9 @@ class Stream { // Disable fileproxies so we can open the source file without recursive encryption \OC_FileProxy::$enabled = false; - $this->handle = fopen( $path, $mode ); + //$this->handle = fopen( $path, $mode ); - //$this->handle = self::$view->fopen( $path, $mode ); + $this->handle = self::$view->fopen( \OCP\USER::getUser() . '/' . 'files' . '/' . $path, $mode ); \OC_FileProxy::$enabled = true; @@ -156,7 +161,7 @@ class Stream { echo "\n\nGROWL {$this->keyfile}\n\n"; - $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/tmp-1346255589.key' ); + //$key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/tmp-1346255589.key' ); $result = Crypt::symmetricDecryptFileContent( $data, $this->keyfile ); @@ -201,17 +206,20 @@ class Stream { # TODO: Move this user call out of here - it belongs elsewhere $user = \OCP\User::getUser(); - if ( self::$view->file_exists( $this->rawPath ) ) { - + //echo "\n\$this->rawPath = {$this->rawPath}"; + + // If a keyfile already exists for a file named identically to file to be written + if ( self::$view->file_exists( $user . '/'. 'files_encryption' . '/' . 'keyfiles' . '/' . $this->rawPath . '.key' ) ) { + # TODO: add error handling for when file exists but no keyfile - // If the data is to be written to an existing file, fetch its keyfile + // Fetch existing keyfile $this->keyfile = Keymanager::getFileKey( $this->rawPath ); } else { if ( $generate ) { - + // If the data is to be written to a new file, generate a new keyfile $this->keyfile = Crypt::generateKey(); @@ -223,16 +231,23 @@ class Stream { /** * @brief Take plain data destined to be written, encrypt it, and write it block by block + * @param string $data data to be written to disk + * @note the data will be written to the path stored in the stream handle, set in stream_open() + * @note $data is only ever x bytes long. stream_write() is called multiple times on data larger than x to process it x byte chunks. */ public function stream_write( $data ) { \OC_FileProxy::$enabled = false; $length = strlen( $data ); - + $written = 0; - $currentPos = ftell( $this->handle ); + $pointer = ftell( $this->handle ); + + echo "\n\n\$length = $length\n"; + + echo "\$pointer = $pointer\n"; # TODO: Move this user call out of here - it belongs elsewhere $user = \OCP\User::getUser(); @@ -247,10 +262,10 @@ class Stream { } -// // If data exists in the writeCache + // If data exists in the writeCache // if ( $this->writeCache ) { // -// trigger_error("write cache is set"); +// //trigger_error("write cache is set"); // // // Concat writeCache to start of $data // $data = $this->writeCache . $data; @@ -260,15 +275,30 @@ class Stream { // } // // // Make sure we always start on a block start -// if ( 0 != ( $currentPos % 8192 ) ) { // If we're not at the end of file yet (in the final chunk), if there will be no bytes left to read after the current chunk + if ( 0 != ( $pointer % 8192 ) ) { // if the current positoin of file indicator is not aligned to a 8192 byte block, fix it so that it is +// +// echo "\n\nNOT ON BLOCK START "; +// echo $pointer % 8192; +// +// echo "\n\n1. $currentPos\n\n"; +// // +// echo "ftell() = ".ftell($this->handle)."\n"; + +// fseek( $this->handle, - ( $pointer % 8192 ), SEEK_CUR ); +// +// $pointer = ftell( $this->handle ); + +// echo "ftell() = ".ftell($this->handle)."\n"; // +// $unencryptedNewBlock = fread( $this->handle, 8192 ); +// +// echo "\n\n2. $currentPos\n\n"; +// // fseek( $this->handle, - ( $currentPos % 8192 ), SEEK_CUR ); +// +// echo "\n\n3. $currentPos\n\n"; // -// $encryptedBlock = fread( $this->handle, 8192 ); -// -// fseek( $this->handle, - ( $currentPos % 8192 ), SEEK_CUR ); -// -// $block = Crypt::symmetricDecryptFileContent( $encryptedBlock, $this->keyfile ); +// $block = Crypt::symmetricDecryptFileContent( $unencryptedNewBlock, $this->keyfile ); // // $x = substr( $block, 0, $currentPos % 8192 ); // @@ -276,13 +306,14 @@ class Stream { // // fseek( $this->handle, - ( $currentPos % 8192 ), SEEK_CUR ); // -// } -/* - $currentPos = ftell( $this->handle );*/ + } + +// $currentPos = ftell( $this->handle ); -// // While there still remains somed data to be written -// while( strlen( $data ) > 0 ) { +// // While there still remains somed data to be processed & written + while( strlen( $data ) > 0 ) { // +// // Remaining length for this iteration, not of the entire file (may be greater than 8192 bytes) // $remainingLength = strlen( $data ); // // // If data remaining to be written is less than the size of 1 block @@ -294,25 +325,56 @@ class Stream { // $this->writeCache = $data; // // $data = ''; -// +// // // } else { - $encrypted = Crypt::symmetricEncryptFileContent( $data, $this->keyfile ); + //echo "\n\nbefore before ".strlen($data)."\n"; - file_put_contents('/home/samtuke/tmp.txt', $encrypted); + // Read the chunk from the start of $data + $chunk = substr( $data, 0, 6126 ); - //echo "\n\nFRESHLY ENCRYPTED = $encrypted\n\n"; + //echo "before ".strlen($data)."\n"; - fwrite( $this->handle, $encrypted ); + //echo "\n\$this->keyfile 1 = {$this->keyfile}"; + + $encrypted = Crypt::symmetricEncryptFileContent( $chunk, $this->keyfile ); + + //echo "\n\n\$rawEnc = $encrypted\n\n"; + + //echo "\$encrypted = ".strlen($encrypted)."\n"; + + $padded = $encrypted . 'xx'; + + //echo "\$padded = ".strlen($padded)."\n"; + + //echo "after ".strlen($encrypted)."\n\n"; + + //file_put_contents('/home/samtuke/tmp.txt', $encrypted); + + fwrite( $this->handle, $padded ); + + $bef = ftell( $this->handle ); + //echo "ftell before = $bef\n"; + + $writtenLen = strlen( $padded ); + //fseek( $this->handle, $writtenLen, SEEK_CUR ); + +// $aft = ftell( $this->handle ); +// echo "ftell after = $aft\n"; +// echo "ftell sum = "; +// echo $aft - $bef."\n"; - $data = substr( $data, 8192 ); + // Remove the chunk we just processed from $data, leaving only unprocessed data in $data var + $data = substr( $data, 6126 ); // } // -// } - - $this->size = max( $this->size, $currentPos + $length ); + } + $this->size = max( $this->size, $pointer + $length ); + + echo "\$this->size = $this->size\n\n"; + return $length; } diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index 81d262460b..f993ecf5bb 100644 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -124,7 +124,130 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { \OC_User::setUserId( 'admin' ); - $filename = 'flockEncrypt'; + $filename = 'tmp-'.time(); + + $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataShort ); + + // Test that data was successfully written + $this->assertTrue( is_int( $cryptedFile ) ); + + + // Get file contents without using any wrapper to get it's actual contents on disk + $retreivedCryptedFile = $this->view->file_get_contents( '/admin/files/' . $filename ); + + // Manually remove padding from end of each chunk + $retreivedCryptedFile = substr( $retreivedCryptedFile, 0, -2 ); + + // Check that the file was encrypted before being written to disk + $this->assertNotEquals( $this->dataShort, $retreivedCryptedFile ); + + + $key = Keymanager::getFileKey( $filename ); + + $manualDecrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key ); + + $this->assertEquals( $this->dataShort, $manualDecrypt ); + + } + + function testSymmetricStreamEncryptLongFileContent() { + + // Generate a a random filename + $filename = 'tmp-'.time(); + + echo "\n\n\$filename = $filename\n\n"; + + // Save long data as encrypted file using stream wrapper + $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong.$this->dataLong ); + + // Test that data was successfully written + $this->assertTrue( is_int( $cryptedFile ) ); + + // Get file contents without using any wrapper to get it's actual contents on disk + $retreivedCryptedFile = $this->view->file_get_contents( '/admin/files/' . $filename ); + + // Check that the file was encrypted before being written to disk + $this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile ); + + // Get file contents without using any wrapper to get it's actual contents on disk + $undecrypted = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files/' . $filename ); + + //echo "\n\n\$undecrypted = $undecrypted\n\n"; + + // Manuallly split saved file into separate IVs and encrypted chunks + $r = preg_split('/(00iv00.{16,18})/', $undecrypted, NULL, PREG_SPLIT_DELIM_CAPTURE); + + //print_r($r); + + // Join IVs and their respective data chunks + $e = array( $r[0].$r[1], $r[2].$r[3], $r[4].$r[5], $r[6].$r[7], $r[8].$r[9], $r[10].$r[11], $r[12].$r[13], $r[14] ); + +// print_r($e); + + $f = array(); + + // Manually remove padding from end of each chunk + foreach ( $e as $e ) { + + $f[] = substr( $e, 0, -2 ); + + } + +// print_r($f); + + // Manually fetch keyfile + $keyfile = Keymanager::getFileKey( $filename ); + + // Set var for reassembling decrypted content + $decrypt = ''; + + // Manually decrypt chunk + foreach ($f as $f) { + +// echo "\n\$encryptMe = $f"; + + $chunkDecrypt = Crypt::symmetricDecryptFileContent( $f, $keyfile ); + + // Assemble decrypted chunks + $decrypt .= $chunkDecrypt; + +// echo "\n\$chunkDecrypt = $chunkDecrypt"; + + } + + $this->assertEquals( $this->dataLong.$this->dataLong, $decrypt ); + + // Teadown + + $this->view->unlink( '/admin/files/' . $filename ); + + Keymanager::deleteFileKey( $filename ); + + // Fetch the saved encrypted file using stream wrapper to decrypt it +// $autoDecrypted = file_get_contents( 'crypt:////home/samtuke/owncloud/git/oc3/data/' . $filename ); +// +// //file_get_contents('crypt:///home/samtuke/tmp-1346255589'); +// +// // Check that the retreived decrypted contents match the original +// $this->assertEquals( $this->dataLong.$this->dataLong, $autoDecrypted ); + + +// $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/' . $filename . '.key' ); +// +// $manualDecrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key ); +// +// echo "\n\n\n\n\n\n\n\n\n\n\$manualDecrypt = $manualDecrypt\n\n"; + +// +// $this->assertEquals( $this->dataLong, $manualDecrypt ); + + } + + function testSymmetricStreamDecryptShortFileContent() { + + \OC_User::setUserId( 'admin' ); + + $filename = 'tmp-'.time(); $cryptedFile = file_put_contents( 'crypt://' . '/' . $filename, $this->dataShort ); @@ -147,44 +270,7 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { } - function testSymmetricStreamEncryptLongFileContent() { - - $filename = 'tmp-'.time(); - - echo "\n\n\$filename = $filename\n\n"; - - $cryptedFile = file_put_contents( 'crypt://' . '/' . '/home/samtuke/owncloud/git/oc3/data/' . $filename, $this->dataLong.$this->dataLong ); - - // Test that data was successfully written - $this->assertTrue( is_int( $cryptedFile ) ); - - - // Get file contents without using any wrapper to get it's actual contents on disk - $retreivedCryptedFile = $this->view->file_get_contents( '/' . $filename ); - - //echo "\n\nsock $retreivedCryptedFile\n\n"; - - // Check that the file was encrypted before being written to disk - $this->assertNotEquals( $this->dataLong.$this->dataLong, $retreivedCryptedFile ); - - $autoDecrypted = file_get_contents( 'crypt:////home/samtuke/owncloud/git/oc3/data/' . $filename ); - - //file_get_contents('crypt:///home/samtuke/tmp-1346255589'); - - $this->assertEquals( $this->dataLong.$this->dataLong, $autoDecrypted ); - - -// $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/' . $filename . '.key' ); -// -// $manualDecrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key ); -// -// echo "\n\n\n\n\n\n\n\n\n\n\$manualDecrypt = $manualDecrypt\n\n"; - -// -// $this->assertEquals( $this->dataLong, $manualDecrypt ); - - } - + // Is this test still necessary? // function testSymmetricBlockStreamDecryptFileContent() { // // \OC_User::setUserId( 'admin' ); diff --git a/lib/filesystemview.php b/lib/filesystemview.php index 448663bb08..893305e347 100644 --- a/lib/filesystemview.php +++ b/lib/filesystemview.php @@ -38,6 +38,9 @@ * OC_Filestorage object */ + /** + * @note default root (if $root is empty or '/') is /data/[user]/ + */ class OC_FilesystemView { private $fakeRoot=''; private $internal_path_cache=array(); From 06ea9c18f8bfbfa6fc7e44f27ab11a68c811bca2 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 16 Oct 2012 15:02:51 +0100 Subject: [PATCH 067/315] Development snapshot Stream reading and writing of small and large files working, using write cache --- apps/files_encryption/lib/stream.php | 143 ++++++++++++++++---------- apps/files_encryption/tests/crypt.php | 86 ++++++++-------- 2 files changed, 130 insertions(+), 99 deletions(-) diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 96b754c1a8..0a8efa41d3 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -90,9 +90,9 @@ class Stream { } else { - //$this->size = self::$view->filesize( $path, $mode ); - - $this->size = filesize( $path ); + $this->size = self::$view->filesize( \OCP\USER::getUser() . '/' . 'files' . '/' . $path, $mode ); + + //$this->size = filesize( $path ); } @@ -140,7 +140,7 @@ class Stream { $this->writeCache = ''; if ( $count != 8192 ) { - + // $count will always be 8192 https://bugs.php.net/bug.php?id=21641 // This makes this function a lot simpler, but will break this class if the above 'bug' gets 'fixed' \OCP\Util::writeLog( 'files_encryption', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', OCP\Util::FATAL ); @@ -151,7 +151,11 @@ class Stream { // $pos = ftell( $this->handle ); // - $data = fread( $this->handle, 8192 ); + // Get the data from the file handle, including IV and padding + $padded = fread( $this->handle, 8192 ); + + // Remove padding, leaving data and IV + $data = substr( $padded, 0, -2 ); //echo "\n\nPRE DECRYPTION = $data\n\n"; // @@ -159,8 +163,6 @@ class Stream { $this->getKey(); - echo "\n\nGROWL {$this->keyfile}\n\n"; - //$key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/tmp-1346255589.key' ); $result = Crypt::symmetricDecryptFileContent( $data, $this->keyfile ); @@ -169,7 +171,7 @@ class Stream { echo "\n\n\$data = $data"; - echo "\n\n\$key = $key"; + echo "\n\n\$key = {$this->keyfile}"; echo "\n\n\$result = $result"; @@ -197,9 +199,34 @@ class Stream { } + /** + * @brief Encrypt and pad data ready for writting to disk + * @param string $plainData data to be encrypted + * @param string $key key to use for encryption + * @return encrypted data on success, false on failure + */ + public function preWriteEncrypt( $plainData, $key ) { + + // Encrypt data to 'catfile', which includes IV + if ( $encrypted = Crypt::symmetricBlockEncryptFileContent( $plainData, $key ) ) { + + // Add padding. In order to end up with data exactly 8192 bytes long we must add two letters. Something about the encryption process always results in 8190 or 8194 byte length, hence the letters must be added manually after encryption takes place. They get removed in the stream read process + $padded = $encrypted . 'xx'; + + return $padded; + + } else { + + return false; + + } + + } + /** * @brief Get the keyfile for the current file, generate one if necessary * @param bool $generate if true, a new key will be generated if none can be found + * @return bool true on key found and set, false on key not found and new key generated and set */ public function getKey( $generate = true ) { @@ -216,6 +243,8 @@ class Stream { // Fetch existing keyfile $this->keyfile = Keymanager::getFileKey( $this->rawPath ); + return true; + } else { if ( $generate ) { @@ -223,6 +252,8 @@ class Stream { // If the data is to be written to a new file, generate a new keyfile $this->keyfile = Crypt::generateKey(); + return false; + } } @@ -230,54 +261,61 @@ class Stream { } /** - * @brief Take plain data destined to be written, encrypt it, and write it block by block + * @brief Handle plain data from the stream, and write it in 8192 byte blocks * @param string $data data to be written to disk * @note the data will be written to the path stored in the stream handle, set in stream_open() - * @note $data is only ever x bytes long. stream_write() is called multiple times on data larger than x to process it x byte chunks. + * @note $data is only ever be a maximum of 8192 bytes long. This is set by PHP internally. stream_write() is called multiple times in a loop on data larger than 8192 bytes + * @note Because the encryption process used increases the length of $data, a writeCache is used to carry over data which would not fit in the required block size + * @note Padding is added to each encrypted block to ensure that the resulting block is exactly 8192 bytes. This is removed during stream_read + * @note PHP automatically updates the file pointer after writing data to reflect it's length. There is generally no need to update the poitner manually using fseek */ public function stream_write( $data ) { + // Disable the file proxies so that encryption is not automatically attempted when the file is written to disk - we are handling that separately here and we don't want to get into an infinite loop \OC_FileProxy::$enabled = false; + // Get the length of the unencrypted data that we are handling $length = strlen( $data ); + // So far this round, no data has been written $written = 0; - + + // Find out where we are up to in the writing of data to the file $pointer = ftell( $this->handle ); - echo "\n\n\$length = $length\n"; + //echo "\n\n\$rawLength = $length\n"; - echo "\$pointer = $pointer\n"; + //echo "\$pointer = $pointer\n"; # TODO: Move this user call out of here - it belongs elsewhere $user = \OCP\User::getUser(); - // Set keyfile property for file in question - $this->getKey(); - - if ( ! self::$view->file_exists( $this->rawPath . $user ) ) { + // Get / generate the keyfile for the file we're handling + // If we're writing a new file (not overwriting an existing one), save the newly generated keyfile + if ( ! $this->getKey() ) { // Save keyfile in parallel directory structure Keymanager::setFileKey( $this->rawPath, $this->keyfile, new \OC_FilesystemView( '/' ) ); } - // If data exists in the writeCache -// if ( $this->writeCache ) { -// -// //trigger_error("write cache is set"); -// -// // Concat writeCache to start of $data -// $data = $this->writeCache . $data; -// -// $this->writeCache = ''; -// -// } + // If extra data is left over from the last round, make sure it is integrated into the next 6126 / 8192 block + if ( $this->writeCache ) { + + // Concat writeCache to start of $data + $data = $this->writeCache . $data; + + //echo "\n\ncache + data length = ".strlen($data)."\n"; + + // Clear the write cache, ready for resuse - it has been flushed and its old contents processed + $this->writeCache = ''; + + } // // // Make sure we always start on a block start if ( 0 != ( $pointer % 8192 ) ) { // if the current positoin of file indicator is not aligned to a 8192 byte block, fix it so that it is // -// echo "\n\nNOT ON BLOCK START "; + //echo "\n\nNOT ON BLOCK START "; // echo $pointer % 8192; // // echo "\n\n1. $currentPos\n\n"; @@ -316,17 +354,17 @@ class Stream { // // Remaining length for this iteration, not of the entire file (may be greater than 8192 bytes) // $remainingLength = strlen( $data ); // -// // If data remaining to be written is less than the size of 1 block -// if ( $remainingLength < 8192 ) { -// -// //trigger_error("remaining length < 8192"); -// -// // Set writeCache to contents of $data -// $this->writeCache = $data; +// // If data remaining to be written is less than the size of 1 6126 byte block + if ( strlen( $data ) < 6126 ) { + + // Set writeCache to contents of $data + // The writeCache will be carried over to the next write round, and added to the start of $data to ensure that written blocks are always the correct length. If there is still data in writeCache after the writing round has finished, then the data will be written to disk by $this->flush(). + $this->writeCache = $data; + + // Clear $data ready for next round + $data = ''; // -// $data = ''; -// // -// } else { + } else { //echo "\n\nbefore before ".strlen($data)."\n"; @@ -337,26 +375,25 @@ class Stream { //echo "\n\$this->keyfile 1 = {$this->keyfile}"; - $encrypted = Crypt::symmetricEncryptFileContent( $chunk, $this->keyfile ); + $encrypted = $this->preWriteEncrypt( $chunk, $this->keyfile ); //echo "\n\n\$rawEnc = $encrypted\n\n"; //echo "\$encrypted = ".strlen($encrypted)."\n"; - $padded = $encrypted . 'xx'; - - //echo "\$padded = ".strlen($padded)."\n"; + //echo "written = ".strlen($encrypted)."\n"; //echo "after ".strlen($encrypted)."\n\n"; //file_put_contents('/home/samtuke/tmp.txt', $encrypted); - fwrite( $this->handle, $padded ); + // Write the data chunk to disk. This will be addended to the last data chunk if the file being handled totals more than 6126 bytes + fwrite( $this->handle, $encrypted ); - $bef = ftell( $this->handle ); + //$bef = ftell( $this->handle ); //echo "ftell before = $bef\n"; - $writtenLen = strlen( $padded ); + $writtenLen = strlen( $encrypted ); //fseek( $this->handle, $writtenLen, SEEK_CUR ); // $aft = ftell( $this->handle ); @@ -364,16 +401,16 @@ class Stream { // echo "ftell sum = "; // echo $aft - $bef."\n"; - // Remove the chunk we just processed from $data, leaving only unprocessed data in $data var + // Remove the chunk we just processed from $data, leaving only unprocessed data in $data var, for handling on the next round $data = substr( $data, 6126 ); -// } -// + } + } $this->size = max( $this->size, $pointer + $length ); - echo "\$this->size = $this->size\n\n"; + //echo "\$this->size = $this->size\n\n"; return $length; @@ -418,11 +455,7 @@ class Stream { // Set keyfile property for file in question $this->getKey(); - //echo "\n\nFLUSH = {$this->writeCache}\n\n"; - - $encrypted = Crypt::symmetricBlockEncryptFileContent( $this->writeCache, $this->keyfile ); - - //echo "\n\nENCFLUSH = $encrypted\n\n"; + $encrypted = $this->preWriteEncrypt( $this->writeCache, $this->keyfile ); fwrite( $this->handle, $encrypted ); diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index f993ecf5bb..b1b13f2ac8 100644 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -22,6 +22,7 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { $this->dataUrl = realpath( dirname(__FILE__).'/../lib/crypt.php' ); $this->legacyData = realpath( dirname(__FILE__).'/legacy-text.txt' ); $this->legacyEncryptedData = realpath( dirname(__FILE__).'/legacy-encrypted-text.txt' ); + $this->randomKey = Crypt::generateKey(); $this->view = new \OC_FilesystemView( '/' ); @@ -79,27 +80,25 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { # TODO: search in keyfile for actual content as IV will ensure this test always passes - $crypted = Crypt::symmetricEncryptFileContent( $this->dataUrl, 'hat' ); + $crypted = Crypt::symmetricEncryptFileContent( $this->dataShort, 'hat' ); - $this->assertNotEquals( $this->dataUrl, $crypted ); + $this->assertNotEquals( $this->dataShort, $crypted ); $decrypt = Crypt::symmetricDecryptFileContent( $crypted, 'hat' ); - $this->assertEquals( $this->dataUrl, $decrypt ); + $this->assertEquals( $this->dataShort, $decrypt ); } function testSymmetricBlockEncryptShortFileContent() { - $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/sscceEncrypt-1345649062.key' ); - - $crypted = Crypt::symmetricBlockEncryptFileContent( $this->dataShort, $key ); + $crypted = Crypt::symmetricBlockEncryptFileContent( $this->dataShort, $this->randomKey ); $this->assertNotEquals( $this->dataShort, $crypted ); - $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, $key ); + $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, $this->randomKey ); $this->assertEquals( $this->dataShort, $decrypt ); @@ -107,22 +106,18 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { function testSymmetricBlockEncryptLongFileContent() { - $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/sscceEncrypt-1345649062.key' ); - - $crypted = Crypt::symmetricBlockEncryptFileContent( $this->dataLong, $key ); + $crypted = Crypt::symmetricBlockEncryptFileContent( $this->dataLong, $this->randomKey ); $this->assertNotEquals( $this->dataLong, $crypted ); - $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, $key ); + $decrypt = Crypt::symmetricBlockDecryptFileContent( $crypted, $this->randomKey ); $this->assertEquals( $this->dataLong, $decrypt ); } function testSymmetricStreamEncryptShortFileContent() { - - \OC_User::setUserId( 'admin' ); $filename = 'tmp-'.time(); @@ -150,6 +145,10 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { } + /** + * @brief Test that data that is written by the crypto stream wrapper + * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read + */ function testSymmetricStreamEncryptLongFileContent() { // Generate a a random filename @@ -177,12 +176,12 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { // Manuallly split saved file into separate IVs and encrypted chunks $r = preg_split('/(00iv00.{16,18})/', $undecrypted, NULL, PREG_SPLIT_DELIM_CAPTURE); - //print_r($r); + print_r($r); // Join IVs and their respective data chunks - $e = array( $r[0].$r[1], $r[2].$r[3], $r[4].$r[5], $r[6].$r[7], $r[8].$r[9], $r[10].$r[11], $r[12].$r[13], $r[14] ); + $e = array( $r[0].$r[1], $r[2].$r[3], $r[4].$r[5], $r[6].$r[7], $r[8].$r[9], $r[10] );//.$r[11], $r[12].$r[13], $r[14] ); -// print_r($e); + //print_r($e); $f = array(); @@ -211,7 +210,7 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { // Assemble decrypted chunks $decrypt .= $chunkDecrypt; -// echo "\n\$chunkDecrypt = $chunkDecrypt"; + //echo "\n\$chunkDecrypt = $chunkDecrypt"; } @@ -223,50 +222,49 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { Keymanager::deleteFileKey( $filename ); - // Fetch the saved encrypted file using stream wrapper to decrypt it -// $autoDecrypted = file_get_contents( 'crypt:////home/samtuke/owncloud/git/oc3/data/' . $filename ); -// -// //file_get_contents('crypt:///home/samtuke/tmp-1346255589'); -// -// // Check that the retreived decrypted contents match the original -// $this->assertEquals( $this->dataLong.$this->dataLong, $autoDecrypted ); - - -// $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/' . $filename . '.key' ); -// -// $manualDecrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key ); -// -// echo "\n\n\n\n\n\n\n\n\n\n\$manualDecrypt = $manualDecrypt\n\n"; - -// -// $this->assertEquals( $this->dataLong, $manualDecrypt ); - } + /** + * @brief Test that data that is read by the crypto stream wrapper + * @depends testSymmetricStreamEncryptLongFileContent + */ function testSymmetricStreamDecryptShortFileContent() { - - \OC_User::setUserId( 'admin' ); $filename = 'tmp-'.time(); - $cryptedFile = file_put_contents( 'crypt://' . '/' . $filename, $this->dataShort ); + // Save long data as encrypted file using stream wrapper + $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataShort ); // Test that data was successfully written $this->assertTrue( is_int( $cryptedFile ) ); // Get file contents without using any wrapper to get it's actual contents on disk - $retreivedCryptedFile = $this->view->file_get_contents( '/'. $filename ); + $retreivedCryptedFile = $this->view->file_get_contents( '/admin/files/' . $filename ); - // Check that the file was encrypted before being written to disk - $this->assertNotEquals( $this->dataShort, $retreivedCryptedFile ); + $decrypt = file_get_contents( 'crypt://' . $filename ); + + $this->assertEquals( $this->dataShort, $decrypt ); + + } + + function testSymmetricStreamDecryptLongFileContent() { + + $filename = 'tmp-'.time(); + + // Save long data as encrypted file using stream wrapper + $cryptedFile = file_put_contents( 'crypt://' . $filename, $this->dataLong ); + + // Test that data was successfully written + $this->assertTrue( is_int( $cryptedFile ) ); - $key = file_get_contents( '/home/samtuke/owncloud/git/oc3/data/admin/files_encryption/keyfiles/' . $filename . '.key' ); + // Get file contents without using any wrapper to get it's actual contents on disk + $retreivedCryptedFile = $this->view->file_get_contents( '/admin/files/' . $filename ); - $manualDecrypt = Crypt::symmetricBlockDecryptFileContent( $retreivedCryptedFile, $key ); + $decrypt = file_get_contents( 'crypt://' . $filename ); - $this->assertEquals( $this->dataShort, $manualDecrypt ); + $this->assertEquals( $this->dataLong, $decrypt ); } From 8b01286a5d14bae90607d5192c89b5f9d72d8bc2 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 16 Oct 2012 16:57:07 +0100 Subject: [PATCH 068/315] Merged branch 'master' --- .gitignore | 2 + .tx/config | 182 - 3rdparty/Archive/Tar.php | 77 +- 3rdparty/MDB2/Driver/Datatype/Common.php | 2 +- 3rdparty/MDB2/Driver/Datatype/oci8.php | 499 + 3rdparty/MDB2/Driver/Function/oci8.php | 187 + 3rdparty/MDB2/Driver/Manager/oci8.php | 1340 + 3rdparty/MDB2/Driver/Native/oci8.php | 60 + 3rdparty/MDB2/Driver/Reverse/oci8.php | 625 + 3rdparty/MDB2/Driver/mysql.php | 2 +- 3rdparty/MDB2/Driver/oci8.php | 1700 + 3rdparty/Sabre.includes.php | 0 3rdparty/Sabre/CalDAV/Backend/Abstract.php | 0 3rdparty/Sabre/CalDAV/Backend/PDO.php | 0 3rdparty/Sabre/CalDAV/Calendar.php | 0 3rdparty/Sabre/CalDAV/CalendarObject.php | 0 3rdparty/Sabre/CalDAV/CalendarQueryParser.php | 0 .../Sabre/CalDAV/CalendarQueryValidator.php | 39 +- 3rdparty/Sabre/CalDAV/CalendarRootNode.php | 0 3rdparty/Sabre/CalDAV/ICSExportPlugin.php | 0 3rdparty/Sabre/CalDAV/ICalendar.php | 0 3rdparty/Sabre/CalDAV/ICalendarObject.php | 0 3rdparty/Sabre/CalDAV/Plugin.php | 146 +- .../Sabre/CalDAV/Principal/Collection.php | 0 3rdparty/Sabre/CalDAV/Principal/ProxyRead.php | 0 .../Sabre/CalDAV/Principal/ProxyWrite.php | 0 3rdparty/Sabre/CalDAV/Principal/User.php | 0 .../SupportedCalendarComponentSet.php | 0 .../CalDAV/Property/SupportedCalendarData.php | 0 .../CalDAV/Property/SupportedCollationSet.php | 0 3rdparty/Sabre/CalDAV/Schedule/IMip.php | 0 3rdparty/Sabre/CalDAV/Schedule/IOutbox.php | 0 3rdparty/Sabre/CalDAV/Schedule/Outbox.php | 0 3rdparty/Sabre/CalDAV/Server.php | 0 3rdparty/Sabre/CalDAV/UserCalendars.php | 0 3rdparty/Sabre/CalDAV/Version.php | 2 +- 3rdparty/Sabre/CalDAV/includes.php | 0 3rdparty/Sabre/CardDAV/AddressBook.php | 4 +- .../Sabre/CardDAV/AddressBookQueryParser.php | 18 +- 3rdparty/Sabre/CardDAV/AddressBookRoot.php | 0 3rdparty/Sabre/CardDAV/Backend/Abstract.php | 0 3rdparty/Sabre/CardDAV/Backend/PDO.php | 0 3rdparty/Sabre/CardDAV/Card.php | 0 3rdparty/Sabre/CardDAV/IAddressBook.php | 0 3rdparty/Sabre/CardDAV/ICard.php | 0 3rdparty/Sabre/CardDAV/IDirectory.php | 0 3rdparty/Sabre/CardDAV/Plugin.php | 84 +- .../CardDAV/Property/SupportedAddressData.php | 0 3rdparty/Sabre/CardDAV/UserAddressBooks.php | 0 3rdparty/Sabre/CardDAV/Version.php | 2 +- 3rdparty/Sabre/CardDAV/includes.php | 0 .../Sabre/DAV/Auth/Backend/AbstractBasic.php | 0 .../Sabre/DAV/Auth/Backend/AbstractDigest.php | 0 3rdparty/Sabre/DAV/Auth/Backend/Apache.php | 0 3rdparty/Sabre/DAV/Auth/Backend/File.php | 0 3rdparty/Sabre/DAV/Auth/Backend/PDO.php | 0 3rdparty/Sabre/DAV/Auth/IBackend.php | 0 3rdparty/Sabre/DAV/Auth/Plugin.php | 0 .../Sabre/DAV/Browser/GuessContentType.php | 0 .../Sabre/DAV/Browser/MapGetToPropFind.php | 0 3rdparty/Sabre/DAV/Browser/Plugin.php | 0 3rdparty/Sabre/DAV/Browser/assets/favicon.ico | Bin .../DAV/Browser/assets/icons/addressbook.png | Bin .../DAV/Browser/assets/icons/calendar.png | Bin .../Sabre/DAV/Browser/assets/icons/card.png | Bin .../DAV/Browser/assets/icons/collection.png | Bin .../Sabre/DAV/Browser/assets/icons/file.png | Bin .../Sabre/DAV/Browser/assets/icons/parent.png | Bin .../DAV/Browser/assets/icons/principal.png | Bin 3rdparty/Sabre/DAV/Client.php | 49 +- 3rdparty/Sabre/DAV/Collection.php | 0 3rdparty/Sabre/DAV/Directory.php | 0 3rdparty/Sabre/DAV/Exception.php | 0 3rdparty/Sabre/DAV/Exception/BadRequest.php | 0 3rdparty/Sabre/DAV/Exception/Conflict.php | 0 .../Sabre/DAV/Exception/ConflictingLock.php | 0 3rdparty/Sabre/DAV/Exception/FileNotFound.php | 0 3rdparty/Sabre/DAV/Exception/Forbidden.php | 0 .../DAV/Exception/InsufficientStorage.php | 0 .../DAV/Exception/InvalidResourceType.php | 0 .../Exception/LockTokenMatchesRequestUri.php | 0 3rdparty/Sabre/DAV/Exception/Locked.php | 0 .../Sabre/DAV/Exception/MethodNotAllowed.php | 0 .../Sabre/DAV/Exception/NotAuthenticated.php | 0 3rdparty/Sabre/DAV/Exception/NotFound.php | 0 .../Sabre/DAV/Exception/NotImplemented.php | 0 .../Sabre/DAV/Exception/PaymentRequired.php | 0 .../DAV/Exception/PreconditionFailed.php | 0 .../DAV/Exception/ReportNotImplemented.php | 0 .../RequestedRangeNotSatisfiable.php | 0 .../DAV/Exception/UnsupportedMediaType.php | 0 3rdparty/Sabre/DAV/FS/Directory.php | 0 3rdparty/Sabre/DAV/FS/File.php | 0 3rdparty/Sabre/DAV/FS/Node.php | 0 3rdparty/Sabre/DAV/FSExt/Directory.php | 0 3rdparty/Sabre/DAV/FSExt/File.php | 0 3rdparty/Sabre/DAV/FSExt/Node.php | 0 3rdparty/Sabre/DAV/File.php | 0 3rdparty/Sabre/DAV/ICollection.php | 0 3rdparty/Sabre/DAV/IExtendedCollection.php | 0 3rdparty/Sabre/DAV/IFile.php | 0 3rdparty/Sabre/DAV/INode.php | 0 3rdparty/Sabre/DAV/IProperties.php | 0 3rdparty/Sabre/DAV/IQuota.php | 0 3rdparty/Sabre/DAV/Locks/Backend/Abstract.php | 0 3rdparty/Sabre/DAV/Locks/Backend/FS.php | 0 3rdparty/Sabre/DAV/Locks/Backend/File.php | 0 3rdparty/Sabre/DAV/Locks/Backend/PDO.php | 0 3rdparty/Sabre/DAV/Locks/LockInfo.php | 0 3rdparty/Sabre/DAV/Locks/Plugin.php | 5 +- 3rdparty/Sabre/DAV/Mount/Plugin.php | 0 3rdparty/Sabre/DAV/Node.php | 0 3rdparty/Sabre/DAV/ObjectTree.php | 0 3rdparty/Sabre/DAV/Property.php | 0 .../Sabre/DAV/Property/GetLastModified.php | 0 3rdparty/Sabre/DAV/Property/Href.php | 0 3rdparty/Sabre/DAV/Property/HrefList.php | 0 3rdparty/Sabre/DAV/Property/IHref.php | 0 3rdparty/Sabre/DAV/Property/LockDiscovery.php | 0 3rdparty/Sabre/DAV/Property/ResourceType.php | 0 3rdparty/Sabre/DAV/Property/Response.php | 0 3rdparty/Sabre/DAV/Property/ResponseList.php | 0 3rdparty/Sabre/DAV/Property/SupportedLock.php | 0 .../Sabre/DAV/Property/SupportedReportSet.php | 0 3rdparty/Sabre/DAV/Server.php | 9 +- 3rdparty/Sabre/DAV/ServerPlugin.php | 0 3rdparty/Sabre/DAV/SimpleCollection.php | 0 3rdparty/Sabre/DAV/SimpleDirectory.php | 0 3rdparty/Sabre/DAV/SimpleFile.php | 0 3rdparty/Sabre/DAV/StringUtil.php | 0 .../Sabre/DAV/TemporaryFileFilterPlugin.php | 0 3rdparty/Sabre/DAV/Tree.php | 0 3rdparty/Sabre/DAV/Tree/Filesystem.php | 4 +- 3rdparty/Sabre/DAV/URLUtil.php | 0 3rdparty/Sabre/DAV/UUIDUtil.php | 0 3rdparty/Sabre/DAV/Version.php | 2 +- 3rdparty/Sabre/DAV/XMLUtil.php | 0 3rdparty/Sabre/DAV/includes.php | 0 .../DAVACL/AbstractPrincipalCollection.php | 0 .../Sabre/DAVACL/Exception/AceConflict.php | 0 .../Sabre/DAVACL/Exception/NeedPrivileges.php | 0 .../Sabre/DAVACL/Exception/NoAbstract.php | 0 .../Exception/NotRecognizedPrincipal.php | 0 .../Exception/NotSupportedPrivilege.php | 0 3rdparty/Sabre/DAVACL/IACL.php | 0 3rdparty/Sabre/DAVACL/IPrincipal.php | 0 3rdparty/Sabre/DAVACL/IPrincipalBackend.php | 0 3rdparty/Sabre/DAVACL/Plugin.php | 0 3rdparty/Sabre/DAVACL/Principal.php | 0 .../Sabre/DAVACL/PrincipalBackend/PDO.php | 0 3rdparty/Sabre/DAVACL/PrincipalCollection.php | 0 3rdparty/Sabre/DAVACL/Property/Acl.php | 0 .../Sabre/DAVACL/Property/AclRestrictions.php | 0 .../Property/CurrentUserPrivilegeSet.php | 0 3rdparty/Sabre/DAVACL/Property/Principal.php | 0 .../DAVACL/Property/SupportedPrivilegeSet.php | 0 3rdparty/Sabre/DAVACL/Version.php | 0 3rdparty/Sabre/DAVACL/includes.php | 0 3rdparty/Sabre/HTTP/AWSAuth.php | 0 3rdparty/Sabre/HTTP/AbstractAuth.php | 0 3rdparty/Sabre/HTTP/BasicAuth.php | 2 +- 3rdparty/Sabre/HTTP/DigestAuth.php | 0 3rdparty/Sabre/HTTP/Request.php | 0 3rdparty/Sabre/HTTP/Response.php | 0 3rdparty/Sabre/HTTP/Util.php | 0 3rdparty/Sabre/HTTP/Version.php | 2 +- 3rdparty/Sabre/HTTP/includes.php | 0 3rdparty/Sabre/VObject/Component.php | 0 3rdparty/Sabre/VObject/Component/VAlarm.php | 0 .../Sabre/VObject/Component/VCalendar.php | 0 3rdparty/Sabre/VObject/Component/VEvent.php | 15 +- 3rdparty/Sabre/VObject/Component/VJournal.php | 0 3rdparty/Sabre/VObject/Component/VTodo.php | 0 3rdparty/Sabre/VObject/DateTimeParser.php | 4 + 3rdparty/Sabre/VObject/Element.php | 0 3rdparty/Sabre/VObject/Element/DateTime.php | 0 .../Sabre/VObject/Element/MultiDateTime.php | 0 3rdparty/Sabre/VObject/ElementList.php | 0 3rdparty/Sabre/VObject/FreeBusyGenerator.php | 0 3rdparty/Sabre/VObject/Node.php | 0 3rdparty/Sabre/VObject/Parameter.php | 0 3rdparty/Sabre/VObject/ParseException.php | 0 3rdparty/Sabre/VObject/Property.php | 0 3rdparty/Sabre/VObject/Property/DateTime.php | 0 .../Sabre/VObject/Property/MultiDateTime.php | 0 3rdparty/Sabre/VObject/Reader.php | 0 3rdparty/Sabre/VObject/RecurrenceIterator.php | 40 +- 3rdparty/Sabre/VObject/Version.php | 2 +- 3rdparty/Sabre/VObject/WindowsTimezoneMap.php | 0 3rdparty/Sabre/VObject/includes.php | 0 3rdparty/Sabre/autoload.php | 0 3rdparty/class.phpmailer.php | 123 +- 3rdparty/class.smtp.php | 11 +- 3rdparty/css/chosen-sprite.png | Bin 742 -> 559 bytes 3rdparty/css/chosen.css | 261 +- 3rdparty/css/chosen/chosen.css | 206 +- 3rdparty/fullcalendar/css/fullcalendar.css | 4 +- .../fullcalendar/css/fullcalendar.print.css | 4 +- 3rdparty/fullcalendar/js/fullcalendar.js | 38 +- 3rdparty/fullcalendar/js/fullcalendar.min.js | 14 +- 3rdparty/fullcalendar/js/gcal.js | 4 +- 3rdparty/js/chosen/VERSION | 2 +- 3rdparty/js/chosen/chosen.jquery.js | 745 +- 3rdparty/js/chosen/chosen.jquery.min.js | 4 +- 3rdparty/miniColors/GPL-LICENSE.txt | 278 + 3rdparty/miniColors/MIT-LICENSE.txt | 20 + 3rdparty/miniColors/css/images/colors.png | Bin 0 -> 12973 bytes 3rdparty/miniColors/css/images/trigger.png | Bin 0 -> 706 bytes 3rdparty/miniColors/css/jquery.miniColors.css | 125 + 3rdparty/miniColors/js/jquery.miniColors.js | 710 + .../miniColors/js/jquery.miniColors.min.js | 9 + .../openid}/class.openid.v3.php | 0 .../openid}/phpmyid.php | 0 3rdparty/php-cloudfiles/cloudfiles.php | 4 +- .../HELP_MY_TESTS_DONT_WORK_ANYMORE | 399 - 3rdparty/simpletest/LICENSE | 502 - 3rdparty/simpletest/README | 102 - 3rdparty/simpletest/VERSION | 1 - 3rdparty/simpletest/arguments.php | 224 - 3rdparty/simpletest/authentication.php | 237 - 3rdparty/simpletest/autorun.php | 101 - 3rdparty/simpletest/browser.php | 1144 - 3rdparty/simpletest/collector.php | 122 - 3rdparty/simpletest/compatibility.php | 166 - 3rdparty/simpletest/cookies.php | 380 - 3rdparty/simpletest/default_reporter.php | 163 - 3rdparty/simpletest/detached.php | 96 - .../docs/en/authentication_documentation.html | 378 - .../docs/en/browser_documentation.html | 501 - 3rdparty/simpletest/docs/en/docs.css | 121 - .../docs/en/expectation_documentation.html | 476 - .../docs/en/form_testing_documentation.html | 351 - .../docs/en/group_test_documentation.html | 252 - 3rdparty/simpletest/docs/en/index.html | 542 - .../docs/en/mock_objects_documentation.html | 870 - 3rdparty/simpletest/docs/en/overview.html | 487 - .../docs/en/partial_mocks_documentation.html | 457 - .../docs/en/reporter_documentation.html | 616 - .../docs/en/unit_test_documentation.html | 442 - .../docs/en/web_tester_documentation.html | 588 - .../docs/fr/authentication_documentation.html | 372 - .../docs/fr/browser_documentation.html | 500 - 3rdparty/simpletest/docs/fr/docs.css | 84 - .../docs/fr/expectation_documentation.html | 451 - .../docs/fr/form_testing_documentation.html | 363 - .../docs/fr/group_test_documentation.html | 265 - 3rdparty/simpletest/docs/fr/index.html | 576 - .../docs/fr/mock_objects_documentation.html | 933 - 3rdparty/simpletest/docs/fr/overview.html | 321 - .../docs/fr/partial_mocks_documentation.html | 475 - .../docs/fr/reporter_documentation.html | 630 - .../docs/fr/unit_test_documentation.html | 447 - .../docs/fr/web_tester_documentation.html | 570 - 3rdparty/simpletest/dumper.php | 407 - 3rdparty/simpletest/eclipse.php | 307 - 3rdparty/simpletest/encoding.php | 649 - 3rdparty/simpletest/errors.php | 267 - 3rdparty/simpletest/exceptions.php | 226 - 3rdparty/simpletest/expectation.php | 984 - .../simpletest/extensions/pear_test_case.php | 196 - 3rdparty/simpletest/extensions/testdox.php | 53 - .../simpletest/extensions/testdox/test.php | 107 - 3rdparty/simpletest/form.php | 361 - 3rdparty/simpletest/frames.php | 592 - 3rdparty/simpletest/http.php | 628 - 3rdparty/simpletest/invoker.php | 139 - 3rdparty/simpletest/mock_objects.php | 1641 - 3rdparty/simpletest/page.php | 542 - 3rdparty/simpletest/php_parser.php | 1054 - 3rdparty/simpletest/recorder.php | 101 - 3rdparty/simpletest/reflection_php4.php | 136 - 3rdparty/simpletest/reflection_php5.php | 386 - 3rdparty/simpletest/remote.php | 115 - 3rdparty/simpletest/reporter.php | 445 - 3rdparty/simpletest/scorer.php | 875 - 3rdparty/simpletest/selector.php | 141 - 3rdparty/simpletest/shell_tester.php | 330 - 3rdparty/simpletest/simpletest.php | 391 - 3rdparty/simpletest/socket.php | 312 - 3rdparty/simpletest/tag.php | 1527 - 3rdparty/simpletest/test_case.php | 658 - 3rdparty/simpletest/tidy_parser.php | 382 - 3rdparty/simpletest/unit_tester.php | 413 - 3rdparty/simpletest/url.php | 550 - 3rdparty/simpletest/user_agent.php | 328 - 3rdparty/simpletest/web_tester.php | 1532 - 3rdparty/simpletest/xml.php | 647 - 3rdparty/smb4php/smb.php | 14 + 3rdparty/timepicker/GPL-LICENSE.txt | 0 3rdparty/timepicker/MIT-LICENSE.txt | 0 .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin .../images/ui-bg_flat_10_000000_40x100.png | Bin .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin .../images/ui-bg_glass_65_ffffff_1x400.png | Bin .../ui-bg_gloss-wave_35_f6a828_500x100.png | Bin .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin .../images/ui-icons_222222_256x240.png | Bin .../images/ui-icons_228ef1_256x240.png | Bin .../images/ui-icons_ef8c08_256x240.png | Bin .../images/ui-icons_ffd27a_256x240.png | Bin .../images/ui-icons_ffffff_256x240.png | Bin .../css/include/jquery-1.5.1.min.js | 0 .../css/include/jquery-ui-1.8.14.custom.css | 0 .../css/include/jquery.ui.core.min.js | 0 .../css/include/jquery.ui.position.min.js | 0 .../css/include/jquery.ui.tabs.min.js | 0 .../css/include/jquery.ui.widget.min.js | 0 .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin .../images/ui-bg_flat_10_000000_40x100.png | Bin .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin .../images/ui-bg_glass_65_ffffff_1x400.png | Bin .../ui-bg_gloss-wave_35_f6a828_500x100.png | Bin .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin .../images/ui-icons_222222_256x240.png | Bin .../images/ui-icons_228ef1_256x240.png | Bin .../images/ui-icons_ef8c08_256x240.png | Bin .../images/ui-icons_ffd27a_256x240.png | Bin .../images/ui-icons_ffffff_256x240.png | Bin .../timepicker/css/jquery.ui.timepicker.css | 2 +- 3rdparty/timepicker/js/i18n/i18n.html | 102 +- .../js/i18n/jquery.ui.timepicker-cs.js | 12 + .../js/i18n/jquery.ui.timepicker-de.js | 11 +- .../js/i18n/jquery.ui.timepicker-es.js | 12 + .../js/i18n/jquery.ui.timepicker-fr.js | 0 .../js/i18n/jquery.ui.timepicker-hr.js | 13 + .../js/i18n/jquery.ui.timepicker-it.js | 12 + .../js/i18n/jquery.ui.timepicker-ja.js | 5 +- .../js/i18n/jquery.ui.timepicker-nl.js | 12 + .../js/i18n/jquery.ui.timepicker-pl.js | 12 + .../js/i18n/jquery.ui.timepicker-pt-BR.js | 12 + .../js/i18n/jquery.ui.timepicker-sl.js | 12 + .../js/i18n/jquery.ui.timepicker-sv.js | 12 + .../js/i18n/jquery.ui.timepicker-tr.js | 12 + .../timepicker/js/jquery.ui.timepicker.js | 115 +- 3rdparty/timepicker/releases.txt | 10 + AUTHORS | 10 + README | 14 +- apps/.gitkeep | 1 - apps/admin_audit/appinfo/app.php | 18 - apps/admin_audit/appinfo/info.xml | 10 - apps/admin_audit/lib/hooks_handlers.php | 72 - apps/admin_dependencies_chk/appinfo/app.php | 4 - apps/admin_dependencies_chk/appinfo/info.xml | 10 - apps/admin_dependencies_chk/appinfo/version | 1 - apps/admin_dependencies_chk/css/style.css | 9 - apps/admin_dependencies_chk/settings.php | 102 - .../templates/settings.php | 16 - apps/admin_migrate/appinfo/app.php | 33 - apps/admin_migrate/appinfo/info.xml | 11 - apps/admin_migrate/appinfo/version | 1 - apps/admin_migrate/settings.php | 57 - apps/admin_migrate/templates/settings.php | 31 - apps/bookmarks/addBm.php | 33 - apps/bookmarks/ajax/addBookmark.php | 37 - apps/bookmarks/ajax/delBookmark.php | 41 - apps/bookmarks/ajax/editBookmark.php | 88 - apps/bookmarks/ajax/recordClick.php | 44 - apps/bookmarks/ajax/updateList.php | 50 - apps/bookmarks/appinfo/app.php | 19 - apps/bookmarks/appinfo/database.xml | 112 - apps/bookmarks/appinfo/info.xml | 11 - apps/bookmarks/appinfo/migrate.php | 68 - apps/bookmarks/appinfo/version | 1 - apps/bookmarks/bookmarksHelper.php | 130 - apps/bookmarks/css/bookmarks.css | 87 - apps/bookmarks/img/bookmarks.png | Bin 496 -> 0 bytes apps/bookmarks/index.php | 37 - apps/bookmarks/js/addBm.js | 16 - apps/bookmarks/js/bookmarks.js | 201 - apps/bookmarks/js/bookmarksearch.js | 23 - apps/bookmarks/l10n/xgettextfiles | 5 - apps/bookmarks/lib/bookmarks.php | 148 - apps/bookmarks/lib/search.php | 47 - apps/bookmarks/settings.php | 11 - apps/bookmarks/templates/addBm.php | 11 - apps/bookmarks/templates/bookmarklet.php | 8 - apps/bookmarks/templates/list.php | 26 - apps/bookmarks/templates/settings.php | 17 - apps/calendar/ajax/cache/rescan.php | 15 - apps/calendar/ajax/cache/status.php | 22 - apps/calendar/ajax/calendar/activation.php | 23 - apps/calendar/ajax/calendar/delete.php | 24 - apps/calendar/ajax/calendar/edit.form.php | 19 - apps/calendar/ajax/calendar/edit.php | 23 - apps/calendar/ajax/calendar/new.form.php | 22 - apps/calendar/ajax/calendar/new.php | 43 - apps/calendar/ajax/calendar/overview.php | 14 - apps/calendar/ajax/calendar/update.php | 48 - apps/calendar/ajax/categories/rescan.php | 42 - apps/calendar/ajax/changeview.php | 21 - apps/calendar/ajax/event/delete.php | 20 - apps/calendar/ajax/event/edit.form.php | 272 - apps/calendar/ajax/event/edit.php | 45 - apps/calendar/ajax/event/move.php | 46 - apps/calendar/ajax/event/new.form.php | 75 - apps/calendar/ajax/event/new.php | 24 - apps/calendar/ajax/event/resize.php | 38 - apps/calendar/ajax/events.php | 30 - apps/calendar/ajax/import/dialog.php | 15 - apps/calendar/ajax/import/dropimport.php | 73 - apps/calendar/ajax/import/import.php | 122 - apps/calendar/ajax/settings/getfirstday.php | 11 - .../ajax/settings/gettimezonedetection.php | 11 - apps/calendar/ajax/settings/guesstimezone.php | 26 - apps/calendar/ajax/settings/setfirstday.php | 15 - apps/calendar/ajax/settings/settimeformat.php | 15 - apps/calendar/ajax/settings/settimezone.php | 25 - apps/calendar/ajax/settings/timeformat.php | 11 - .../ajax/settings/timezonedetection.php | 16 - apps/calendar/ajax/share/activation.php | 11 - apps/calendar/ajax/share/changepermission.php | 48 - apps/calendar/ajax/share/dropdown.php | 18 - apps/calendar/ajax/share/share.php | 59 - apps/calendar/ajax/share/unshare.php | 51 - apps/calendar/appinfo/app.php | 33 - apps/calendar/appinfo/database.xml | 345 - apps/calendar/appinfo/info.xml | 19 - apps/calendar/appinfo/remote.php | 39 - apps/calendar/appinfo/update.php | 24 - apps/calendar/appinfo/version | 1 - apps/calendar/caldav.php | 6 - apps/calendar/css/style.css | 135 - apps/calendar/export.php | 30 - apps/calendar/img/Icon License | 2 - apps/calendar/img/icon.png | Bin 423 -> 0 bytes apps/calendar/img/icon.svg | 54 - apps/calendar/index.php | 64 - apps/calendar/js/calendar.js | 928 - apps/calendar/js/geo.js | 20 - apps/calendar/js/loader.js | 81 - apps/calendar/js/settings.js | 67 - apps/calendar/l10n/ar.php | 135 - apps/calendar/l10n/bg_BG.php | 40 - apps/calendar/l10n/ca.php | 162 - apps/calendar/l10n/cs_CZ.php | 162 - apps/calendar/l10n/da.php | 162 - apps/calendar/l10n/de.php | 162 - apps/calendar/l10n/el.php | 162 - apps/calendar/l10n/eo.php | 162 - apps/calendar/l10n/es.php | 162 - apps/calendar/l10n/et_EE.php | 162 - apps/calendar/l10n/eu.php | 159 - apps/calendar/l10n/fa.php | 162 - apps/calendar/l10n/fi_FI.php | 138 - apps/calendar/l10n/fr.php | 162 - apps/calendar/l10n/gl.php | 162 - apps/calendar/l10n/he.php | 162 - apps/calendar/l10n/hr.php | 158 - apps/calendar/l10n/hu_HU.php | 162 - apps/calendar/l10n/hy.php | 11 - apps/calendar/l10n/ia.php | 115 - apps/calendar/l10n/id.php | 40 - apps/calendar/l10n/it.php | 162 - apps/calendar/l10n/ja_JP.php | 160 - apps/calendar/l10n/ko.php | 161 - apps/calendar/l10n/lb.php | 132 - apps/calendar/l10n/lt_LT.php | 140 - apps/calendar/l10n/mk.php | 162 - apps/calendar/l10n/ms_MY.php | 135 - apps/calendar/l10n/nb_NO.php | 157 - apps/calendar/l10n/nl.php | 162 - apps/calendar/l10n/nn_NO.php | 135 - apps/calendar/l10n/pl.php | 162 - apps/calendar/l10n/pt_BR.php | 162 - apps/calendar/l10n/pt_PT.php | 162 - apps/calendar/l10n/ro.php | 162 - apps/calendar/l10n/ru.php | 159 - apps/calendar/l10n/sk_SK.php | 162 - apps/calendar/l10n/sl.php | 162 - apps/calendar/l10n/sr.php | 64 - apps/calendar/l10n/sr@latin.php | 64 - apps/calendar/l10n/sv.php | 162 - apps/calendar/l10n/th_TH.php | 162 - apps/calendar/l10n/tr.php | 162 - apps/calendar/l10n/uk.php | 89 - apps/calendar/l10n/xgettextfiles | 12 - apps/calendar/l10n/zh_CN.php | 162 - apps/calendar/l10n/zh_TW.php | 162 - apps/calendar/lib/alarm.php | 13 - apps/calendar/lib/app.php | 426 - apps/calendar/lib/attendees.php | 13 - apps/calendar/lib/calendar.php | 274 - apps/calendar/lib/connector_sabre.php | 308 - apps/calendar/lib/export.php | 94 - apps/calendar/lib/hooks.php | 29 - apps/calendar/lib/object.php | 937 - apps/calendar/lib/repeat.php | 204 - apps/calendar/lib/search.php | 49 - apps/calendar/lib/share.php | 298 - apps/calendar/settings.php | 17 - apps/calendar/share.php | 31 - apps/calendar/templates/calendar.php | 61 - .../templates/part.choosecalendar.php | 51 - .../part.choosecalendar.rowfields.php | 21 - .../part.choosecalendar.rowfields.shared.php | 4 - apps/calendar/templates/part.editcalendar.php | 44 - apps/calendar/templates/part.editevent.php | 13 - apps/calendar/templates/part.eventform.php | 251 - apps/calendar/templates/part.import.php | 30 - apps/calendar/templates/part.newevent.php | 9 - apps/calendar/templates/part.showevent.php | 243 - apps/calendar/templates/settings.php | 67 - apps/calendar/templates/share.dropdown.php | 77 - apps/contacts/ajax/activation.php | 28 - apps/contacts/ajax/addbook.php | 19 - apps/contacts/ajax/addcontact.php | 50 - apps/contacts/ajax/addproperty.php | 139 - .../ajax/categories/categoriesfor.php | 27 - apps/contacts/ajax/categories/delete.php | 47 - apps/contacts/ajax/categories/list.php | 15 - apps/contacts/ajax/categories/rescan.php | 16 - apps/contacts/ajax/chooseaddressbook.php | 15 - apps/contacts/ajax/contactdetails.php | 54 - apps/contacts/ajax/contacts.php | 74 - apps/contacts/ajax/createaddressbook.php | 36 - apps/contacts/ajax/cropphoto.php | 36 - apps/contacts/ajax/currentphoto.php | 53 - apps/contacts/ajax/deletebook.php | 33 - apps/contacts/ajax/deletecard.php | 45 - apps/contacts/ajax/deleteproperty.php | 45 - apps/contacts/ajax/editaddress.php | 41 - apps/contacts/ajax/editaddressbook.php | 16 - apps/contacts/ajax/editname.php | 34 - apps/contacts/ajax/importaddressbook.php | 23 - apps/contacts/ajax/importdialog.php | 15 - apps/contacts/ajax/loadcard.php | 49 - apps/contacts/ajax/loadintro.php | 31 - apps/contacts/ajax/loadphoto.php | 46 - apps/contacts/ajax/loghandler.php | 40 - apps/contacts/ajax/movetoaddressbook.php | 41 - apps/contacts/ajax/oc_photo.php | 60 - apps/contacts/ajax/savecrop.php | 107 - apps/contacts/ajax/saveproperty.php | 128 - apps/contacts/ajax/updateaddressbook.php | 38 - apps/contacts/ajax/uploadimport.php | 72 - apps/contacts/ajax/uploadphoto.php | 104 - apps/contacts/appinfo/app.php | 24 - apps/contacts/appinfo/database.xml | 137 - apps/contacts/appinfo/info.xml | 16 - apps/contacts/appinfo/migrate.php | 71 - apps/contacts/appinfo/remote.php | 55 - apps/contacts/appinfo/update.php | 25 - apps/contacts/appinfo/version | 1 - apps/contacts/carddav.php | 6 - apps/contacts/css/contacts.css | 126 - apps/contacts/css/jquery.Jcrop.css | 84 - apps/contacts/css/jquery.combobox.css | 3 - apps/contacts/export.php | 34 - apps/contacts/img/Jcrop.gif | Bin 329 -> 0 bytes apps/contacts/img/contact-new.png | Bin 658 -> 0 bytes apps/contacts/img/contact-new.svg | 129 - apps/contacts/img/globe.svg | 102 - apps/contacts/img/person.png | Bin 978 -> 0 bytes apps/contacts/img/person.svg | 175 - apps/contacts/img/person_large.png | Bin 7929 -> 0 bytes apps/contacts/import.php | 112 - apps/contacts/index.php | 62 - apps/contacts/js/contacts.js | 1805 - apps/contacts/js/expanding.js | 118 - apps/contacts/js/jquery.Jcrop.js | 1765 - apps/contacts/js/jquery.Jcrop.min.js | 255 - apps/contacts/js/jquery.combobox.js | 158 - apps/contacts/js/jquery.multi-autocomplete.js | 94 - apps/contacts/js/loader.js | 86 - apps/contacts/l10n/ar.php | 58 - apps/contacts/l10n/ca.php | 157 - apps/contacts/l10n/cs_CZ.php | 157 - apps/contacts/l10n/da.php | 157 - apps/contacts/l10n/de.php | 157 - apps/contacts/l10n/el.php | 157 - apps/contacts/l10n/eo.php | 146 - apps/contacts/l10n/es.php | 157 - apps/contacts/l10n/et_EE.php | 157 - apps/contacts/l10n/eu.php | 124 - apps/contacts/l10n/fa.php | 157 - apps/contacts/l10n/fi_FI.php | 109 - apps/contacts/l10n/fr.php | 149 - apps/contacts/l10n/gl.php | 58 - apps/contacts/l10n/he.php | 65 - apps/contacts/l10n/hr.php | 63 - apps/contacts/l10n/hu_HU.php | 157 - apps/contacts/l10n/ia.php | 94 - apps/contacts/l10n/it.php | 157 - apps/contacts/l10n/ja_JP.php | 152 - apps/contacts/l10n/ko.php | 92 - apps/contacts/l10n/lb.php | 44 - apps/contacts/l10n/lt_LT.php | 49 - apps/contacts/l10n/mk.php | 157 - apps/contacts/l10n/ms_MY.php | 58 - apps/contacts/l10n/nb_NO.php | 135 - apps/contacts/l10n/nl.php | 142 - apps/contacts/l10n/nn_NO.php | 58 - apps/contacts/l10n/pl.php | 157 - apps/contacts/l10n/pt_BR.php | 157 - apps/contacts/l10n/pt_PT.php | 129 - apps/contacts/l10n/ro.php | 92 - apps/contacts/l10n/ru.php | 127 - apps/contacts/l10n/sk_SK.php | 155 - apps/contacts/l10n/sl.php | 157 - apps/contacts/l10n/sr.php | 47 - apps/contacts/l10n/sr@latin.php | 29 - apps/contacts/l10n/sv.php | 143 - apps/contacts/l10n/th_TH.php | 157 - apps/contacts/l10n/tr.php | 157 - apps/contacts/l10n/uk.php | 29 - apps/contacts/l10n/xgettextfiles | 18 - apps/contacts/l10n/zh_CN.php | 127 - apps/contacts/l10n/zh_TW.php | 93 - apps/contacts/lib/VCFExportPlugin.php | 100 - apps/contacts/lib/addressbook.php | 327 - apps/contacts/lib/app.php | 230 - apps/contacts/lib/connector_sabre.php | 198 - apps/contacts/lib/hooks.php | 110 - apps/contacts/lib/search.php | 21 - apps/contacts/lib/vcard.php | 623 - apps/contacts/photo.php | 72 - apps/contacts/settings.php | 6 - apps/contacts/templates/index.php | 29 - .../templates/part.chooseaddressbook.php | 25 - .../part.chooseaddressbook.rowfields.php | 18 - apps/contacts/templates/part.contact.php | 129 - apps/contacts/templates/part.cropphoto.php | 68 - .../templates/part.edit_address_dialog.php | 62 - .../templates/part.edit_categories_dialog.php | 16 - .../templates/part.edit_name_dialog.php | 58 - .../templates/part.editaddressbook.php | 31 - apps/contacts/templates/part.import.php | 27 - .../templates/part.importaddressbook.php | 38 - apps/contacts/templates/part.no_contacts.php | 7 - apps/contacts/templates/settings.php | 19 - apps/contacts/thumbnail.php | 79 - apps/contacts/tmpphoto.php | 34 - apps/external/ajax/setsites.php | 25 - apps/external/appinfo/app.php | 33 - apps/external/appinfo/info.xml | 10 - apps/external/appinfo/version | 1 - apps/external/css/style.css | 14 - apps/external/img/external.png | Bin 459 -> 0 bytes apps/external/img/external.svg | 292 - apps/external/index.php | 42 - apps/external/js/admin.js | 57 - apps/external/lib/external.php | 34 - apps/external/settings.php | 9 - apps/external/templates/frame.php | 26 - apps/external/templates/settings.php | 21 - apps/files/admin.php | 11 +- apps/files/ajax/autocomplete.php | 24 +- apps/files/ajax/delete.php | 6 +- apps/files/ajax/list.php | 12 +- apps/files/ajax/mimeicon.php | 6 - apps/files/ajax/move.php | 4 +- apps/files/ajax/newfile.php | 91 +- apps/files/ajax/newfolder.php | 10 +- apps/files/ajax/rawlist.php | 8 +- apps/files/ajax/scan.php | 27 +- apps/files/ajax/timezone.php | 1 - apps/files/ajax/upload.php | 17 +- apps/files/appinfo/filesync.php | 64 + apps/files/appinfo/info.xml | 3 +- apps/files/appinfo/update.php | 15 +- apps/files/appinfo/version | 2 +- apps/files/css/files.css | 16 +- apps/files/download.php | 4 +- apps/files/index.php | 31 +- apps/files/js/fileactions.js | 70 +- apps/files/js/filelist.js | 293 +- apps/files/js/files.js | 242 +- apps/files/l10n/ar.php | 4 +- apps/files/l10n/bg_BG.php | 21 +- apps/files/l10n/ca.php | 41 +- apps/files/l10n/cs_CZ.php | 71 +- apps/files/l10n/da.php | 41 +- apps/files/l10n/de.php | 61 +- apps/files/l10n/el.php | 57 +- apps/files/l10n/eo.php | 41 +- apps/files/l10n/es.php | 43 +- apps/files/l10n/es_AR.php | 71 + apps/files/l10n/et_EE.php | 26 +- apps/files/l10n/eu.php | 41 +- apps/files/l10n/fa.php | 21 +- apps/files/l10n/fi_FI.php | 39 +- apps/files/l10n/fr.php | 45 +- apps/files/l10n/gl.php | 28 +- apps/files/l10n/he.php | 15 +- apps/files/l10n/hr.php | 41 +- apps/files/l10n/hu_HU.php | 21 +- apps/files/l10n/ia.php | 4 +- apps/files/l10n/id.php | 23 +- apps/files/l10n/it.php | 41 +- apps/files/l10n/ja_JP.php | 41 +- apps/files/l10n/ko.php | 21 +- apps/files/l10n/lb.php | 21 +- apps/files/l10n/lt_LT.php | 25 +- apps/files/l10n/lv.php | 42 + apps/files/l10n/mk.php | 14 +- apps/files/l10n/ms_MY.php | 34 +- apps/files/l10n/nb_NO.php | 22 +- apps/files/l10n/nl.php | 41 +- apps/files/l10n/nn_NO.php | 4 +- apps/files/l10n/oc.php | 71 + apps/files/l10n/pl.php | 41 +- apps/files/l10n/pt_BR.php | 41 +- apps/files/l10n/pt_PT.php | 53 +- apps/files/l10n/ro.php | 41 +- apps/files/l10n/ru.php | 44 +- apps/files/l10n/ru_RU.php | 71 + apps/files/l10n/si_LK.php | 18 + apps/files/l10n/sk_SK.php | 47 +- apps/files/l10n/sl.php | 31 +- apps/files/l10n/sr.php | 4 +- apps/files/l10n/sr@latin.php | 4 +- apps/files/l10n/sv.php | 55 +- apps/files/l10n/th_TH.php | 41 +- apps/files/l10n/tr.php | 22 +- apps/files/l10n/uk.php | 25 +- apps/files/l10n/vi.php | 54 + apps/files/l10n/zh_CN.GB2312.php | 71 + apps/files/l10n/zh_CN.php | 41 +- apps/files/l10n/zh_TW.php | 13 +- apps/files/settings.php | 8 +- apps/files/templates/admin.php | 5 +- apps/files/templates/index.php | 29 +- apps/files/templates/part.breadcrumb.php | 4 +- apps/files/templates/part.list.php | 12 +- apps/files_archive/appinfo/app.php | 13 - apps/files_archive/appinfo/info.xml | 14 - apps/files_archive/appinfo/version | 1 - apps/files_archive/js/archive.js | 19 - apps/files_archive/lib/storage.php | 146 - apps/files_archive/tests/data/lorem.txt | 4 - apps/files_archive/tests/storage.php | 39 - apps/files_encryption/appinfo/info.xml | 4 +- .../l10n/.gitkeep | 0 apps/files_encryption/l10n/ca.php | 6 + apps/files_encryption/l10n/cs_CZ.php | 6 + apps/files_encryption/l10n/da.php | 6 + apps/files_encryption/l10n/de.php | 6 + apps/files_encryption/l10n/el.php | 6 + apps/files_encryption/l10n/eo.php | 6 + apps/files_encryption/l10n/es.php | 6 + apps/files_encryption/l10n/es_AR.php | 6 + apps/files_encryption/l10n/et_EE.php | 6 + apps/files_encryption/l10n/eu.php | 6 + apps/files_encryption/l10n/fa.php | 5 + apps/files_encryption/l10n/fi_FI.php | 6 + apps/files_encryption/l10n/fr.php | 6 + apps/files_encryption/l10n/gl.php | 6 + apps/files_encryption/l10n/hu_HU.php | 6 + apps/files_encryption/l10n/it.php | 6 + apps/files_encryption/l10n/ja_JP.php | 6 + apps/files_encryption/l10n/ku_IQ.php | 6 + apps/files_encryption/l10n/lt_LT.php | 6 + apps/files_encryption/l10n/nb_NO.php | 6 + apps/files_encryption/l10n/nl.php | 6 + apps/files_encryption/l10n/pl.php | 6 + apps/files_encryption/l10n/pt_BR.php | 6 + apps/files_encryption/l10n/pt_PT.php | 6 + apps/files_encryption/l10n/ro.php | 6 + apps/files_encryption/l10n/ru.php | 6 + apps/files_encryption/l10n/ru_RU.php | 6 + apps/files_encryption/l10n/sk_SK.php | 6 + apps/files_encryption/l10n/sl.php | 6 + apps/files_encryption/l10n/sv.php | 6 + apps/files_encryption/l10n/th_TH.php | 6 + apps/files_encryption/l10n/vi.php | 6 + apps/files_encryption/l10n/zh_CN.GB2312.php | 6 + apps/files_encryption/l10n/zh_CN.php | 6 + apps/files_encryption/l10n/zh_TW.php | 6 + apps/files_encryption/tests/crypt.php | 1 + apps/files_encryption/tests/out.txt | 78 + .../ajax/addRootCertificate.php | 46 +- apps/files_external/ajax/dropbox.php | 2 - apps/files_external/ajax/google.php | 2 - .../ajax/removeRootCertificate.php | 13 +- apps/files_external/appinfo/info.xml | 2 +- apps/files_external/css/settings.css | 2 + apps/files_external/js/dropbox.js | 61 +- apps/files_external/js/google.js | 87 +- apps/files_external/js/settings.js | 37 +- .../l10n/.gitkeep} | 0 apps/files_external/l10n/ca.php | 24 + apps/files_external/l10n/cs_CZ.php | 24 + apps/files_external/l10n/da.php | 24 + apps/files_external/l10n/de.php | 24 + apps/files_external/l10n/el.php | 24 + apps/files_external/l10n/eo.php | 24 + apps/files_external/l10n/es.php | 24 + apps/files_external/l10n/es_AR.php | 24 + apps/files_external/l10n/et_EE.php | 18 + apps/files_external/l10n/eu.php | 24 + apps/files_external/l10n/fi_FI.php | 23 + apps/files_external/l10n/fr.php | 24 + apps/files_external/l10n/gl.php | 18 + apps/files_external/l10n/he.php | 13 + apps/files_external/l10n/it.php | 24 + apps/files_external/l10n/ja_JP.php | 24 + apps/files_external/l10n/lt_LT.php | 9 + apps/files_external/l10n/nb_NO.php | 8 + apps/files_external/l10n/nl.php | 24 + apps/files_external/l10n/pl.php | 24 + apps/files_external/l10n/pt_BR.php | 24 + apps/files_external/l10n/pt_PT.php | 24 + apps/files_external/l10n/ro.php | 18 + apps/files_external/l10n/ru.php | 18 + apps/files_external/l10n/ru_RU.php | 24 + apps/files_external/l10n/sk_SK.php | 23 + apps/files_external/l10n/sl.php | 18 + apps/files_external/l10n/sv.php | 24 + apps/files_external/l10n/th_TH.php | 24 + apps/files_external/l10n/uk.php | 5 + apps/files_external/l10n/vi.php | 18 + apps/files_external/l10n/zh_CN.GB2312.php | 24 + apps/files_external/lib/amazons3.php | 10 +- apps/files_external/lib/config.php | 100 +- apps/files_external/lib/dropbox.php | 39 +- apps/files_external/lib/ftp.php | 27 +- apps/files_external/lib/google.php | 49 +- apps/files_external/lib/smb.php | 40 +- apps/files_external/lib/streamwrapper.php | 34 +- apps/files_external/lib/swift.php | 210 +- apps/files_external/lib/webdav.php | 111 +- apps/files_external/personal.php | 2 - apps/files_external/settings.php | 4 +- apps/files_external/templates/settings.php | 52 +- apps/files_external/tests/amazons3.php | 63 +- apps/files_external/tests/config.php | 11 +- apps/files_external/tests/dropbox.php | 27 + apps/files_external/tests/ftp.php | 29 +- apps/files_external/tests/google.php | 65 +- apps/files_external/tests/smb.php | 27 +- apps/files_external/tests/swift.php | 32 +- apps/files_external/tests/webdav.php | 27 +- apps/files_imageviewer/appinfo/app.php | 6 - apps/files_imageviewer/appinfo/info.xml | 11 - apps/files_imageviewer/appinfo/version | 1 - .../css/jquery.fancybox-1.3.4.css | 359 - apps/files_imageviewer/img/blank.gif | Bin 43 -> 0 bytes apps/files_imageviewer/img/fancy_close.png | Bin 1517 -> 0 bytes apps/files_imageviewer/img/fancy_loading.png | Bin 10195 -> 0 bytes apps/files_imageviewer/img/fancy_nav_left.png | Bin 1446 -> 0 bytes .../files_imageviewer/img/fancy_nav_right.png | Bin 1454 -> 0 bytes apps/files_imageviewer/img/fancy_shadow_e.png | Bin 107 -> 0 bytes apps/files_imageviewer/img/fancy_shadow_n.png | Bin 106 -> 0 bytes .../files_imageviewer/img/fancy_shadow_ne.png | Bin 347 -> 0 bytes .../files_imageviewer/img/fancy_shadow_nw.png | Bin 324 -> 0 bytes apps/files_imageviewer/img/fancy_shadow_s.png | Bin 111 -> 0 bytes .../files_imageviewer/img/fancy_shadow_se.png | Bin 352 -> 0 bytes .../files_imageviewer/img/fancy_shadow_sw.png | Bin 340 -> 0 bytes apps/files_imageviewer/img/fancy_shadow_w.png | Bin 103 -> 0 bytes .../img/fancy_title_left.png | Bin 503 -> 0 bytes .../img/fancy_title_main.png | Bin 96 -> 0 bytes .../img/fancy_title_over.png | Bin 70 -> 0 bytes .../img/fancy_title_right.png | Bin 506 -> 0 bytes apps/files_imageviewer/img/fancybox-x.png | Bin 203 -> 0 bytes apps/files_imageviewer/img/fancybox-y.png | Bin 176 -> 0 bytes apps/files_imageviewer/img/fancybox.png | Bin 15287 -> 0 bytes .../js/jquery.fancybox-1.3.4.js | 1158 - .../js/jquery.fancybox-1.3.4.pack.js | 1 - .../js/jquery.mousewheel-3.0.4.js | 78 - .../js/jquery.mousewheel-3.0.4.pack.js | 14 - apps/files_imageviewer/js/lightbox.js | 31 - apps/files_pdfviewer/appinfo/app.php | 8 - apps/files_pdfviewer/appinfo/info.xml | 11 - apps/files_pdfviewer/appinfo/version | 1 - apps/files_pdfviewer/css/history.png | Bin 539 -> 0 bytes apps/files_pdfviewer/css/viewer.css | 267 - apps/files_pdfviewer/js/pdfjs/LICENSE | 30 - apps/files_pdfviewer/js/pdfjs/README | 7 - apps/files_pdfviewer/js/pdfjs/build/pdf.js | 33830 ---------------- .../files_pdfviewer/js/pdfjs/compatibility.js | 340 - apps/files_pdfviewer/js/pdfjs/update.sh | 6 - apps/files_pdfviewer/js/pdfjs/viewer.js | 1873 - .../js/pdfjs/web/images/bookmark.svg | 662 - .../js/pdfjs/web/images/check.svg | 3 - .../js/pdfjs/web/images/comment.svg | 3 - .../js/pdfjs/web/images/document-print.svg | 533 - .../js/pdfjs/web/images/download.svg | 620 - .../js/pdfjs/web/images/go-down.svg | 201 - .../js/pdfjs/web/images/go-up.svg | 197 - .../js/pdfjs/web/images/nav-outline.svg | 202 - .../js/pdfjs/web/images/nav-thumbs.svg | 283 - .../js/pdfjs/web/images/pin-down.svg | 297 - .../js/pdfjs/web/images/pin-up.svg | 230 - .../js/pdfjs/web/images/zoom-in.svg | 437 - .../js/pdfjs/web/images/zoom-out.svg | 425 - apps/files_pdfviewer/js/pdfview.js | 762 - apps/files_pdfviewer/js/viewer.js | 50 - apps/files_sharing/ajax/email.php | 13 - apps/files_sharing/ajax/getitem.php | 66 - apps/files_sharing/ajax/getstatuses.php | 22 - apps/files_sharing/ajax/setpermissions.php | 12 - apps/files_sharing/ajax/share.php | 37 - apps/files_sharing/ajax/toggleresharing.php | 9 - apps/files_sharing/ajax/unshare.php | 11 - apps/files_sharing/ajax/userautocomplete.php | 30 - apps/files_sharing/appinfo/app.php | 27 +- apps/files_sharing/appinfo/database.xml | 42 - apps/files_sharing/appinfo/info.xml | 6 +- apps/files_sharing/appinfo/update.php | 72 + apps/files_sharing/appinfo/version | 2 +- apps/files_sharing/css/public.css | 11 + apps/files_sharing/css/sharing.css | 15 - apps/files_sharing/get.php | 88 - apps/files_sharing/js/list.js | 54 - apps/files_sharing/js/public.js | 49 + apps/files_sharing/js/settings.js | 9 - apps/files_sharing/js/share.js | 387 +- .../l10n/.gitkeep} | 0 apps/files_sharing/l10n/ca.php | 9 + apps/files_sharing/l10n/cs_CZ.php | 9 + apps/files_sharing/l10n/da.php | 9 + apps/files_sharing/l10n/de.php | 9 + apps/files_sharing/l10n/el.php | 9 + apps/files_sharing/l10n/eo.php | 9 + apps/files_sharing/l10n/es.php | 9 + apps/files_sharing/l10n/es_AR.php | 9 + apps/files_sharing/l10n/et_EE.php | 7 + apps/files_sharing/l10n/eu.php | 9 + apps/files_sharing/l10n/fa.php | 6 + apps/files_sharing/l10n/fi_FI.php | 9 + apps/files_sharing/l10n/fr.php | 9 + apps/files_sharing/l10n/gl.php | 7 + apps/files_sharing/l10n/he.php | 9 + apps/files_sharing/l10n/hu_HU.php | 6 + apps/files_sharing/l10n/it.php | 9 + apps/files_sharing/l10n/ja_JP.php | 9 + apps/files_sharing/l10n/ku_IQ.php | 9 + apps/files_sharing/l10n/lt_LT.php | 6 + apps/files_sharing/l10n/nb_NO.php | 6 + apps/files_sharing/l10n/nl.php | 9 + apps/files_sharing/l10n/pl.php | 9 + apps/files_sharing/l10n/pt_BR.php | 9 + apps/files_sharing/l10n/pt_PT.php | 9 + apps/files_sharing/l10n/ro.php | 9 + apps/files_sharing/l10n/ru.php | 7 + apps/files_sharing/l10n/ru_RU.php | 9 + apps/files_sharing/l10n/sk_SK.php | 9 + apps/files_sharing/l10n/sl.php | 9 + apps/files_sharing/l10n/sv.php | 9 + apps/files_sharing/l10n/th_TH.php | 9 + apps/files_sharing/l10n/uk.php | 4 + apps/files_sharing/l10n/vi.php | 7 + apps/files_sharing/l10n/zh_CN.GB2312.php | 9 + apps/files_sharing/l10n/zh_CN.php | 9 + apps/files_sharing/l10n/zh_TW.php | 6 + apps/files_sharing/lib/share/file.php | 127 + apps/files_sharing/lib/share/folder.php | 71 + apps/files_sharing/lib/sharedstorage.php | 450 + apps/files_sharing/lib_share.php | 515 - apps/files_sharing/list.php | 35 - apps/files_sharing/public.php | 199 + apps/files_sharing/settings.php | 9 - apps/files_sharing/sharedstorage.php | 541 - apps/files_sharing/templates/authenticate.php | 9 + apps/files_sharing/templates/list.php | 30 - apps/files_sharing/templates/public.php | 35 + apps/files_sharing/templates/settings.php | 6 - apps/files_sharing_log/appinfo/app.php | 22 - apps/files_sharing_log/appinfo/database.xml | 44 - apps/files_sharing_log/appinfo/info.xml | 10 - apps/files_sharing_log/appinfo/version | 1 - apps/files_sharing_log/css/style.css | 7 - apps/files_sharing_log/index.php | 21 - apps/files_sharing_log/log.php | 34 - apps/files_sharing_log/templates/index.php | 42 - apps/files_texteditor/ajax/loadfile.php | 51 - apps/files_texteditor/ajax/mtime.php | 49 - apps/files_texteditor/ajax/savefile.php | 76 - apps/files_texteditor/appinfo/app.php | 6 - apps/files_texteditor/appinfo/info.xml | 11 - apps/files_texteditor/appinfo/version | 1 - .../DroidSansMono/DroidSansMono-webfont.eot | Bin 78034 -> 0 bytes .../DroidSansMono/DroidSansMono-webfont.svg | 630 - .../DroidSansMono/DroidSansMono-webfont.ttf | Bin 77800 -> 0 bytes .../DroidSansMono/DroidSansMono-webfont.woff | Bin 46192 -> 0 bytes .../DroidSansMono/Google Android License.txt | 18 - .../css/DroidSansMono/demo.html | 33 - .../css/DroidSansMono/stylesheet.css | 15 - apps/files_texteditor/css/style.css | 11 - apps/files_texteditor/js/aceeditor/LICENSE | 476 - .../js/aceeditor/ace-compat-uncompressed.js | 480 - .../js/aceeditor/ace-compat.js | 1 - .../js/aceeditor/ace-uncompressed.js | 16616 -------- apps/files_texteditor/js/aceeditor/ace.js | 9 - .../keybinding-emacs-uncompressed.js | 150 - .../js/aceeditor/keybinding-emacs.js | 1 - .../aceeditor/keybinding-vim-uncompressed.js | 138 - .../js/aceeditor/keybinding-vim.js | 1 - .../js/aceeditor/mode-c_cpp-uncompressed.js | 920 - .../js/aceeditor/mode-c_cpp.js | 1 - .../js/aceeditor/mode-clojure-uncompressed.js | 422 - .../js/aceeditor/mode-clojure.js | 1 - .../js/aceeditor/mode-coffee-uncompressed.js | 605 - .../js/aceeditor/mode-coffee.js | 1 - .../aceeditor/mode-coldfusion-uncompressed.js | 2433 -- .../js/aceeditor/mode-coldfusion.js | 1 - .../js/aceeditor/mode-csharp-uncompressed.js | 770 - .../js/aceeditor/mode-csharp.js | 1 - .../js/aceeditor/mode-css-uncompressed.js | 640 - .../files_texteditor/js/aceeditor/mode-css.js | 1 - .../js/aceeditor/mode-groovy-uncompressed.js | 1370 - .../js/aceeditor/mode-groovy.js | 1 - .../js/aceeditor/mode-haxe-uncompressed.js | 770 - .../js/aceeditor/mode-haxe.js | 1 - .../js/aceeditor/mode-html-uncompressed.js | 2449 -- .../js/aceeditor/mode-html.js | 1 - .../js/aceeditor/mode-java-uncompressed.js | 1372 - .../js/aceeditor/mode-java.js | 1 - .../aceeditor/mode-javascript-uncompressed.js | 1203 - .../js/aceeditor/mode-javascript.js | 1 - .../js/aceeditor/mode-json-uncompressed.js | 698 - .../js/aceeditor/mode-json.js | 1 - .../js/aceeditor/mode-latex-uncompressed.js | 95 - .../js/aceeditor/mode-latex.js | 1 - .../js/aceeditor/mode-less-uncompressed.js | 654 - .../js/aceeditor/mode-less.js | 1 - .../js/aceeditor/mode-liquid-uncompressed.js | 1332 - .../js/aceeditor/mode-liquid.js | 1 - .../js/aceeditor/mode-lua-uncompressed.js | 523 - .../files_texteditor/js/aceeditor/mode-lua.js | 1 - .../aceeditor/mode-markdown-uncompressed.js | 2897 -- .../js/aceeditor/mode-markdown.js | 1 - .../js/aceeditor/mode-ocaml-uncompressed.js | 539 - .../js/aceeditor/mode-ocaml.js | 1 - .../js/aceeditor/mode-perl-uncompressed.js | 573 - .../js/aceeditor/mode-perl.js | 1 - .../js/aceeditor/mode-pgsql-uncompressed.js | 1107 - .../js/aceeditor/mode-pgsql.js | 1 - .../js/aceeditor/mode-php-uncompressed.js | 1886 - .../files_texteditor/js/aceeditor/mode-php.js | 1 - .../aceeditor/mode-powershell-uncompressed.js | 708 - .../js/aceeditor/mode-powershell.js | 1 - .../js/aceeditor/mode-python-uncompressed.js | 506 - .../js/aceeditor/mode-python.js | 1 - .../js/aceeditor/mode-ruby-uncompressed.js | 391 - .../js/aceeditor/mode-ruby.js | 1 - .../js/aceeditor/mode-scad-uncompressed.js | 908 - .../js/aceeditor/mode-scad.js | 1 - .../js/aceeditor/mode-scala-uncompressed.js | 1372 - .../js/aceeditor/mode-scala.js | 1 - .../js/aceeditor/mode-scss-uncompressed.js | 678 - .../js/aceeditor/mode-scss.js | 1 - .../js/aceeditor/mode-sh-uncompressed.js | 281 - apps/files_texteditor/js/aceeditor/mode-sh.js | 1 - .../js/aceeditor/mode-sql-uncompressed.js | 159 - .../files_texteditor/js/aceeditor/mode-sql.js | 1 - .../js/aceeditor/mode-svg-uncompressed.js | 2112 - .../files_texteditor/js/aceeditor/mode-svg.js | 1 - .../js/aceeditor/mode-textile-uncompressed.js | 254 - .../js/aceeditor/mode-textile.js | 1 - .../js/aceeditor/mode-xml-uncompressed.js | 1009 - .../files_texteditor/js/aceeditor/mode-xml.js | 1 - .../js/aceeditor/mode-xquery-uncompressed.js | 540 - .../js/aceeditor/mode-xquery.js | 1 - .../js/aceeditor/theme-clouds-uncompressed.js | 155 - .../js/aceeditor/theme-clouds.js | 1 - .../js/aceeditor/worker-coffee.js | 7477 ---- .../js/aceeditor/worker-css.js | 11714 ------ .../js/aceeditor/worker-javascript.js | 10614 ----- .../js/aceeditor/worker-json.js | 3083 -- apps/files_texteditor/js/editor.js | 331 - apps/files_versions/ajax/expireAll.php | 13 +- apps/files_versions/ajax/getVersions.php | 8 +- apps/files_versions/ajax/rollbackVersion.php | 3 +- apps/files_versions/ajax/togglesettings.php | 1 + apps/files_versions/appinfo/api.php | 34 + apps/files_versions/appinfo/app.php | 2 +- apps/files_versions/appinfo/info.xml | 2 +- apps/files_versions/appinfo/update.php | 15 + apps/files_versions/appinfo/version | 2 +- apps/files_versions/history.php | 46 +- apps/files_versions/js/settings-personal.js | 28 +- apps/files_versions/js/versions.js | 94 +- apps/files_versions/l10n/.gitkeep | 0 apps/files_versions/l10n/ca.php | 8 + apps/files_versions/l10n/cs_CZ.php | 8 + apps/files_versions/l10n/da.php | 8 + apps/files_versions/l10n/de.php | 8 + apps/files_versions/l10n/el.php | 8 + apps/files_versions/l10n/eo.php | 8 + apps/files_versions/l10n/es.php | 8 + apps/files_versions/l10n/es_AR.php | 8 + apps/files_versions/l10n/et_EE.php | 5 + apps/files_versions/l10n/eu.php | 8 + apps/files_versions/l10n/fa.php | 3 + apps/files_versions/l10n/fi_FI.php | 8 + apps/files_versions/l10n/fr.php | 8 + apps/files_versions/l10n/gl.php | 7 + apps/files_versions/l10n/he.php | 5 + apps/files_versions/l10n/it.php | 8 + apps/files_versions/l10n/ja_JP.php | 8 + apps/files_versions/l10n/ku_IQ.php | 8 + apps/files_versions/l10n/lt_LT.php | 3 + apps/files_versions/l10n/nb_NO.php | 3 + apps/files_versions/l10n/nl.php | 8 + apps/files_versions/l10n/pl.php | 8 + apps/files_versions/l10n/pt_BR.php | 8 + apps/files_versions/l10n/pt_PT.php | 8 + apps/files_versions/l10n/ro.php | 8 + apps/files_versions/l10n/ru.php | 5 + apps/files_versions/l10n/ru_RU.php | 8 + apps/files_versions/l10n/sk_SK.php | 8 + apps/files_versions/l10n/sl.php | 8 + apps/files_versions/l10n/sv.php | 8 + apps/files_versions/l10n/th_TH.php | 8 + apps/files_versions/l10n/vi.php | 5 + apps/files_versions/l10n/zh_CN.GB2312.php | 8 + apps/files_versions/l10n/zh_CN.php | 8 + apps/files_versions/lib/hooks.php | 33 +- apps/files_versions/lib/versions.php | 609 +- apps/files_versions/settings-personal.php | 1 - apps/files_versions/templates/history.php | 6 +- .../templates/settings-personal.php | 13 +- apps/files_versions/templates/settings.php | 5 +- apps/gallery/ajax/createAlbum.php | 30 - apps/gallery/ajax/galleryOp.php | 188 - apps/gallery/ajax/sharing.php | 117 - apps/gallery/ajax/thumbnail.php | 36 - apps/gallery/appinfo/app.php | 55 - apps/gallery/appinfo/database.xml | 60 - apps/gallery/appinfo/info.xml | 15 - apps/gallery/appinfo/update.php | 11 - apps/gallery/appinfo/version | 1 - apps/gallery/css/sharing.css | 8 - apps/gallery/css/styles.css | 14 - apps/gallery/css/supersized.css | 25 - apps/gallery/css/supersized.shutter.css | 74 - apps/gallery/img/breadcrumb.png | Bin 220 -> 0 bytes apps/gallery/img/delete.png | Bin 275 -> 0 bytes apps/gallery/img/loading.gif | Bin 1849 -> 0 bytes apps/gallery/img/rename.png | Bin 310 -> 0 bytes apps/gallery/img/share.png | Bin 377 -> 0 bytes apps/gallery/img/supersized/back.png | Bin 2629 -> 0 bytes apps/gallery/img/supersized/bg-black.png | Bin 1074 -> 0 bytes apps/gallery/img/supersized/bg-hover.png | Bin 960 -> 0 bytes .../img/supersized/button-tray-down.png | Bin 1506 -> 0 bytes .../gallery/img/supersized/button-tray-up.png | Bin 1466 -> 0 bytes apps/gallery/img/supersized/forward.png | Bin 2614 -> 0 bytes apps/gallery/img/supersized/nav-bg.png | Bin 995 -> 0 bytes apps/gallery/img/supersized/nav-dot.png | Bin 1901 -> 0 bytes apps/gallery/img/supersized/pause.png | Bin 1131 -> 0 bytes apps/gallery/img/supersized/play.png | Bin 1562 -> 0 bytes apps/gallery/img/supersized/progress-back.png | Bin 929 -> 0 bytes apps/gallery/img/supersized/progress-bar.png | Bin 929 -> 0 bytes apps/gallery/img/supersized/progress.gif | Bin 2608 -> 0 bytes .../img/supersized/supersized-logo.png | Bin 3982 -> 0 bytes apps/gallery/img/supersized/thumb-back.png | Bin 2122 -> 0 bytes apps/gallery/img/supersized/thumb-forward.png | Bin 2118 -> 0 bytes apps/gallery/index.php | 105 - apps/gallery/js/albums.js | 101 - apps/gallery/js/jquery.easing.min.js | 71 - apps/gallery/js/pictures.js | 68 - apps/gallery/js/scanner.js | 34 - apps/gallery/js/sharing.js | 57 - apps/gallery/js/slideshow.js | 58 - apps/gallery/js/supersized.3.2.7.js | 930 - apps/gallery/js/supersized.3.2.7.min.js | 13 - apps/gallery/js/supersized.shutter.js | 337 - apps/gallery/js/supersized.shutter.min.js | 14 - apps/gallery/l10n/ar.php | 4 - apps/gallery/l10n/ca.php | 12 - apps/gallery/l10n/cs_CZ.php | 12 - apps/gallery/l10n/da.php | 12 - apps/gallery/l10n/de.php | 12 - apps/gallery/l10n/el.php | 12 - apps/gallery/l10n/eo.php | 12 - apps/gallery/l10n/es.php | 12 - apps/gallery/l10n/et_EE.php | 12 - apps/gallery/l10n/eu.php | 12 - apps/gallery/l10n/fa.php | 12 - apps/gallery/l10n/fi_FI.php | 12 - apps/gallery/l10n/fr.php | 12 - apps/gallery/l10n/gl.php | 12 - apps/gallery/l10n/hr.php | 12 - apps/gallery/l10n/hu_HU.php | 12 - apps/gallery/l10n/ia.php | 4 - apps/gallery/l10n/id.php | 12 - apps/gallery/l10n/it.php | 12 - apps/gallery/l10n/ja_JP.php | 12 - apps/gallery/l10n/ko.php | 12 - apps/gallery/l10n/lb.php | 12 - apps/gallery/l10n/lt_LT.php | 12 - apps/gallery/l10n/mk.php | 12 - apps/gallery/l10n/ms_MY.php | 4 - apps/gallery/l10n/nb_NO.php | 12 - apps/gallery/l10n/nl.php | 12 - apps/gallery/l10n/nn_NO.php | 4 - apps/gallery/l10n/pl.php | 12 - apps/gallery/l10n/pt_BR.php | 12 - apps/gallery/l10n/pt_PT.php | 12 - apps/gallery/l10n/ro.php | 12 - apps/gallery/l10n/ru.php | 12 - apps/gallery/l10n/sk_SK.php | 12 - apps/gallery/l10n/sl.php | 12 - apps/gallery/l10n/sr.php | 4 - apps/gallery/l10n/sv.php | 12 - apps/gallery/l10n/th_TH.php | 12 - apps/gallery/l10n/tr.php | 12 - apps/gallery/l10n/uk.php | 4 - apps/gallery/l10n/zh_CN.php | 12 - apps/gallery/l10n/zh_TW.php | 12 - apps/gallery/lib/album.php | 111 - apps/gallery/lib/hooks_handlers.php | 40 - apps/gallery/lib/images_utils.php | 62 - apps/gallery/lib/managers.php | 113 - apps/gallery/lib/photo.php | 103 - apps/gallery/lib/scanner.php | 145 - apps/gallery/lib/sharing.php | 89 - apps/gallery/lib/tiles.php | 176 - apps/gallery/lib/tiles_test.php | 85 - apps/gallery/sharing.php | 47 - apps/gallery/templates/index.php | 84 - apps/gallery/templates/view_album.php | 47 - apps/media/ajax/api.php | 133 - apps/media/ajax/autoupdate.php | 37 - apps/media/appinfo/app.php | 47 - apps/media/appinfo/database.xml | 328 - apps/media/appinfo/info.xml | 15 - apps/media/appinfo/version | 1 - apps/media/css/music.css | 48 - apps/media/css/player.css | 23 - apps/media/index.php | 42 - apps/media/js/Jplayer.swf | Bin 7679 -> 0 bytes apps/media/js/collection.js | 368 - .../js/jQuery.jPlayer.2.1.0.source/Jplayer.as | 415 - .../jQuery.jPlayer.2.1.0.source/Jplayer.fla | Bin 61952 -> 0 bytes .../add-on/jplayer.playlist.js | 452 - .../add-on/jquery.jplayer.inspector.js | 331 - .../happyworm/jPlayer/JplayerEvent.as | 69 - .../happyworm/jPlayer/JplayerMp3.as | 328 - .../happyworm/jPlayer/JplayerMp4.as | 413 - .../happyworm/jPlayer/JplayerStatus.as | 101 - .../jquery.jplayer.js | 2349 -- apps/media/js/jquery.jplayer.min.js | 2 - apps/media/js/loader.js | 59 - apps/media/js/music.js | 57 - apps/media/js/player.js | 214 - apps/media/js/playlist.js | 57 - apps/media/js/scanner.js | 44 - apps/media/l10n/ar.php | 13 - apps/media/l10n/bg_BG.php | 13 - apps/media/l10n/ca.php | 13 - apps/media/l10n/cs_CZ.php | 13 - apps/media/l10n/da.php | 13 - apps/media/l10n/de.php | 13 - apps/media/l10n/el.php | 13 - apps/media/l10n/eo.php | 13 - apps/media/l10n/es.php | 13 - apps/media/l10n/et_EE.php | 13 - apps/media/l10n/eu.php | 13 - apps/media/l10n/fa.php | 13 - apps/media/l10n/fi_FI.php | 13 - apps/media/l10n/fr.php | 13 - apps/media/l10n/gl.php | 13 - apps/media/l10n/he.php | 13 - apps/media/l10n/hr.php | 13 - apps/media/l10n/hu_HU.php | 13 - apps/media/l10n/ia.php | 13 - apps/media/l10n/id.php | 13 - apps/media/l10n/it.php | 13 - apps/media/l10n/ja_JP.php | 13 - apps/media/l10n/ko.php | 13 - apps/media/l10n/lb.php | 13 - apps/media/l10n/lt_LT.php | 13 - apps/media/l10n/mk.php | 13 - apps/media/l10n/ms_MY.php | 13 - apps/media/l10n/nb_NO.php | 13 - apps/media/l10n/nl.php | 13 - apps/media/l10n/nn_NO.php | 13 - apps/media/l10n/pl.php | 13 - apps/media/l10n/pt_BR.php | 13 - apps/media/l10n/pt_PT.php | 13 - apps/media/l10n/ro.php | 13 - apps/media/l10n/ru.php | 13 - apps/media/l10n/sk_SK.php | 13 - apps/media/l10n/sl.php | 13 - apps/media/l10n/sr.php | 13 - apps/media/l10n/sr@latin.php | 13 - apps/media/l10n/sv.php | 13 - apps/media/l10n/th_TH.php | 13 - apps/media/l10n/tr.php | 13 - apps/media/l10n/xgettextfiles | 6 - apps/media/l10n/zh_CN.php | 13 - apps/media/l10n/zh_TW.php | 13 - apps/media/lib_ampache.php | 421 - apps/media/lib_collection.php | 389 - apps/media/lib_media.php | 97 - apps/media/lib_scanner.php | 138 - apps/media/remote.php | 11 - apps/media/server/xml.server.php | 79 - apps/media/settings.php | 5 - apps/media/templates/music.php | 52 - apps/media/templates/player.php | 16 - apps/media/templates/settings.php | 7 - apps/remoteStorage/BearerAuth.php | 61 - apps/remoteStorage/WebDAV.php | 101 - apps/remoteStorage/ajax/revokeToken.php | 39 - apps/remoteStorage/appinfo/app.php | 2 - apps/remoteStorage/appinfo/database.xml | 52 - apps/remoteStorage/appinfo/info.xml | 10 - apps/remoteStorage/appinfo/version | 1 - apps/remoteStorage/appinfo/webfinger.php | 8 - apps/remoteStorage/auth.php | 123 - apps/remoteStorage/lib_remoteStorage.php | 69 - apps/remoteStorage/oauth_ro_auth.php | 70 - apps/remoteStorage/remoteStorage.png | Bin 1273 -> 0 bytes apps/remoteStorage/settings.php | 6 - apps/remoteStorage/templates/settings.php | 28 - apps/tasks/ajax/addtask.php | 27 - apps/tasks/ajax/addtaskform.php | 20 - apps/tasks/ajax/delete.php | 31 - apps/tasks/ajax/edittask.php | 31 - apps/tasks/ajax/edittaskform.php | 24 - apps/tasks/ajax/getdetails.php | 24 - apps/tasks/ajax/gettasks.php | 36 - apps/tasks/ajax/update_property.php | 68 - apps/tasks/appinfo/app.php | 11 - apps/tasks/appinfo/info.xml | 11 - apps/tasks/css/style.css | 62 - apps/tasks/img/icon.png | Bin 457 -> 0 bytes apps/tasks/img/icon.svg | 101 - apps/tasks/index.php | 33 - apps/tasks/js/tasks.js | 535 - apps/tasks/lib/app.php | 188 - apps/tasks/lib/vtodo.php | 27 - apps/tasks/templates/part.addtaskform.php | 15 - apps/tasks/templates/part.details.php | 42 - apps/tasks/templates/part.edittaskform.php | 5 - apps/tasks/templates/part.property.php | 22 - apps/tasks/templates/part.taskform.php | 36 - apps/tasks/templates/part.tasks.php | 3 - apps/tasks/templates/tasks.php | 34 - apps/user_ldap/ajax/testConfiguration.php | 39 + apps/user_ldap/appinfo/app.php | 16 +- apps/user_ldap/appinfo/database.xml | 49 + apps/user_ldap/appinfo/info.xml | 2 +- apps/user_ldap/appinfo/install.php | 2 +- apps/user_ldap/appinfo/update.php | 46 +- apps/user_ldap/appinfo/version | 2 +- apps/user_ldap/css/settings.css | 10 + apps/user_ldap/group_ldap.php | 193 +- apps/user_ldap/js/settings.js | 21 + apps/user_ldap/l10n/.gitkeep | 0 apps/user_ldap/l10n/ca.php | 37 + apps/user_ldap/l10n/cs_CZ.php | 37 + apps/user_ldap/l10n/da.php | 10 + apps/user_ldap/l10n/de.php | 37 + apps/user_ldap/l10n/el.php | 18 + apps/user_ldap/l10n/eo.php | 35 + apps/user_ldap/l10n/es.php | 37 + apps/user_ldap/l10n/es_AR.php | 37 + apps/user_ldap/l10n/et_EE.php | 31 + apps/user_ldap/l10n/eu.php | 37 + apps/user_ldap/l10n/fa.php | 5 + apps/user_ldap/l10n/fi_FI.php | 37 + apps/user_ldap/l10n/fr.php | 37 + apps/user_ldap/l10n/it.php | 37 + apps/user_ldap/l10n/ja_JP.php | 37 + apps/user_ldap/l10n/lt_LT.php | 9 + apps/user_ldap/l10n/pl.php | 37 + apps/user_ldap/l10n/pt_BR.php | 37 + apps/user_ldap/l10n/pt_PT.php | 18 + apps/user_ldap/l10n/ro.php | 37 + apps/user_ldap/l10n/ru.php | 37 + apps/user_ldap/l10n/ru_RU.php | 37 + apps/user_ldap/l10n/sl.php | 37 + apps/user_ldap/l10n/sv.php | 37 + apps/user_ldap/l10n/th_TH.php | 37 + apps/user_ldap/l10n/uk.php | 4 + apps/user_ldap/l10n/vi.php | 13 + apps/user_ldap/l10n/zh_CN.GB2312.php | 37 + apps/user_ldap/l10n/zh_CN.php | 9 + apps/user_ldap/lib/access.php | 683 + apps/user_ldap/lib/connection.php | 360 + apps/user_ldap/lib/jobs.php | 157 + apps/user_ldap/lib_ldap.php | 721 - apps/user_ldap/settings.php | 28 +- apps/user_ldap/templates/settings.php | 34 +- apps/user_ldap/tests/group_ldap.php | 10 +- apps/user_ldap/user_ldap.php | 168 +- apps/user_migrate/ajax/export.php | 62 - apps/user_migrate/appinfo/app.php | 33 - apps/user_migrate/appinfo/info.xml | 11 - apps/user_migrate/appinfo/version | 1 - apps/user_migrate/js/export.js | 27 - apps/user_migrate/settings.php | 89 - apps/user_migrate/templates/settings.php | 19 - apps/user_openid/appinfo/app.php | 52 - apps/user_openid/appinfo/info.xml | 14 - apps/user_openid/appinfo/version | 1 - apps/user_openid/js/settings.js | 10 - apps/user_openid/settings.php | 10 - apps/user_openid/templates/nomode.php | 28 - apps/user_openid/templates/settings.php | 8 - apps/user_openid/user.php | 47 - apps/user_openid/user_openid.php | 65 - apps/user_webdavauth/appinfo/app.php | 37 + apps/user_webdavauth/appinfo/info.xml | 11 + apps/user_webdavauth/settings.php | 36 + apps/user_webdavauth/templates/settings.php | 7 + apps/user_webdavauth/user_webdavauth.php | 83 + apps/user_webfinger/appinfo/app.php | 3 - apps/user_webfinger/appinfo/info.xml | 10 - apps/user_webfinger/appinfo/version | 1 - apps/user_webfinger/host-meta.php | 11 - apps/user_webfinger/webfinger.php | 60 - autotest.sh | 111 + config/config.sample.php | 26 +- core/ajax/appconfig.php | 16 +- core/ajax/grouplist.php | 47 - core/ajax/requesttoken.php | 41 + core/ajax/share.php | 154 + core/ajax/translations.php | 2 +- core/ajax/userlist.php | 46 - core/ajax/validateuser.php | 38 - core/ajax/vcategories/add.php | 6 +- core/ajax/vcategories/delete.php | 6 +- core/ajax/vcategories/edit.php | 8 +- core/css/share.css | 22 + core/css/styles.css | 31 +- core/img/actions/add.png | Bin 488 -> 441 bytes core/img/actions/clock.png | Bin 0 -> 466 bytes core/img/actions/clock.svg | 20 + core/img/actions/delete.png | Bin 275 -> 240 bytes core/img/actions/download.png | Bin 246 -> 236 bytes core/img/actions/history.png | Bin 370 -> 363 bytes core/img/actions/info.png | Bin 474 -> 423 bytes core/img/actions/lock.png | Bin 0 -> 346 bytes core/img/actions/lock.svg | 8 + core/img/actions/logout.png | Bin 657 -> 592 bytes core/img/actions/mail.png | Bin 463 -> 405 bytes core/img/actions/pause-big.png | Bin 183 -> 166 bytes core/img/actions/pause.png | Bin 182 -> 170 bytes core/img/actions/play-add.png | Bin 275 -> 237 bytes core/img/actions/play-big.png | Bin 212 -> 210 bytes core/img/actions/play-next.png | Bin 253 -> 224 bytes core/img/actions/play-previous.png | Bin 260 -> 237 bytes core/img/actions/play.png | Bin 220 -> 201 bytes core/img/actions/public.png | Bin 459 -> 412 bytes core/img/actions/rename.png | Bin 310 -> 267 bytes core/img/actions/search.png | Bin 701 -> 554 bytes core/img/actions/settings.png | Bin 883 -> 683 bytes core/img/actions/share.png | Bin 377 -> 338 bytes core/img/actions/shared.png | Bin 437 -> 364 bytes core/img/actions/sound-off.png | Bin 217 -> 192 bytes core/img/actions/sound.png | Bin 292 -> 254 bytes core/img/actions/triangle-s.png | Bin 526 -> 515 bytes core/img/actions/upload-white.png | Bin 228 -> 226 bytes core/img/actions/upload.png | Bin 236 -> 235 bytes core/img/breadcrumb-start.png | Bin 452 -> 311 bytes core/img/breadcrumb.png | Bin 452 -> 320 bytes core/img/favicon-touch.png | Bin 5703 -> 3705 bytes core/img/favicon.png | Bin 1231 -> 912 bytes core/img/filetypes/application-msword.png | Bin 28346 -> 789 bytes core/img/filetypes/application-sgf.png | Bin 725 -> 702 bytes ...ication-vnd.oasis.opendocument.formula.png | Bin 580 -> 479 bytes ...cation-vnd.oasis.opendocument.graphics.png | Bin 572 -> 475 bytes ...on-vnd.oasis.opendocument.presentation.png | Bin 441 -> 333 bytes ...ion-vnd.oasis.opendocument.spreadsheet.png | Bin 436 -> 344 bytes ...pplication-vnd.oasis.opendocument.text.png | Bin 420 -> 347 bytes .../filetypes/application-x-7z-compressed.png | Bin 652 -> 650 bytes .../application-x-bzip-compressed-tar.png | Bin 652 -> 650 bytes core/img/filetypes/application-x-bzip.png | Bin 652 -> 650 bytes .../application-x-compressed-tar.png | Bin 652 -> 650 bytes core/img/filetypes/application-x-deb.png | Bin 652 -> 650 bytes .../application-x-debian-package.png | Bin 570 -> 548 bytes core/img/filetypes/application-x-gzip.png | Bin 652 -> 650 bytes .../application-x-lzma-compressed-tar.png | Bin 652 -> 650 bytes core/img/filetypes/application-x-rar.png | Bin 652 -> 650 bytes core/img/filetypes/application-x-rpm.png | Bin 652 -> 650 bytes core/img/filetypes/application-x-tar.png | Bin 652 -> 650 bytes core/img/filetypes/application-x-tarz.png | Bin 652 -> 650 bytes core/img/filetypes/application-zip.png | Bin 652 -> 650 bytes core/img/filetypes/flash.png | Bin 582 -> 580 bytes core/img/icon-error.png | Bin 1573 -> 1571 bytes core/img/icon-error.svg | 24 +- core/img/icon-sync.png | Bin 1577 -> 1544 bytes core/img/icon-sync.svg | 20 +- core/img/icon.png | Bin 1344 -> 1305 bytes core/img/icon.svg | 22 +- core/img/logo-inverted.png | Bin 8116 -> 5938 bytes core/img/logo-square.png | Bin 22792 -> 16048 bytes core/img/logo-wide.png | Bin 2293 -> 1908 bytes core/img/logo.png | Bin 7356 -> 5860 bytes core/img/places/file.png | Bin 391 -> 364 bytes core/img/places/folder.png | Bin 386 -> 339 bytes core/img/places/home.png | Bin 416 -> 372 bytes core/img/places/music.png | Bin 561 -> 532 bytes core/img/places/picture.png | Bin 307 -> 300 bytes core/img/rating/s1.png | Bin 0 -> 454 bytes core/img/rating/s10.png | Bin 0 -> 848 bytes core/img/rating/s11.png | Bin 0 -> 724 bytes core/img/rating/s2.png | Bin 0 -> 731 bytes core/img/rating/s3.png | Bin 0 -> 918 bytes core/img/rating/s4.png | Bin 0 -> 989 bytes core/img/rating/s5.png | Bin 0 -> 939 bytes core/img/rating/s6.png | Bin 0 -> 992 bytes core/img/rating/s7.png | Bin 0 -> 939 bytes core/img/rating/s8.png | Bin 0 -> 987 bytes core/img/rating/s9.png | Bin 0 -> 908 bytes core/img/remoteStorage-big.png | Bin 9742 -> 8997 bytes .../js/LICENSE.jquery.inview | 0 core/js/backgroundjobs.js | 25 + core/js/config.js | 2 +- core/js/eventsource.js | 1 + {apps/contacts => core}/js/jquery.inview.js | 4 +- {apps/contacts => core}/js/jquery.inview.txt | 0 core/js/js.js | 360 +- core/js/listview.js | 10 +- core/js/oc-dialogs.js | 16 +- core/js/oc-vcategories.js | 4 +- core/js/requesttoken.js | 55 + core/js/setup.js | 11 +- core/js/share.js | 514 + core/l10n/ar.php | 5 +- core/l10n/bg_BG.php | 27 +- core/l10n/ca.php | 54 +- core/l10n/cs_CZ.php | 88 +- core/l10n/da.php | 51 +- core/l10n/de.php | 92 +- core/l10n/el.php | 52 +- core/l10n/eo.php | 58 +- core/l10n/es.php | 53 +- core/l10n/es_AR.php | 91 + core/l10n/et_EE.php | 23 +- core/l10n/eu.php | 50 +- core/l10n/fa.php | 23 +- core/l10n/fi_FI.php | 47 +- core/l10n/fr.php | 58 +- core/l10n/gl.php | 23 +- core/l10n/he.php | 24 +- core/l10n/hi.php | 14 + core/l10n/hr.php | 51 +- core/l10n/hu_HU.php | 49 +- core/l10n/ia.php | 5 +- core/l10n/id.php | 22 +- core/l10n/ignorelist | 1 + core/l10n/it.php | 58 +- core/l10n/ja_JP.php | 54 +- core/l10n/ko.php | 23 +- core/l10n/ku_IQ.php | 21 + core/l10n/lb.php | 26 +- core/l10n/lt_LT.php | 25 +- core/l10n/lv.php | 35 + core/l10n/mk.php | 23 +- core/l10n/ms_MY.php | 29 +- core/l10n/nb_NO.php | 23 +- core/l10n/nl.php | 53 +- core/l10n/nn_NO.php | 5 +- core/l10n/oc.php | 91 + core/l10n/pl.php | 51 +- core/l10n/pt_BR.php | 54 +- core/l10n/pt_PT.php | 51 +- core/l10n/ro.php | 45 +- core/l10n/ru.php | 24 +- core/l10n/ru_RU.php | 83 + core/l10n/si_LK.php | 29 + core/l10n/sk_SK.php | 46 +- core/l10n/sl.php | 25 +- core/l10n/sr.php | 5 +- core/l10n/sr@latin.php | 4 +- core/l10n/sv.php | 70 +- core/l10n/th_TH.php | 51 +- core/l10n/tr.php | 24 +- core/l10n/uk.php | 21 +- core/l10n/vi.php | 63 + core/l10n/zh_CN.GB2312.php | 91 + core/l10n/zh_CN.php | 45 +- core/l10n/zh_TW.php | 24 +- core/lostpassword/index.php | 27 +- core/lostpassword/resetpassword.php | 4 +- core/lostpassword/templates/email.php | 3 +- core/lostpassword/templates/lostpassword.php | 1 - core/minimizer.php | 4 +- core/templates/403.php | 2 +- core/templates/404.php | 2 +- core/templates/exception.php | 30 + core/templates/installation.php | 41 +- core/templates/layout.base.php | 33 + core/templates/layout.guest.php | 10 +- core/templates/layout.user.php | 26 +- core/templates/login.php | 22 +- core/templates/verify.php | 18 + cron.php | 89 + db_structure.xml | 1184 +- files/webdav.php | 8 +- index.php | 106 +- l10n/.tx/config | 52 +- l10n/af/admin_dependencies_chk.po | 73 + l10n/af/admin_migrate.po | 32 + l10n/af/bookmarks.po | 60 + l10n/af/calendar.po | 444 +- l10n/af/contacts.po | 935 +- l10n/af/core.po | 257 +- l10n/af/files.po | 189 +- l10n/af/files_encryption.po | 34 + l10n/af/files_external.po | 106 + l10n/af/files_odfviewer.po | 22 + l10n/af/files_pdfviewer.po | 42 + l10n/af/files_sharing.po | 48 + l10n/af/files_texteditor.po | 44 + l10n/af/files_versions.po | 42 + l10n/af/impress.po | 22 + l10n/af/lib.po | 125 + l10n/af/settings.po | 207 +- l10n/af/tasks.po | 106 + l10n/af/user_ldap.po | 170 + l10n/af/user_migrate.po | 51 + l10n/af/user_openid.po | 54 + l10n/ar/admin_dependencies_chk.po | 73 + l10n/ar/admin_migrate.po | 32 + l10n/ar/bookmarks.po | 60 + l10n/ar/calendar.po | 522 +- l10n/ar/contacts.po | 925 +- l10n/ar/core.po | 263 +- l10n/ar/files.po | 189 +- l10n/ar/files_encryption.po | 34 + l10n/ar/files_external.po | 106 + l10n/ar/files_odfviewer.po | 22 + l10n/ar/files_pdfviewer.po | 42 + l10n/ar/files_sharing.po | 48 + l10n/ar/files_texteditor.po | 44 + l10n/ar/files_versions.po | 42 + l10n/ar/impress.po | 22 + l10n/ar/lib.po | 125 + l10n/ar/media.po | 14 +- l10n/ar/settings.po | 211 +- l10n/ar/tasks.po | 106 + l10n/ar/user_ldap.po | 170 + l10n/ar/user_migrate.po | 51 + l10n/ar/user_openid.po | 54 + l10n/ar_SA/admin_dependencies_chk.po | 73 + l10n/ar_SA/admin_migrate.po | 32 + l10n/ar_SA/bookmarks.po | 60 + l10n/ar_SA/calendar.po | 813 + l10n/ar_SA/contacts.po | 952 + l10n/ar_SA/core.po | 431 + l10n/ar_SA/files.po | 299 + l10n/ar_SA/files_encryption.po | 34 + l10n/ar_SA/files_external.po | 106 + l10n/ar_SA/files_odfviewer.po | 22 + l10n/ar_SA/files_pdfviewer.po | 42 + l10n/ar_SA/files_sharing.po | 48 + l10n/ar_SA/files_texteditor.po | 44 + l10n/ar_SA/files_versions.po | 42 + l10n/ar_SA/gallery.po | 58 + l10n/ar_SA/impress.po | 22 + l10n/ar_SA/lib.po | 125 + l10n/ar_SA/media.po | 66 + l10n/ar_SA/settings.po | 321 + l10n/ar_SA/tasks.po | 106 + l10n/ar_SA/user_ldap.po | 170 + l10n/ar_SA/user_migrate.po | 51 + l10n/ar_SA/user_openid.po | 54 + l10n/bg_BG/admin_dependencies_chk.po | 73 + l10n/bg_BG/admin_migrate.po | 32 + l10n/bg_BG/bookmarks.po | 61 + l10n/bg_BG/calendar.po | 549 +- l10n/bg_BG/contacts.po | 935 +- l10n/bg_BG/core.po | 304 +- l10n/bg_BG/files.po | 216 +- l10n/bg_BG/files_encryption.po | 34 + l10n/bg_BG/files_external.po | 106 + l10n/bg_BG/files_odfviewer.po | 22 + l10n/bg_BG/files_pdfviewer.po | 42 + l10n/bg_BG/files_sharing.po | 48 + l10n/bg_BG/files_texteditor.po | 44 + l10n/bg_BG/files_versions.po | 42 + l10n/bg_BG/impress.po | 22 + l10n/bg_BG/lib.po | 125 + l10n/bg_BG/media.po | 13 +- l10n/bg_BG/settings.po | 236 +- l10n/bg_BG/tasks.po | 106 + l10n/bg_BG/user_ldap.po | 170 + l10n/bg_BG/user_migrate.po | 51 + l10n/bg_BG/user_openid.po | 54 + l10n/ca/admin_dependencies_chk.po | 74 + l10n/ca/admin_migrate.po | 33 + l10n/ca/bookmarks.po | 61 + l10n/ca/calendar.po | 472 +- l10n/ca/contacts.po | 1023 +- l10n/ca/core.po | 301 +- l10n/ca/files.po | 215 +- l10n/ca/files_encryption.po | 35 + l10n/ca/files_external.po | 107 + l10n/ca/files_odfviewer.po | 22 + l10n/ca/files_pdfviewer.po | 42 + l10n/ca/files_sharing.po | 49 + l10n/ca/files_texteditor.po | 44 + l10n/ca/files_versions.po | 44 + l10n/ca/gallery.po | 64 +- l10n/ca/impress.po | 22 + l10n/ca/lib.po | 126 + l10n/ca/settings.po | 231 +- l10n/ca/tasks.po | 107 + l10n/ca/user_ldap.po | 171 + l10n/ca/user_migrate.po | 52 + l10n/ca/user_openid.po | 55 + l10n/cs_CZ/admin_dependencies_chk.po | 74 + l10n/cs_CZ/admin_migrate.po | 33 + l10n/cs_CZ/bookmarks.po | 61 + l10n/cs_CZ/calendar.po | 464 +- l10n/cs_CZ/contacts.po | 1025 +- l10n/cs_CZ/core.po | 336 +- l10n/cs_CZ/files.po | 248 +- l10n/cs_CZ/files_encryption.po | 36 + l10n/cs_CZ/files_external.po | 110 + l10n/cs_CZ/files_odfviewer.po | 22 + l10n/cs_CZ/files_pdfviewer.po | 42 + l10n/cs_CZ/files_sharing.po | 51 + l10n/cs_CZ/files_texteditor.po | 44 + l10n/cs_CZ/files_versions.po | 44 + l10n/cs_CZ/gallery.po | 84 +- l10n/cs_CZ/impress.po | 22 + l10n/cs_CZ/lib.po | 127 + l10n/cs_CZ/settings.po | 258 +- l10n/cs_CZ/tasks.po | 107 + l10n/cs_CZ/user_ldap.po | 172 + l10n/cs_CZ/user_migrate.po | 52 + l10n/cs_CZ/user_openid.po | 55 + l10n/da/admin_dependencies_chk.po | 73 + l10n/da/admin_migrate.po | 33 + l10n/da/bookmarks.po | 60 + l10n/da/calendar.po | 470 +- l10n/da/contacts.po | 1016 +- l10n/da/core.po | 304 +- l10n/da/files.po | 217 +- l10n/da/files_encryption.po | 35 + l10n/da/files_external.po | 108 + l10n/da/files_odfviewer.po | 22 + l10n/da/files_pdfviewer.po | 42 + l10n/da/files_sharing.po | 50 + l10n/da/files_texteditor.po | 44 + l10n/da/files_versions.po | 44 + l10n/da/impress.po | 22 + l10n/da/lib.po | 127 + l10n/da/settings.po | 229 +- l10n/da/tasks.po | 107 + l10n/da/user_ldap.po | 172 + l10n/da/user_migrate.po | 51 + l10n/da/user_openid.po | 54 + l10n/de/admin_dependencies_chk.po | 77 + l10n/de/admin_migrate.po | 34 + l10n/de/bookmarks.po | 63 + l10n/de/calendar.po | 491 +- l10n/de/contacts.po | 1049 +- l10n/de/core.po | 345 +- l10n/de/files.po | 239 +- l10n/de/files_encryption.po | 35 + l10n/de/files_external.po | 110 + l10n/de/files_odfviewer.po | 23 + l10n/de/files_pdfviewer.po | 43 + l10n/de/files_sharing.po | 53 + l10n/de/files_texteditor.po | 45 + l10n/de/files_versions.po | 47 + l10n/de/gallery.po | 66 +- l10n/de/impress.po | 23 + l10n/de/lib.po | 129 + l10n/de/settings.po | 256 +- l10n/de/tasks.po | 109 + l10n/de/user_ldap.po | 176 + l10n/de/user_migrate.po | 54 + l10n/de/user_openid.po | 57 + l10n/de_DE/calendar.po | 636 - l10n/de_DE/core.po | 170 - l10n/de_DE/files.po | 108 - l10n/de_DE/media.po | 64 - l10n/de_DE/settings.po | 156 - l10n/el/admin_dependencies_chk.po | 74 + l10n/el/admin_migrate.po | 33 + l10n/el/bookmarks.po | 62 + l10n/el/calendar.po | 472 +- l10n/el/contacts.po | 1030 +- l10n/el/core.po | 301 +- l10n/el/files.po | 234 +- l10n/el/files_encryption.po | 35 + l10n/el/files_external.po | 111 + l10n/el/files_odfviewer.po | 22 + l10n/el/files_pdfviewer.po | 42 + l10n/el/files_sharing.po | 51 + l10n/el/files_texteditor.po | 44 + l10n/el/files_versions.po | 45 + l10n/el/gallery.po | 65 +- l10n/el/impress.po | 22 + l10n/el/lib.po | 126 + l10n/el/settings.po | 265 +- l10n/el/tasks.po | 107 + l10n/el/user_ldap.po | 173 + l10n/el/user_migrate.po | 52 + l10n/el/user_openid.po | 55 + l10n/eo/admin_dependencies_chk.po | 74 + l10n/eo/admin_migrate.po | 33 + l10n/eo/bookmarks.po | 61 + l10n/eo/calendar.po | 471 +- l10n/eo/contacts.po | 1016 +- l10n/eo/core.po | 312 +- l10n/eo/files.po | 212 +- l10n/eo/files_encryption.po | 35 + l10n/eo/files_external.po | 107 + l10n/eo/files_odfviewer.po | 22 + l10n/eo/files_pdfviewer.po | 42 + l10n/eo/files_sharing.po | 49 + l10n/eo/files_texteditor.po | 44 + l10n/eo/files_versions.po | 43 + l10n/eo/impress.po | 22 + l10n/eo/lib.po | 126 + l10n/eo/media.po | 19 +- l10n/eo/settings.po | 226 +- l10n/eo/tasks.po | 107 + l10n/eo/user_ldap.po | 171 + l10n/eo/user_migrate.po | 52 + l10n/eo/user_openid.po | 55 + l10n/es/admin_dependencies_chk.po | 74 + l10n/es/admin_migrate.po | 33 + l10n/es/bookmarks.po | 61 + l10n/es/calendar.po | 470 +- l10n/es/contacts.po | 1013 +- l10n/es/core.po | 305 +- l10n/es/files.po | 216 +- l10n/es/files_encryption.po | 35 + l10n/es/files_external.po | 109 + l10n/es/files_odfviewer.po | 22 + l10n/es/files_pdfviewer.po | 42 + l10n/es/files_sharing.po | 51 + l10n/es/files_texteditor.po | 44 + l10n/es/files_versions.po | 46 + l10n/es/gallery.po | 65 +- l10n/es/impress.po | 22 + l10n/es/lib.po | 127 + l10n/es/settings.po | 229 +- l10n/es/tasks.po | 107 + l10n/es/user_ldap.po | 175 + l10n/es/user_migrate.po | 52 + l10n/es/user_openid.po | 55 + l10n/es_AR/core.po | 432 + l10n/es_AR/files.po | 300 + l10n/es_AR/files_encryption.po | 35 + l10n/es_AR/files_external.po | 107 + l10n/es_AR/files_sharing.po | 49 + l10n/es_AR/files_versions.po | 43 + l10n/es_AR/lib.po | 126 + l10n/es_AR/settings.po | 322 + l10n/es_AR/user_ldap.po | 171 + l10n/et_EE/admin_dependencies_chk.po | 74 + l10n/et_EE/admin_migrate.po | 33 + l10n/et_EE/bookmarks.po | 61 + l10n/et_EE/calendar.po | 468 +- l10n/et_EE/contacts.po | 1003 +- l10n/et_EE/core.po | 295 +- l10n/et_EE/files.po | 205 +- l10n/et_EE/files_encryption.po | 35 + l10n/et_EE/files_external.po | 107 + l10n/et_EE/files_odfviewer.po | 22 + l10n/et_EE/files_pdfviewer.po | 42 + l10n/et_EE/files_sharing.po | 49 + l10n/et_EE/files_texteditor.po | 44 + l10n/et_EE/files_versions.po | 43 + l10n/et_EE/impress.po | 22 + l10n/et_EE/lib.po | 126 + l10n/et_EE/settings.po | 225 +- l10n/et_EE/tasks.po | 107 + l10n/et_EE/user_ldap.po | 171 + l10n/et_EE/user_migrate.po | 51 + l10n/et_EE/user_openid.po | 55 + l10n/eu/admin_dependencies_chk.po | 73 + l10n/eu/admin_migrate.po | 32 + l10n/eu/bookmarks.po | 60 + l10n/eu/calendar.po | 452 +- l10n/eu/contacts.po | 1129 +- l10n/eu/core.po | 299 +- l10n/eu/files.po | 211 +- l10n/eu/files_encryption.po | 35 + l10n/eu/files_external.po | 107 + l10n/eu/files_odfviewer.po | 22 + l10n/eu/files_pdfviewer.po | 42 + l10n/eu/files_sharing.po | 49 + l10n/eu/files_texteditor.po | 44 + l10n/eu/files_versions.po | 43 + l10n/eu/impress.po | 22 + l10n/eu/lib.po | 126 + l10n/eu/settings.po | 229 +- l10n/eu/tasks.po | 106 + l10n/eu/user_ldap.po | 171 + l10n/eu/user_migrate.po | 51 + l10n/eu/user_openid.po | 54 + l10n/eu_ES/admin_dependencies_chk.po | 73 + l10n/eu_ES/admin_migrate.po | 32 + l10n/eu_ES/bookmarks.po | 60 + l10n/eu_ES/calendar.po | 813 + l10n/eu_ES/contacts.po | 952 + l10n/eu_ES/core.po | 431 + l10n/eu_ES/files.po | 299 + l10n/eu_ES/files_encryption.po | 34 + l10n/eu_ES/files_external.po | 106 + l10n/eu_ES/files_odfviewer.po | 22 + l10n/eu_ES/files_pdfviewer.po | 42 + l10n/eu_ES/files_sharing.po | 48 + l10n/eu_ES/files_texteditor.po | 44 + l10n/eu_ES/files_versions.po | 42 + l10n/eu_ES/gallery.po | 58 + l10n/eu_ES/impress.po | 22 + l10n/eu_ES/lib.po | 125 + l10n/eu_ES/media.po | 66 + l10n/eu_ES/settings.po | 321 + l10n/eu_ES/tasks.po | 106 + l10n/eu_ES/user_ldap.po | 170 + l10n/eu_ES/user_migrate.po | 51 + l10n/eu_ES/user_openid.po | 54 + l10n/fa/admin_dependencies_chk.po | 73 + l10n/fa/admin_migrate.po | 32 + l10n/fa/bookmarks.po | 61 + l10n/fa/calendar.po | 468 +- l10n/fa/contacts.po | 1011 +- l10n/fa/core.po | 295 +- l10n/fa/files.po | 203 +- l10n/fa/files_encryption.po | 35 + l10n/fa/files_external.po | 106 + l10n/fa/files_odfviewer.po | 22 + l10n/fa/files_pdfviewer.po | 42 + l10n/fa/files_sharing.po | 49 + l10n/fa/files_texteditor.po | 44 + l10n/fa/files_versions.po | 43 + l10n/fa/impress.po | 22 + l10n/fa/lib.po | 126 + l10n/fa/settings.po | 222 +- l10n/fa/tasks.po | 107 + l10n/fa/user_ldap.po | 171 + l10n/fa/user_migrate.po | 51 + l10n/fa/user_openid.po | 54 + l10n/fi/admin_dependencies_chk.po | 73 + l10n/fi/admin_migrate.po | 32 + l10n/fi/bookmarks.po | 60 + l10n/fi/calendar.po | 813 + l10n/fi/contacts.po | 952 + l10n/fi/core.po | 431 + l10n/fi/files.po | 299 + l10n/fi/files_encryption.po | 34 + l10n/fi/files_external.po | 106 + l10n/fi/files_odfviewer.po | 22 + l10n/fi/files_pdfviewer.po | 42 + l10n/fi/files_sharing.po | 48 + l10n/fi/files_texteditor.po | 44 + l10n/fi/files_versions.po | 42 + l10n/fi/gallery.po | 58 + l10n/fi/impress.po | 22 + l10n/fi/lib.po | 125 + l10n/fi/media.po | 66 + l10n/fi/settings.po | 321 + l10n/fi/tasks.po | 106 + l10n/fi/user_ldap.po | 170 + l10n/fi/user_migrate.po | 51 + l10n/fi/user_openid.po | 54 + l10n/fi_FI/admin_dependencies_chk.po | 74 + l10n/fi_FI/admin_migrate.po | 33 + l10n/fi_FI/bookmarks.po | 61 + l10n/fi_FI/calendar.po | 450 +- l10n/fi_FI/contacts.po | 1009 +- l10n/fi_FI/core.po | 299 +- l10n/fi_FI/files.po | 210 +- l10n/fi_FI/files_encryption.po | 35 + l10n/fi_FI/files_external.po | 109 + l10n/fi_FI/files_odfviewer.po | 22 + l10n/fi_FI/files_pdfviewer.po | 42 + l10n/fi_FI/files_sharing.po | 50 + l10n/fi_FI/files_texteditor.po | 44 + l10n/fi_FI/files_versions.po | 43 + l10n/fi_FI/gallery.po | 64 +- l10n/fi_FI/impress.po | 22 + l10n/fi_FI/lib.po | 126 + l10n/fi_FI/settings.po | 226 +- l10n/fi_FI/tasks.po | 107 + l10n/fi_FI/user_ldap.po | 173 + l10n/fi_FI/user_migrate.po | 52 + l10n/fi_FI/user_openid.po | 55 + l10n/fr/admin_dependencies_chk.po | 74 + l10n/fr/admin_migrate.po | 33 + l10n/fr/bookmarks.po | 62 + l10n/fr/calendar.po | 471 +- l10n/fr/contacts.po | 1047 +- l10n/fr/core.po | 309 +- l10n/fr/files.po | 223 +- l10n/fr/files_encryption.po | 35 + l10n/fr/files_external.po | 107 + l10n/fr/files_odfviewer.po | 22 + l10n/fr/files_pdfviewer.po | 42 + l10n/fr/files_sharing.po | 53 + l10n/fr/files_texteditor.po | 44 + l10n/fr/files_versions.po | 43 + l10n/fr/gallery.po | 66 +- l10n/fr/impress.po | 22 + l10n/fr/lib.po | 127 + l10n/fr/media.po | 16 +- l10n/fr/settings.po | 231 +- l10n/fr/tasks.po | 109 + l10n/fr/user_ldap.po | 175 + l10n/fr/user_migrate.po | 53 + l10n/fr/user_openid.po | 55 + l10n/gl/admin_dependencies_chk.po | 73 + l10n/gl/admin_migrate.po | 33 + l10n/gl/bookmarks.po | 60 + l10n/gl/calendar.po | 468 +- l10n/gl/contacts.po | 1193 +- l10n/gl/core.po | 295 +- l10n/gl/files.po | 205 +- l10n/gl/files_encryption.po | 35 + l10n/gl/files_external.po | 107 + l10n/gl/files_odfviewer.po | 22 + l10n/gl/files_pdfviewer.po | 42 + l10n/gl/files_sharing.po | 49 + l10n/gl/files_texteditor.po | 44 + l10n/gl/files_versions.po | 43 + l10n/gl/impress.po | 22 + l10n/gl/lib.po | 126 + l10n/gl/settings.po | 221 +- l10n/gl/tasks.po | 106 + l10n/gl/user_ldap.po | 170 + l10n/gl/user_migrate.po | 51 + l10n/gl/user_openid.po | 54 + l10n/he/admin_dependencies_chk.po | 73 + l10n/he/admin_migrate.po | 32 + l10n/he/bookmarks.po | 60 + l10n/he/calendar.po | 469 +- l10n/he/contacts.po | 1160 +- l10n/he/core.po | 297 +- l10n/he/files.po | 203 +- l10n/he/files_encryption.po | 34 + l10n/he/files_external.po | 107 + l10n/he/files_odfviewer.po | 22 + l10n/he/files_pdfviewer.po | 42 + l10n/he/files_sharing.po | 49 + l10n/he/files_texteditor.po | 44 + l10n/he/files_versions.po | 43 + l10n/he/impress.po | 22 + l10n/he/lib.po | 126 + l10n/he/settings.po | 222 +- l10n/he/tasks.po | 106 + l10n/he/user_ldap.po | 170 + l10n/he/user_migrate.po | 51 + l10n/he/user_openid.po | 54 + l10n/hi/core.po | 432 + l10n/hi/files.po | 299 + l10n/hi/files_encryption.po | 34 + l10n/hi/files_external.po | 106 + l10n/hi/files_sharing.po | 48 + l10n/hi/files_versions.po | 42 + l10n/hi/lib.po | 125 + l10n/hi/settings.po | 321 + l10n/hi/user_ldap.po | 170 + l10n/hr/admin_dependencies_chk.po | 73 + l10n/hr/admin_migrate.po | 32 + l10n/hr/bookmarks.po | 60 + l10n/hr/calendar.po | 450 +- l10n/hr/contacts.po | 1055 +- l10n/hr/core.po | 302 +- l10n/hr/files.po | 214 +- l10n/hr/files_encryption.po | 34 + l10n/hr/files_external.po | 106 + l10n/hr/files_odfviewer.po | 22 + l10n/hr/files_pdfviewer.po | 42 + l10n/hr/files_sharing.po | 48 + l10n/hr/files_texteditor.po | 44 + l10n/hr/files_versions.po | 42 + l10n/hr/impress.po | 22 + l10n/hr/lib.po | 125 + l10n/hr/settings.po | 224 +- l10n/hr/tasks.po | 106 + l10n/hr/user_ldap.po | 170 + l10n/hr/user_migrate.po | 51 + l10n/hr/user_openid.po | 54 + l10n/hu_HU/admin_dependencies_chk.po | 73 + l10n/hu_HU/admin_migrate.po | 32 + l10n/hu_HU/bookmarks.po | 60 + l10n/hu_HU/calendar.po | 468 +- l10n/hu_HU/contacts.po | 1011 +- l10n/hu_HU/core.po | 321 +- l10n/hu_HU/files.po | 201 +- l10n/hu_HU/files_encryption.po | 35 + l10n/hu_HU/files_external.po | 106 + l10n/hu_HU/files_odfviewer.po | 22 + l10n/hu_HU/files_pdfviewer.po | 42 + l10n/hu_HU/files_sharing.po | 49 + l10n/hu_HU/files_texteditor.po | 44 + l10n/hu_HU/files_versions.po | 42 + l10n/hu_HU/impress.po | 22 + l10n/hu_HU/lib.po | 126 + l10n/hu_HU/settings.po | 221 +- l10n/hu_HU/tasks.po | 106 + l10n/hu_HU/user_ldap.po | 170 + l10n/hu_HU/user_migrate.po | 51 + l10n/hu_HU/user_openid.po | 54 + l10n/hy/admin_dependencies_chk.po | 73 + l10n/hy/admin_migrate.po | 32 + l10n/hy/bookmarks.po | 60 + l10n/hy/calendar.po | 444 +- l10n/hy/contacts.po | 935 +- l10n/hy/core.po | 257 +- l10n/hy/files.po | 189 +- l10n/hy/files_encryption.po | 34 + l10n/hy/files_external.po | 106 + l10n/hy/files_odfviewer.po | 22 + l10n/hy/files_pdfviewer.po | 42 + l10n/hy/files_sharing.po | 48 + l10n/hy/files_texteditor.po | 44 + l10n/hy/files_versions.po | 42 + l10n/hy/impress.po | 22 + l10n/hy/lib.po | 125 + l10n/hy/settings.po | 207 +- l10n/hy/tasks.po | 106 + l10n/hy/user_ldap.po | 170 + l10n/hy/user_migrate.po | 51 + l10n/hy/user_openid.po | 54 + l10n/ia/admin_dependencies_chk.po | 73 + l10n/ia/admin_migrate.po | 32 + l10n/ia/bookmarks.po | 60 + l10n/ia/calendar.po | 442 +- l10n/ia/contacts.po | 957 +- l10n/ia/core.po | 263 +- l10n/ia/files.po | 189 +- l10n/ia/files_encryption.po | 34 + l10n/ia/files_external.po | 106 + l10n/ia/files_odfviewer.po | 22 + l10n/ia/files_pdfviewer.po | 42 + l10n/ia/files_sharing.po | 48 + l10n/ia/files_texteditor.po | 44 + l10n/ia/files_versions.po | 42 + l10n/ia/impress.po | 22 + l10n/ia/lib.po | 125 + l10n/ia/settings.po | 207 +- l10n/ia/tasks.po | 106 + l10n/ia/user_ldap.po | 170 + l10n/ia/user_migrate.po | 51 + l10n/ia/user_openid.po | 54 + l10n/id/admin_dependencies_chk.po | 73 + l10n/id/admin_migrate.po | 32 + l10n/id/bookmarks.po | 60 + l10n/id/calendar.po | 446 +- l10n/id/contacts.po | 935 +- l10n/id/core.po | 296 +- l10n/id/files.po | 208 +- l10n/id/files_encryption.po | 34 + l10n/id/files_external.po | 106 + l10n/id/files_odfviewer.po | 22 + l10n/id/files_pdfviewer.po | 42 + l10n/id/files_sharing.po | 48 + l10n/id/files_texteditor.po | 44 + l10n/id/files_versions.po | 42 + l10n/id/impress.po | 22 + l10n/id/lib.po | 125 + l10n/id/settings.po | 222 +- l10n/id/tasks.po | 106 + l10n/id/user_ldap.po | 170 + l10n/id/user_migrate.po | 51 + l10n/id/user_openid.po | 54 + l10n/id_ID/admin_dependencies_chk.po | 73 + l10n/id_ID/admin_migrate.po | 32 + l10n/id_ID/bookmarks.po | 60 + l10n/id_ID/calendar.po | 813 + l10n/id_ID/contacts.po | 952 + l10n/id_ID/core.po | 431 + l10n/id_ID/files.po | 299 + l10n/id_ID/files_encryption.po | 34 + l10n/id_ID/files_external.po | 106 + l10n/id_ID/files_odfviewer.po | 22 + l10n/id_ID/files_pdfviewer.po | 42 + l10n/id_ID/files_sharing.po | 48 + l10n/id_ID/files_texteditor.po | 44 + l10n/id_ID/files_versions.po | 42 + l10n/id_ID/gallery.po | 58 + l10n/id_ID/impress.po | 22 + l10n/id_ID/lib.po | 125 + l10n/id_ID/media.po | 66 + l10n/id_ID/settings.po | 321 + l10n/id_ID/tasks.po | 106 + l10n/id_ID/user_ldap.po | 170 + l10n/id_ID/user_migrate.po | 51 + l10n/id_ID/user_openid.po | 54 + l10n/it/admin_dependencies_chk.po | 74 + l10n/it/admin_migrate.po | 33 + l10n/it/bookmarks.po | 61 + l10n/it/calendar.po | 468 +- l10n/it/contacts.po | 1023 +- l10n/it/core.po | 303 +- l10n/it/files.po | 211 +- l10n/it/files_encryption.po | 35 + l10n/it/files_external.po | 108 + l10n/it/files_odfviewer.po | 22 + l10n/it/files_pdfviewer.po | 42 + l10n/it/files_sharing.po | 49 + l10n/it/files_texteditor.po | 44 + l10n/it/files_versions.po | 43 + l10n/it/gallery.po | 64 +- l10n/it/impress.po | 22 + l10n/it/lib.po | 126 + l10n/it/settings.po | 225 +- l10n/it/tasks.po | 107 + l10n/it/user_ldap.po | 172 + l10n/it/user_migrate.po | 52 + l10n/it/user_openid.po | 55 + l10n/ja_JP/admin_dependencies_chk.po | 74 + l10n/ja_JP/admin_migrate.po | 33 + l10n/ja_JP/bookmarks.po | 60 + l10n/ja_JP/calendar.po | 519 +- l10n/ja_JP/contacts.po | 1052 +- l10n/ja_JP/core.po | 300 +- l10n/ja_JP/files.po | 212 +- l10n/ja_JP/files_encryption.po | 35 + l10n/ja_JP/files_external.po | 107 + l10n/ja_JP/files_odfviewer.po | 22 + l10n/ja_JP/files_pdfviewer.po | 42 + l10n/ja_JP/files_sharing.po | 50 + l10n/ja_JP/files_texteditor.po | 44 + l10n/ja_JP/files_versions.po | 44 + l10n/ja_JP/impress.po | 22 + l10n/ja_JP/lib.po | 126 + l10n/ja_JP/settings.po | 223 +- l10n/ja_JP/tasks.po | 108 + l10n/ja_JP/user_ldap.po | 172 + l10n/ja_JP/user_migrate.po | 52 + l10n/ja_JP/user_openid.po | 55 + l10n/ko/admin_dependencies_chk.po | 73 + l10n/ko/admin_migrate.po | 32 + l10n/ko/bookmarks.po | 60 + l10n/ko/calendar.po | 472 +- l10n/ko/contacts.po | 1063 +- l10n/ko/core.po | 295 +- l10n/ko/files.po | 201 +- l10n/ko/files_encryption.po | 34 + l10n/ko/files_external.po | 106 + l10n/ko/files_odfviewer.po | 22 + l10n/ko/files_pdfviewer.po | 42 + l10n/ko/files_sharing.po | 48 + l10n/ko/files_texteditor.po | 44 + l10n/ko/files_versions.po | 42 + l10n/ko/impress.po | 22 + l10n/ko/lib.po | 125 + l10n/ko/settings.po | 221 +- l10n/ko/tasks.po | 106 + l10n/ko/user_ldap.po | 170 + l10n/ko/user_migrate.po | 51 + l10n/ko/user_openid.po | 54 + l10n/ku_IQ/core.po | 432 + l10n/ku_IQ/files.po | 299 + l10n/ku_IQ/files_encryption.po | 35 + l10n/ku_IQ/files_external.po | 106 + l10n/ku_IQ/files_sharing.po | 49 + l10n/ku_IQ/files_versions.po | 43 + l10n/ku_IQ/lib.po | 125 + l10n/ku_IQ/settings.po | 321 + l10n/ku_IQ/user_ldap.po | 170 + l10n/l10n.pl | 2 +- l10n/lb/admin_dependencies_chk.po | 73 + l10n/lb/admin_migrate.po | 32 + l10n/lb/bookmarks.po | 60 + l10n/lb/calendar.po | 446 +- l10n/lb/contacts.po | 1087 +- l10n/lb/core.po | 299 +- l10n/lb/files.po | 205 +- l10n/lb/files_encryption.po | 34 + l10n/lb/files_external.po | 106 + l10n/lb/files_odfviewer.po | 22 + l10n/lb/files_pdfviewer.po | 42 + l10n/lb/files_sharing.po | 48 + l10n/lb/files_texteditor.po | 44 + l10n/lb/files_versions.po | 42 + l10n/lb/impress.po | 22 + l10n/lb/lib.po | 125 + l10n/lb/settings.po | 223 +- l10n/lb/tasks.po | 106 + l10n/lb/user_ldap.po | 170 + l10n/lb/user_migrate.po | 51 + l10n/lb/user_openid.po | 54 + l10n/lt_LT/admin_dependencies_chk.po | 74 + l10n/lt_LT/admin_migrate.po | 33 + l10n/lt_LT/bookmarks.po | 61 + l10n/lt_LT/calendar.po | 450 +- l10n/lt_LT/contacts.po | 939 +- l10n/lt_LT/core.po | 299 +- l10n/lt_LT/files.po | 214 +- l10n/lt_LT/files_encryption.po | 35 + l10n/lt_LT/files_external.po | 107 + l10n/lt_LT/files_odfviewer.po | 22 + l10n/lt_LT/files_pdfviewer.po | 42 + l10n/lt_LT/files_sharing.po | 49 + l10n/lt_LT/files_texteditor.po | 44 + l10n/lt_LT/files_versions.po | 43 + l10n/lt_LT/impress.po | 22 + l10n/lt_LT/lib.po | 126 + l10n/lt_LT/settings.po | 217 +- l10n/lt_LT/tasks.po | 107 + l10n/lt_LT/user_ldap.po | 171 + l10n/lt_LT/user_migrate.po | 52 + l10n/lt_LT/user_openid.po | 54 + l10n/lv/admin_dependencies_chk.po | 73 + l10n/lv/admin_migrate.po | 32 + l10n/lv/bookmarks.po | 60 + l10n/lv/calendar.po | 813 + l10n/lv/contacts.po | 952 + l10n/lv/core.po | 432 + l10n/lv/files.po | 300 + l10n/lv/files_encryption.po | 34 + l10n/lv/files_external.po | 106 + l10n/lv/files_odfviewer.po | 22 + l10n/lv/files_pdfviewer.po | 42 + l10n/lv/files_sharing.po | 48 + l10n/lv/files_texteditor.po | 44 + l10n/lv/files_versions.po | 42 + l10n/lv/gallery.po | 58 + l10n/lv/impress.po | 22 + l10n/lv/lib.po | 125 + l10n/lv/media.po | 66 + l10n/lv/settings.po | 322 + l10n/lv/tasks.po | 106 + l10n/lv/user_ldap.po | 170 + l10n/lv/user_migrate.po | 51 + l10n/lv/user_openid.po | 54 + l10n/mk/admin_dependencies_chk.po | 73 + l10n/mk/admin_migrate.po | 32 + l10n/mk/bookmarks.po | 60 + l10n/mk/calendar.po | 469 +- l10n/mk/contacts.po | 1012 +- l10n/mk/core.po | 296 +- l10n/mk/files.po | 202 +- l10n/mk/files_encryption.po | 34 + l10n/mk/files_external.po | 106 + l10n/mk/files_odfviewer.po | 22 + l10n/mk/files_pdfviewer.po | 42 + l10n/mk/files_sharing.po | 48 + l10n/mk/files_texteditor.po | 44 + l10n/mk/files_versions.po | 42 + l10n/mk/impress.po | 22 + l10n/mk/lib.po | 125 + l10n/mk/settings.po | 222 +- l10n/mk/tasks.po | 106 + l10n/mk/user_ldap.po | 170 + l10n/mk/user_migrate.po | 51 + l10n/mk/user_openid.po | 54 + l10n/ms_MY/admin_dependencies_chk.po | 73 + l10n/ms_MY/admin_migrate.po | 32 + l10n/ms_MY/bookmarks.po | 60 + l10n/ms_MY/calendar.po | 521 +- l10n/ms_MY/contacts.po | 1199 +- l10n/ms_MY/core.po | 308 +- l10n/ms_MY/files.po | 225 +- l10n/ms_MY/files_encryption.po | 34 + l10n/ms_MY/files_external.po | 106 + l10n/ms_MY/files_odfviewer.po | 22 + l10n/ms_MY/files_pdfviewer.po | 42 + l10n/ms_MY/files_sharing.po | 48 + l10n/ms_MY/files_texteditor.po | 44 + l10n/ms_MY/files_versions.po | 42 + l10n/ms_MY/impress.po | 22 + l10n/ms_MY/lib.po | 125 + l10n/ms_MY/settings.po | 245 +- l10n/ms_MY/tasks.po | 106 + l10n/ms_MY/user_ldap.po | 170 + l10n/ms_MY/user_migrate.po | 51 + l10n/ms_MY/user_openid.po | 54 + l10n/nb_NO/admin_dependencies_chk.po | 74 + l10n/nb_NO/admin_migrate.po | 33 + l10n/nb_NO/bookmarks.po | 62 + l10n/nb_NO/calendar.po | 452 +- l10n/nb_NO/contacts.po | 1001 +- l10n/nb_NO/core.po | 296 +- l10n/nb_NO/files.po | 204 +- l10n/nb_NO/files_encryption.po | 35 + l10n/nb_NO/files_external.po | 107 + l10n/nb_NO/files_odfviewer.po | 22 + l10n/nb_NO/files_pdfviewer.po | 42 + l10n/nb_NO/files_sharing.po | 49 + l10n/nb_NO/files_texteditor.po | 44 + l10n/nb_NO/files_versions.po | 43 + l10n/nb_NO/gallery.po | 85 +- l10n/nb_NO/impress.po | 22 + l10n/nb_NO/lib.po | 127 + l10n/nb_NO/settings.po | 231 +- l10n/nb_NO/tasks.po | 107 + l10n/nb_NO/user_ldap.po | 170 + l10n/nb_NO/user_migrate.po | 51 + l10n/nb_NO/user_openid.po | 54 + l10n/nl/admin_dependencies_chk.po | 73 + l10n/nl/admin_migrate.po | 33 + l10n/nl/bookmarks.po | 61 + l10n/nl/calendar.po | 474 +- l10n/nl/contacts.po | 1036 +- l10n/nl/core.po | 304 +- l10n/nl/files.po | 214 +- l10n/nl/files_encryption.po | 35 + l10n/nl/files_external.po | 107 + l10n/nl/files_odfviewer.po | 22 + l10n/nl/files_pdfviewer.po | 42 + l10n/nl/files_sharing.po | 50 + l10n/nl/files_texteditor.po | 44 + l10n/nl/files_versions.po | 43 + l10n/nl/gallery.po | 85 +- l10n/nl/impress.po | 22 + l10n/nl/lib.po | 126 + l10n/nl/settings.po | 227 +- l10n/nl/tasks.po | 106 + l10n/nl/user_ldap.po | 170 + l10n/nl/user_migrate.po | 51 + l10n/nl/user_openid.po | 55 + l10n/nn_NO/admin_dependencies_chk.po | 73 + l10n/nn_NO/admin_migrate.po | 32 + l10n/nn_NO/bookmarks.po | 60 + l10n/nn_NO/calendar.po | 448 +- l10n/nn_NO/contacts.po | 925 +- l10n/nn_NO/core.po | 263 +- l10n/nn_NO/files.po | 189 +- l10n/nn_NO/files_encryption.po | 34 + l10n/nn_NO/files_external.po | 106 + l10n/nn_NO/files_odfviewer.po | 22 + l10n/nn_NO/files_pdfviewer.po | 42 + l10n/nn_NO/files_sharing.po | 48 + l10n/nn_NO/files_texteditor.po | 44 + l10n/nn_NO/files_versions.po | 42 + l10n/nn_NO/impress.po | 22 + l10n/nn_NO/lib.po | 125 + l10n/nn_NO/settings.po | 219 +- l10n/nn_NO/tasks.po | 106 + l10n/nn_NO/user_ldap.po | 170 + l10n/nn_NO/user_migrate.po | 51 + l10n/nn_NO/user_openid.po | 54 + l10n/oc/core.po | 432 + l10n/oc/files.po | 300 + l10n/oc/files_encryption.po | 34 + l10n/oc/files_external.po | 106 + l10n/oc/files_sharing.po | 48 + l10n/oc/files_versions.po | 42 + l10n/oc/lib.po | 126 + l10n/oc/settings.po | 322 + l10n/oc/user_ldap.po | 170 + l10n/pl/admin_dependencies_chk.po | 74 + l10n/pl/admin_migrate.po | 33 + l10n/pl/bookmarks.po | 60 + l10n/pl/calendar.po | 469 +- l10n/pl/contacts.po | 1016 +- l10n/pl/core.po | 302 +- l10n/pl/files.po | 215 +- l10n/pl/files_encryption.po | 35 + l10n/pl/files_external.po | 108 + l10n/pl/files_odfviewer.po | 22 + l10n/pl/files_pdfviewer.po | 42 + l10n/pl/files_sharing.po | 51 + l10n/pl/files_texteditor.po | 44 + l10n/pl/files_versions.po | 44 + l10n/pl/gallery.po | 65 +- l10n/pl/impress.po | 22 + l10n/pl/lib.po | 126 + l10n/pl/settings.po | 226 +- l10n/pl/tasks.po | 107 + l10n/pl/user_ldap.po | 172 + l10n/pl/user_migrate.po | 52 + l10n/pl/user_openid.po | 55 + l10n/pl_PL/core.po | 431 + l10n/pl_PL/files.po | 299 + l10n/pl_PL/files_encryption.po | 34 + l10n/pl_PL/files_external.po | 106 + l10n/pl_PL/files_sharing.po | 48 + l10n/pl_PL/files_versions.po | 42 + l10n/pl_PL/lib.po | 125 + l10n/pl_PL/settings.po | 321 + l10n/pl_PL/user_ldap.po | 170 + l10n/pt_BR/admin_dependencies_chk.po | 73 + l10n/pt_BR/admin_migrate.po | 32 + l10n/pt_BR/bookmarks.po | 60 + l10n/pt_BR/calendar.po | 469 +- l10n/pt_BR/contacts.po | 1013 +- l10n/pt_BR/core.po | 302 +- l10n/pt_BR/files.po | 214 +- l10n/pt_BR/files_encryption.po | 35 + l10n/pt_BR/files_external.po | 107 + l10n/pt_BR/files_odfviewer.po | 22 + l10n/pt_BR/files_pdfviewer.po | 42 + l10n/pt_BR/files_sharing.po | 49 + l10n/pt_BR/files_texteditor.po | 44 + l10n/pt_BR/files_versions.po | 44 + l10n/pt_BR/impress.po | 22 + l10n/pt_BR/lib.po | 126 + l10n/pt_BR/settings.po | 226 +- l10n/pt_BR/tasks.po | 106 + l10n/pt_BR/user_ldap.po | 171 + l10n/pt_BR/user_migrate.po | 51 + l10n/pt_BR/user_openid.po | 54 + l10n/pt_PT/admin_dependencies_chk.po | 73 + l10n/pt_PT/admin_migrate.po | 32 + l10n/pt_PT/bookmarks.po | 60 + l10n/pt_PT/calendar.po | 467 +- l10n/pt_PT/contacts.po | 1060 +- l10n/pt_PT/core.po | 300 +- l10n/pt_PT/files.po | 227 +- l10n/pt_PT/files_encryption.po | 35 + l10n/pt_PT/files_external.po | 107 + l10n/pt_PT/files_odfviewer.po | 22 + l10n/pt_PT/files_pdfviewer.po | 42 + l10n/pt_PT/files_sharing.po | 49 + l10n/pt_PT/files_texteditor.po | 44 + l10n/pt_PT/files_versions.po | 43 + l10n/pt_PT/gallery.po | 85 +- l10n/pt_PT/impress.po | 22 + l10n/pt_PT/lib.po | 126 + l10n/pt_PT/settings.po | 237 +- l10n/pt_PT/tasks.po | 106 + l10n/pt_PT/user_ldap.po | 172 + l10n/pt_PT/user_migrate.po | 51 + l10n/pt_PT/user_openid.po | 54 + l10n/ro/admin_dependencies_chk.po | 73 + l10n/ro/admin_migrate.po | 32 + l10n/ro/bookmarks.po | 60 + l10n/ro/calendar.po | 450 +- l10n/ro/contacts.po | 959 +- l10n/ro/core.po | 298 +- l10n/ro/files.po | 212 +- l10n/ro/files_encryption.po | 35 + l10n/ro/files_external.po | 107 + l10n/ro/files_odfviewer.po | 22 + l10n/ro/files_pdfviewer.po | 42 + l10n/ro/files_sharing.po | 49 + l10n/ro/files_texteditor.po | 44 + l10n/ro/files_versions.po | 43 + l10n/ro/impress.po | 22 + l10n/ro/lib.po | 126 + l10n/ro/settings.po | 225 +- l10n/ro/tasks.po | 107 + l10n/ro/user_ldap.po | 172 + l10n/ro/user_migrate.po | 51 + l10n/ro/user_openid.po | 54 + l10n/ru/admin_dependencies_chk.po | 74 + l10n/ru/admin_migrate.po | 33 + l10n/ru/bookmarks.po | 61 + l10n/ru/calendar.po | 488 +- l10n/ru/contacts.po | 1176 +- l10n/ru/core.po | 297 +- l10n/ru/files.po | 224 +- l10n/ru/files_encryption.po | 35 + l10n/ru/files_external.po | 107 + l10n/ru/files_odfviewer.po | 22 + l10n/ru/files_pdfviewer.po | 42 + l10n/ru/files_sharing.po | 51 + l10n/ru/files_texteditor.po | 44 + l10n/ru/files_versions.po | 44 + l10n/ru/gallery.po | 85 +- l10n/ru/impress.po | 22 + l10n/ru/lib.po | 128 + l10n/ru/settings.po | 227 +- l10n/ru/tasks.po | 107 + l10n/ru/user_ldap.po | 172 + l10n/ru/user_migrate.po | 52 + l10n/ru/user_openid.po | 55 + l10n/ru_RU/core.po | 432 + l10n/ru_RU/files.po | 300 + l10n/ru_RU/files_encryption.po | 35 + l10n/ru_RU/files_external.po | 107 + l10n/ru_RU/files_sharing.po | 49 + l10n/ru_RU/files_versions.po | 43 + l10n/ru_RU/lib.po | 126 + l10n/ru_RU/settings.po | 322 + l10n/ru_RU/user_ldap.po | 171 + l10n/si_LK/core.po | 432 + l10n/si_LK/files.po | 300 + l10n/si_LK/files_encryption.po | 34 + l10n/si_LK/files_external.po | 106 + l10n/si_LK/files_sharing.po | 48 + l10n/si_LK/files_versions.po | 42 + l10n/si_LK/lib.po | 125 + l10n/si_LK/settings.po | 321 + l10n/si_LK/user_ldap.po | 170 + l10n/sk_SK/admin_dependencies_chk.po | 73 + l10n/sk_SK/admin_migrate.po | 32 + l10n/sk_SK/bookmarks.po | 60 + l10n/sk_SK/calendar.po | 468 +- l10n/sk_SK/contacts.po | 1016 +- l10n/sk_SK/core.po | 300 +- l10n/sk_SK/files.po | 218 +- l10n/sk_SK/files_encryption.po | 35 + l10n/sk_SK/files_external.po | 108 + l10n/sk_SK/files_odfviewer.po | 22 + l10n/sk_SK/files_pdfviewer.po | 42 + l10n/sk_SK/files_sharing.po | 50 + l10n/sk_SK/files_texteditor.po | 44 + l10n/sk_SK/files_versions.po | 43 + l10n/sk_SK/impress.po | 22 + l10n/sk_SK/lib.po | 126 + l10n/sk_SK/settings.po | 224 +- l10n/sk_SK/tasks.po | 106 + l10n/sk_SK/user_ldap.po | 170 + l10n/sk_SK/user_migrate.po | 51 + l10n/sk_SK/user_openid.po | 54 + l10n/sl/admin_dependencies_chk.po | 74 + l10n/sl/admin_migrate.po | 33 + l10n/sl/bookmarks.po | 61 + l10n/sl/calendar.po | 468 +- l10n/sl/contacts.po | 1023 +- l10n/sl/core.po | 295 +- l10n/sl/files.po | 209 +- l10n/sl/files_encryption.po | 35 + l10n/sl/files_external.po | 107 + l10n/sl/files_odfviewer.po | 22 + l10n/sl/files_pdfviewer.po | 42 + l10n/sl/files_sharing.po | 49 + l10n/sl/files_texteditor.po | 44 + l10n/sl/files_versions.po | 43 + l10n/sl/gallery.po | 64 +- l10n/sl/impress.po | 22 + l10n/sl/lib.po | 126 + l10n/sl/settings.po | 221 +- l10n/sl/tasks.po | 107 + l10n/sl/user_ldap.po | 171 + l10n/sl/user_migrate.po | 52 + l10n/sl/user_openid.po | 55 + l10n/so/admin_dependencies_chk.po | 73 + l10n/so/admin_migrate.po | 32 + l10n/so/bookmarks.po | 60 + l10n/so/calendar.po | 813 + l10n/so/contacts.po | 952 + l10n/so/core.po | 431 + l10n/so/files.po | 299 + l10n/so/files_encryption.po | 34 + l10n/so/files_external.po | 106 + l10n/so/files_odfviewer.po | 22 + l10n/so/files_pdfviewer.po | 42 + l10n/so/files_sharing.po | 48 + l10n/so/files_texteditor.po | 44 + l10n/so/files_versions.po | 42 + l10n/so/gallery.po | 58 + l10n/so/impress.po | 22 + l10n/so/lib.po | 125 + l10n/so/media.po | 66 + l10n/so/settings.po | 321 + l10n/so/tasks.po | 106 + l10n/so/user_ldap.po | 170 + l10n/so/user_migrate.po | 51 + l10n/so/user_openid.po | 54 + l10n/sr/admin_dependencies_chk.po | 73 + l10n/sr/admin_migrate.po | 32 + l10n/sr/bookmarks.po | 60 + l10n/sr/calendar.po | 446 +- l10n/sr/contacts.po | 915 +- l10n/sr/core.po | 263 +- l10n/sr/files.po | 189 +- l10n/sr/files_encryption.po | 34 + l10n/sr/files_external.po | 106 + l10n/sr/files_odfviewer.po | 22 + l10n/sr/files_pdfviewer.po | 42 + l10n/sr/files_sharing.po | 48 + l10n/sr/files_texteditor.po | 44 + l10n/sr/files_versions.po | 42 + l10n/sr/impress.po | 22 + l10n/sr/lib.po | 125 + l10n/sr/settings.po | 211 +- l10n/sr/tasks.po | 106 + l10n/sr/user_ldap.po | 170 + l10n/sr/user_migrate.po | 51 + l10n/sr/user_openid.po | 54 + l10n/sr@latin/admin_dependencies_chk.po | 73 + l10n/sr@latin/admin_migrate.po | 32 + l10n/sr@latin/bookmarks.po | 60 + l10n/sr@latin/calendar.po | 446 +- l10n/sr@latin/contacts.po | 911 +- l10n/sr@latin/core.po | 261 +- l10n/sr@latin/files.po | 189 +- l10n/sr@latin/files_encryption.po | 34 + l10n/sr@latin/files_external.po | 106 + l10n/sr@latin/files_odfviewer.po | 22 + l10n/sr@latin/files_pdfviewer.po | 42 + l10n/sr@latin/files_sharing.po | 48 + l10n/sr@latin/files_texteditor.po | 44 + l10n/sr@latin/files_versions.po | 42 + l10n/sr@latin/impress.po | 22 + l10n/sr@latin/lib.po | 125 + l10n/sr@latin/settings.po | 211 +- l10n/sr@latin/tasks.po | 106 + l10n/sr@latin/user_ldap.po | 170 + l10n/sr@latin/user_migrate.po | 51 + l10n/sr@latin/user_openid.po | 54 + l10n/sv/admin_dependencies_chk.po | 74 + l10n/sv/admin_migrate.po | 33 + l10n/sv/bookmarks.po | 61 + l10n/sv/calendar.po | 469 +- l10n/sv/contacts.po | 1063 +- l10n/sv/core.po | 317 +- l10n/sv/files.po | 229 +- l10n/sv/files_encryption.po | 35 + l10n/sv/files_external.po | 107 + l10n/sv/files_odfviewer.po | 22 + l10n/sv/files_pdfviewer.po | 42 + l10n/sv/files_sharing.po | 49 + l10n/sv/files_texteditor.po | 44 + l10n/sv/files_versions.po | 43 + l10n/sv/gallery.po | 65 +- l10n/sv/impress.po | 22 + l10n/sv/lib.po | 127 + l10n/sv/media.po | 14 +- l10n/sv/settings.po | 236 +- l10n/sv/tasks.po | 107 + l10n/sv/user_ldap.po | 171 + l10n/sv/user_migrate.po | 52 + l10n/sv/user_openid.po | 55 + l10n/ta_LK/core.po | 431 + l10n/ta_LK/files.po | 299 + l10n/ta_LK/files_encryption.po | 34 + l10n/ta_LK/files_external.po | 106 + l10n/ta_LK/files_sharing.po | 48 + l10n/ta_LK/files_versions.po | 42 + l10n/ta_LK/lib.po | 125 + l10n/ta_LK/settings.po | 320 + l10n/ta_LK/user_ldap.po | 170 + l10n/templates/bookmarks.pot | 60 - l10n/templates/calendar.pot | 689 - l10n/templates/contacts.pot | 818 - l10n/templates/core.pot | 249 +- l10n/templates/files.pot | 181 +- l10n/templates/files_encryption.pot | 34 + l10n/templates/files_external.pot | 106 + l10n/templates/files_sharing.pot | 48 + l10n/templates/files_versions.pot | 42 + l10n/templates/gallery.pot | 94 - l10n/templates/lib.pot | 125 + l10n/templates/media.pot | 66 - l10n/templates/settings.pot | 198 +- l10n/templates/user_ldap.pot | 168 + l10n/th_TH/admin_dependencies_chk.po | 74 + l10n/th_TH/admin_migrate.po | 33 + l10n/th_TH/bookmarks.po | 61 + l10n/th_TH/calendar.po | 468 +- l10n/th_TH/contacts.po | 1013 +- l10n/th_TH/core.po | 299 +- l10n/th_TH/files.po | 211 +- l10n/th_TH/files_encryption.po | 35 + l10n/th_TH/files_external.po | 107 + l10n/th_TH/files_odfviewer.po | 22 + l10n/th_TH/files_pdfviewer.po | 42 + l10n/th_TH/files_sharing.po | 49 + l10n/th_TH/files_texteditor.po | 44 + l10n/th_TH/files_versions.po | 43 + l10n/th_TH/gallery.po | 84 +- l10n/th_TH/impress.po | 22 + l10n/th_TH/lib.po | 126 + l10n/th_TH/settings.po | 223 +- l10n/th_TH/tasks.po | 107 + l10n/th_TH/user_ldap.po | 171 + l10n/th_TH/user_migrate.po | 52 + l10n/th_TH/user_openid.po | 55 + l10n/tr/admin_dependencies_chk.po | 73 + l10n/tr/admin_migrate.po | 32 + l10n/tr/bookmarks.po | 60 + l10n/tr/calendar.po | 470 +- l10n/tr/contacts.po | 1012 +- l10n/tr/core.po | 297 +- l10n/tr/files.po | 205 +- l10n/tr/files_encryption.po | 34 + l10n/tr/files_external.po | 106 + l10n/tr/files_odfviewer.po | 22 + l10n/tr/files_pdfviewer.po | 42 + l10n/tr/files_sharing.po | 48 + l10n/tr/files_texteditor.po | 44 + l10n/tr/files_versions.po | 42 + l10n/tr/gallery.po | 66 +- l10n/tr/impress.po | 22 + l10n/tr/lib.po | 125 + l10n/tr/settings.po | 223 +- l10n/tr/tasks.po | 106 + l10n/tr/user_ldap.po | 170 + l10n/tr/user_migrate.po | 51 + l10n/tr/user_openid.po | 54 + l10n/uk/admin_dependencies_chk.po | 73 + l10n/uk/admin_migrate.po | 32 + l10n/uk/bookmarks.po | 60 + l10n/uk/calendar.po | 476 +- l10n/uk/contacts.po | 915 +- l10n/uk/core.po | 292 +- l10n/uk/files.po | 215 +- l10n/uk/files_encryption.po | 34 + l10n/uk/files_external.po | 107 + l10n/uk/files_odfviewer.po | 22 + l10n/uk/files_pdfviewer.po | 42 + l10n/uk/files_sharing.po | 49 + l10n/uk/files_texteditor.po | 44 + l10n/uk/files_versions.po | 42 + l10n/uk/impress.po | 22 + l10n/uk/lib.po | 127 + l10n/uk/media.po | 35 +- l10n/uk/settings.po | 236 +- l10n/uk/tasks.po | 106 + l10n/uk/user_ldap.po | 171 + l10n/uk/user_migrate.po | 51 + l10n/uk/user_openid.po | 54 + l10n/vi/admin_dependencies_chk.po | 73 + l10n/vi/admin_migrate.po | 32 + l10n/vi/bookmarks.po | 60 + l10n/vi/calendar.po | 815 + l10n/vi/contacts.po | 953 + l10n/vi/core.po | 432 + l10n/vi/files.po | 301 + l10n/vi/files_encryption.po | 35 + l10n/vi/files_external.po | 107 + l10n/vi/files_odfviewer.po | 22 + l10n/vi/files_pdfviewer.po | 42 + l10n/vi/files_sharing.po | 49 + l10n/vi/files_texteditor.po | 44 + l10n/vi/files_versions.po | 43 + l10n/vi/gallery.po | 60 + l10n/vi/impress.po | 22 + l10n/vi/lib.po | 126 + l10n/vi/media.po | 67 + l10n/vi/settings.po | 325 + l10n/vi/tasks.po | 106 + l10n/vi/user_ldap.po | 171 + l10n/vi/user_migrate.po | 51 + l10n/vi/user_openid.po | 54 + l10n/zh_CN.GB2312/admin_dependencies_chk.po | 73 + l10n/zh_CN.GB2312/admin_migrate.po | 32 + l10n/zh_CN.GB2312/bookmarks.po | 60 + l10n/zh_CN.GB2312/calendar.po | 814 + l10n/zh_CN.GB2312/contacts.po | 952 + l10n/zh_CN.GB2312/core.po | 433 + l10n/zh_CN.GB2312/files.po | 301 + l10n/zh_CN.GB2312/files_encryption.po | 35 + l10n/zh_CN.GB2312/files_external.po | 107 + l10n/zh_CN.GB2312/files_odfviewer.po | 22 + l10n/zh_CN.GB2312/files_pdfviewer.po | 42 + l10n/zh_CN.GB2312/files_sharing.po | 49 + l10n/zh_CN.GB2312/files_texteditor.po | 44 + l10n/zh_CN.GB2312/files_versions.po | 43 + l10n/zh_CN.GB2312/gallery.po | 58 + l10n/zh_CN.GB2312/impress.po | 22 + l10n/zh_CN.GB2312/lib.po | 126 + l10n/zh_CN.GB2312/media.po | 67 + l10n/zh_CN.GB2312/settings.po | 323 + l10n/zh_CN.GB2312/tasks.po | 106 + l10n/zh_CN.GB2312/user_ldap.po | 171 + l10n/zh_CN.GB2312/user_migrate.po | 51 + l10n/zh_CN.GB2312/user_openid.po | 54 + l10n/zh_CN/admin_dependencies_chk.po | 73 + l10n/zh_CN/admin_migrate.po | 32 + l10n/zh_CN/bookmarks.po | 61 + l10n/zh_CN/calendar.po | 453 +- l10n/zh_CN/contacts.po | 1056 +- l10n/zh_CN/core.po | 300 +- l10n/zh_CN/files.po | 214 +- l10n/zh_CN/files_encryption.po | 35 + l10n/zh_CN/files_external.po | 106 + l10n/zh_CN/files_odfviewer.po | 22 + l10n/zh_CN/files_pdfviewer.po | 42 + l10n/zh_CN/files_sharing.po | 49 + l10n/zh_CN/files_texteditor.po | 44 + l10n/zh_CN/files_versions.po | 43 + l10n/zh_CN/gallery.po | 85 +- l10n/zh_CN/impress.po | 22 + l10n/zh_CN/lib.po | 127 + l10n/zh_CN/settings.po | 226 +- l10n/zh_CN/tasks.po | 106 + l10n/zh_CN/user_ldap.po | 171 + l10n/zh_CN/user_migrate.po | 51 + l10n/zh_CN/user_openid.po | 54 + l10n/zh_TW/admin_dependencies_chk.po | 73 + l10n/zh_TW/admin_migrate.po | 32 + l10n/zh_TW/bookmarks.po | 60 + l10n/zh_TW/calendar.po | 450 +- l10n/zh_TW/contacts.po | 977 +- l10n/zh_TW/core.po | 296 +- l10n/zh_TW/files.po | 198 +- l10n/zh_TW/files_encryption.po | 35 + l10n/zh_TW/files_external.po | 106 + l10n/zh_TW/files_odfviewer.po | 22 + l10n/zh_TW/files_pdfviewer.po | 42 + l10n/zh_TW/files_sharing.po | 49 + l10n/zh_TW/files_texteditor.po | 44 + l10n/zh_TW/files_versions.po | 42 + l10n/zh_TW/impress.po | 22 + l10n/zh_TW/lib.po | 127 + l10n/zh_TW/settings.po | 228 +- l10n/zh_TW/tasks.po | 106 + l10n/zh_TW/user_ldap.po | 170 + l10n/zh_TW/user_migrate.po | 51 + l10n/zh_TW/user_openid.po | 54 + lib/MDB2/Driver/Datatype/sqlite3.php | 6 +- lib/MDB2/Driver/Function/sqlite3.php | 8 +- lib/MDB2/Driver/Manager/sqlite3.php | 4 +- lib/MDB2/Driver/Native/sqlite3.php | 1 - lib/MDB2/Driver/Reverse/sqlite3.php | 4 +- lib/MDB2/Driver/sqlite3.php | 30 +- lib/app.php | 371 +- lib/appconfig.php | 96 +- lib/archive.php | 31 +- lib/archive/tar.php | 174 +- lib/archive/zip.php | 91 +- lib/backgroundjob/queuedtask.php | 104 + lib/backgroundjob/regulartask.php | 52 + lib/backgroundjob/worker.php | 118 + lib/base.php | 426 +- lib/cache.php | 108 +- lib/cache/apc.php | 5 +- lib/cache/broker.php | 6 +- lib/cache/file.php | 43 +- lib/cache/fileglobal.php | 45 +- lib/cache/xcache.php | 17 +- lib/config.php | 50 +- lib/connector/sabre/auth.php | 21 +- lib/connector/sabre/client.php | 342 +- lib/connector/sabre/directory.php | 76 +- lib/connector/sabre/file.php | 35 +- lib/connector/sabre/locks.php | 29 +- lib/connector/sabre/node.php | 64 +- lib/connector/sabre/principal.php | 12 +- lib/db.php | 463 +- lib/eventsource.php | 21 +- lib/filecache.php | 272 +- lib/filecache/cached.php | 43 +- lib/filecache/update.php | 124 +- lib/filechunking.php | 148 + lib/fileproxy.php | 40 +- lib/fileproxy/fileoperations.php | 37 + lib/fileproxy/quota.php | 40 +- lib/files.php | 187 +- lib/filestorage.php | 12 +- lib/filestorage/common.php | 147 +- lib/filestorage/commontest.php | 34 +- lib/filestorage/local.php | 112 +- lib/filestorage/temporary.php | 6 +- lib/filesystem.php | 484 +- lib/filesystemview.php | 566 +- lib/geo.php | 4 +- lib/group.php | 142 +- lib/group/backend.php | 48 +- lib/group/database.php | 134 +- lib/group/dummy.php | 37 +- lib/group/example.php | 18 +- lib/group/interface.php | 83 + lib/helper.php | 382 +- lib/hook.php | 45 +- lib/image.php | 174 +- lib/installer.php | 154 +- lib/json.php | 79 +- lib/l10n.php | 122 +- lib/l10n/ca.php | 28 + lib/l10n/cs_CZ.php | 28 + lib/l10n/da.php | 28 + lib/l10n/de.php | 28 + lib/l10n/el.php | 28 + lib/l10n/eo.php | 28 + lib/l10n/es.php | 28 + lib/l10n/es_AR.php | 28 + lib/l10n/et_EE.php | 28 + lib/l10n/eu.php | 28 + lib/l10n/fa.php | 16 + lib/l10n/fi_FI.php | 28 + lib/l10n/fr.php | 28 + lib/l10n/gl.php | 28 + lib/l10n/he.php | 28 + lib/l10n/hu_HU.php | 25 + lib/l10n/it.php | 28 + lib/l10n/ja_JP.php | 28 + lib/l10n/lt_LT.php | 21 + lib/l10n/nb_NO.php | 25 + lib/l10n/nl.php | 28 + lib/l10n/oc.php | 24 + lib/l10n/pl.php | 28 + lib/l10n/pt_BR.php | 28 + lib/l10n/pt_PT.php | 28 + lib/l10n/ro.php | 28 + lib/l10n/ru.php | 28 + lib/l10n/ru_RU.php | 28 + lib/l10n/sk_SK.php | 25 + lib/l10n/sl.php | 28 + lib/l10n/string.php | 6 +- lib/l10n/sv.php | 28 + lib/l10n/th_TH.php | 28 + lib/l10n/uk.php | 25 + lib/l10n/vi.php | 28 + lib/l10n/zh_CN.GB2312.php | 28 + lib/l10n/zh_CN.php | 28 + lib/l10n/zh_TW.php | 28 + lib/log.php | 35 +- lib/log/owncloud.php | 4 +- lib/mail.php | 72 +- lib/migrate.php | 206 +- lib/migration/content.php | 139 +- lib/migration/provider.php | 26 +- lib/mimetypes.fixlist.php | 22 - lib/mimetypes.list.php | 18 +- lib/minimizer.php | 41 +- lib/minimizer/css.php | 6 +- lib/minimizer/js.php | 4 +- lib/ocs.php | 272 +- lib/ocsclient.php | 90 +- lib/preferences.php | 118 +- lib/public/app.php | 184 +- lib/public/backgroundjob.php | 117 + lib/public/config.php | 123 +- lib/public/db.php | 23 +- lib/public/files.php | 35 +- lib/public/groupinterface.php | 31 + lib/public/json.php | 125 +- lib/public/response.php | 12 +- lib/public/share.php | 1251 + lib/public/template.php | 16 +- lib/public/user.php | 52 +- lib/public/userinterface.php | 31 + lib/public/util.php | 97 +- lib/request.php | 77 + lib/response.php | 3 +- lib/search.php | 22 +- lib/search/provider.php | 12 +- lib/search/provider/file.php | 36 +- lib/search/result.php | 2 +- lib/setup.php | 251 +- lib/streamwrappers.php | 45 +- lib/subadmin.php | 184 + lib/template.php | 208 +- lib/templatelayout.php | 43 +- lib/updater.php | 30 +- lib/user.php | 249 +- lib/user/backend.php | 25 +- lib/user/database.php | 76 +- lib/user/dummy.php | 20 +- lib/user/example.php | 22 +- lib/user/http.php | 37 +- lib/user/interface.php | 60 + lib/util.php | 413 +- lib/vcategories.php | 15 +- lib/vobject.php | 64 +- ocs/providers.php | 8 +- ocs/v1.php | 2 +- public.php | 14 +- remote.php | 35 +- search/ajax/search.php | 4 +- search/index.php | 51 - search/js/result.js | 3 +- search/templates/index.php | 17 - settings/admin.php | 14 +- settings/ajax/apps/ocs.php | 65 + settings/ajax/changepassword.php | 34 +- settings/ajax/creategroup.php | 18 +- settings/ajax/createuser.php | 44 +- settings/ajax/disableapp.php | 2 +- settings/ajax/enableapp.php | 12 +- settings/ajax/getlog.php | 6 +- settings/ajax/lostpassword.php | 6 +- settings/ajax/openid.php | 6 +- settings/ajax/removegroup.php | 6 +- settings/ajax/removeuser.php | 21 +- settings/ajax/setlanguage.php | 6 +- settings/ajax/setloglevel.php | 4 +- settings/ajax/setquota.php | 24 +- settings/ajax/togglegroups.php | 32 +- settings/ajax/togglesubadmins.php | 19 + settings/ajax/userlist.php | 52 + settings/apps.php | 137 +- settings/css/settings.css | 28 +- settings/help.php | 4 +- settings/img/admin.png | Bin 302 -> 224 bytes settings/img/apps.png | Bin 255 -> 229 bytes settings/img/help.png | Bin 474 -> 423 bytes settings/img/log.png | Bin 441 -> 342 bytes settings/img/personal.png | Bin 589 -> 504 bytes settings/img/users.png | Bin 743 -> 639 bytes settings/js/admin.js | 30 +- settings/js/apps.js | 153 +- settings/js/log.js | 3 + settings/js/personal.js | 2 +- settings/js/users.js | 309 +- settings/l10n/ar.php | 5 - settings/l10n/bg_BG.php | 18 +- settings/l10n/ca.php | 43 +- settings/l10n/cs_CZ.php | 67 +- settings/l10n/da.php | 41 +- settings/l10n/de.php | 63 +- settings/l10n/el.php | 71 +- settings/l10n/eo.php | 38 +- settings/l10n/es.php | 41 +- settings/l10n/es_AR.php | 73 + settings/l10n/et_EE.php | 31 +- settings/l10n/eu.php | 42 +- settings/l10n/fa.php | 12 +- settings/l10n/fi_FI.php | 39 +- settings/l10n/fr.php | 43 +- settings/l10n/gl.php | 15 +- settings/l10n/he.php | 11 +- settings/l10n/hr.php | 15 +- settings/l10n/hu_HU.php | 14 +- settings/l10n/ia.php | 4 - settings/l10n/id.php | 13 +- settings/l10n/it.php | 43 +- settings/l10n/ja_JP.php | 41 +- settings/l10n/ko.php | 16 +- settings/l10n/lb.php | 22 +- settings/l10n/lt_LT.php | 12 +- settings/l10n/lv.php | 48 + settings/l10n/mk.php | 11 +- settings/l10n/ms_MY.php | 32 +- settings/l10n/nb_NO.php | 19 +- settings/l10n/nl.php | 41 +- settings/l10n/nn_NO.php | 11 +- settings/l10n/oc.php | 61 + settings/l10n/pl.php | 41 +- settings/l10n/pt_BR.php | 41 +- settings/l10n/pt_PT.php | 51 +- settings/l10n/ro.php | 40 +- settings/l10n/ru.php | 33 +- settings/l10n/ru_RU.php | 72 + settings/l10n/si_LK.php | 15 + settings/l10n/sk_SK.php | 37 +- settings/l10n/sl.php | 40 +- settings/l10n/sr.php | 5 - settings/l10n/sr@latin.php | 5 - settings/l10n/sv.php | 47 +- settings/l10n/th_TH.php | 41 +- settings/l10n/tr.php | 13 +- settings/l10n/uk.php | 18 + settings/l10n/vi.php | 65 + settings/l10n/zh_CN.GB2312.php | 72 + settings/l10n/zh_CN.php | 42 +- settings/l10n/zh_TW.php | 30 +- settings/languageCodes.php | 9 + settings/log.php | 44 - settings/personal.php | 35 +- settings/settings.php | 9 +- settings/templates/admin.php | 69 +- settings/templates/apps.php | 23 +- settings/templates/help.php | 7 +- settings/templates/personal.php | 6 +- settings/templates/settings.php | 2 +- settings/templates/users.php | 73 +- settings/trans.png | Bin 187 -> 185 bytes settings/users.php | 46 +- status.php | 10 +- tests/apps.php | 41 + tests/bootstrap.php | 31 + .../tests => tests}/data/data.tar.gz | Bin .../tests => tests}/data/data.zip | Bin tests/data/db_structure.xml | 138 + tests/data/db_structure2.xml | 77 + tests/data/logo-wide.png | Bin 3559 -> 2882 bytes tests/index.php | 73 - tests/lib/archive.php | 58 +- tests/lib/archive/tar.php | 22 +- tests/lib/archive/zip.php | 22 +- tests/lib/cache.php | 37 +- tests/lib/cache/apc.php | 19 +- tests/lib/cache/file.php | 27 +- tests/lib/cache/xcache.php | 14 +- tests/lib/db.php | 70 + tests/lib/dbschema.php | 118 + tests/lib/filestorage.php | 337 +- tests/lib/filestorage/commontest.php | 6 +- tests/lib/filestorage/local.php | 4 +- tests/lib/filesystem.php | 127 +- tests/lib/geo.php | 19 + tests/lib/group.php | 6 +- tests/lib/group/backend.php | 8 +- tests/lib/group/database.php | 10 +- tests/lib/group/dummy.php | 2 +- tests/lib/helper.php | 140 + tests/lib/share/backend.php | 71 + tests/lib/share/share.php | 408 + tests/lib/streamwrappers.php | 16 +- tests/lib/user/backend.php | 6 +- tests/lib/user/database.php | 9 +- tests/lib/user/dummy.php | 2 +- tests/lib/util.php | 45 + tests/phpunit.xml | 7 + themes/README | 2 +- webapps.php | 54 - 3169 files changed, 195341 insertions(+), 257373 deletions(-) delete mode 100644 .tx/config create mode 100644 3rdparty/MDB2/Driver/Datatype/oci8.php create mode 100644 3rdparty/MDB2/Driver/Function/oci8.php create mode 100644 3rdparty/MDB2/Driver/Manager/oci8.php create mode 100644 3rdparty/MDB2/Driver/Native/oci8.php create mode 100644 3rdparty/MDB2/Driver/Reverse/oci8.php create mode 100644 3rdparty/MDB2/Driver/oci8.php mode change 100644 => 100755 3rdparty/Sabre.includes.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Backend/Abstract.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Backend/PDO.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Calendar.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/CalendarObject.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/CalendarQueryParser.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/CalendarQueryValidator.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/CalendarRootNode.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/ICSExportPlugin.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/ICalendar.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/ICalendarObject.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Plugin.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Principal/Collection.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Principal/ProxyRead.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Principal/User.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Schedule/IMip.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Schedule/IOutbox.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Schedule/Outbox.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Server.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/UserCalendars.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/Version.php mode change 100644 => 100755 3rdparty/Sabre/CalDAV/includes.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/AddressBook.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/AddressBookQueryParser.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/AddressBookRoot.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/Backend/Abstract.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/Backend/PDO.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/Card.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/IAddressBook.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/ICard.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/IDirectory.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/Plugin.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/UserAddressBooks.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/Version.php mode change 100644 => 100755 3rdparty/Sabre/CardDAV/includes.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Auth/Backend/Apache.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Auth/Backend/File.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Auth/Backend/PDO.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Auth/IBackend.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Auth/Plugin.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/GuessContentType.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/Plugin.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/assets/favicon.ico mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/assets/icons/card.png mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/assets/icons/collection.png mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/assets/icons/file.png mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/assets/icons/parent.png mode change 100644 => 100755 3rdparty/Sabre/DAV/Browser/assets/icons/principal.png mode change 100644 => 100755 3rdparty/Sabre/DAV/Client.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Collection.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Directory.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/BadRequest.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/Conflict.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/ConflictingLock.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/FileNotFound.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/Forbidden.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/InsufficientStorage.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/InvalidResourceType.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/Locked.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/NotAuthenticated.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/NotFound.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/NotImplemented.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/PaymentRequired.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/PreconditionFailed.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php mode change 100644 => 100755 3rdparty/Sabre/DAV/FS/Directory.php mode change 100644 => 100755 3rdparty/Sabre/DAV/FS/File.php mode change 100644 => 100755 3rdparty/Sabre/DAV/FS/Node.php mode change 100644 => 100755 3rdparty/Sabre/DAV/FSExt/Directory.php mode change 100644 => 100755 3rdparty/Sabre/DAV/FSExt/File.php mode change 100644 => 100755 3rdparty/Sabre/DAV/FSExt/Node.php mode change 100644 => 100755 3rdparty/Sabre/DAV/File.php mode change 100644 => 100755 3rdparty/Sabre/DAV/ICollection.php mode change 100644 => 100755 3rdparty/Sabre/DAV/IExtendedCollection.php mode change 100644 => 100755 3rdparty/Sabre/DAV/IFile.php mode change 100644 => 100755 3rdparty/Sabre/DAV/INode.php mode change 100644 => 100755 3rdparty/Sabre/DAV/IProperties.php mode change 100644 => 100755 3rdparty/Sabre/DAV/IQuota.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Locks/Backend/Abstract.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Locks/Backend/FS.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Locks/Backend/File.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Locks/Backend/PDO.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Locks/LockInfo.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Locks/Plugin.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Mount/Plugin.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Node.php mode change 100644 => 100755 3rdparty/Sabre/DAV/ObjectTree.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/GetLastModified.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/Href.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/HrefList.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/IHref.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/LockDiscovery.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/ResourceType.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/Response.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/ResponseList.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/SupportedLock.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Property/SupportedReportSet.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Server.php mode change 100644 => 100755 3rdparty/Sabre/DAV/ServerPlugin.php mode change 100644 => 100755 3rdparty/Sabre/DAV/SimpleCollection.php mode change 100644 => 100755 3rdparty/Sabre/DAV/SimpleDirectory.php mode change 100644 => 100755 3rdparty/Sabre/DAV/SimpleFile.php mode change 100644 => 100755 3rdparty/Sabre/DAV/StringUtil.php mode change 100644 => 100755 3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Tree.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Tree/Filesystem.php mode change 100644 => 100755 3rdparty/Sabre/DAV/URLUtil.php mode change 100644 => 100755 3rdparty/Sabre/DAV/UUIDUtil.php mode change 100644 => 100755 3rdparty/Sabre/DAV/Version.php mode change 100644 => 100755 3rdparty/Sabre/DAV/XMLUtil.php mode change 100644 => 100755 3rdparty/Sabre/DAV/includes.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Exception/AceConflict.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Exception/NoAbstract.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/IACL.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/IPrincipal.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/IPrincipalBackend.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Plugin.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Principal.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/PrincipalCollection.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Property/Acl.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Property/AclRestrictions.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Property/Principal.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/Version.php mode change 100644 => 100755 3rdparty/Sabre/DAVACL/includes.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/AWSAuth.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/AbstractAuth.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/BasicAuth.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/DigestAuth.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/Request.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/Response.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/Util.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/Version.php mode change 100644 => 100755 3rdparty/Sabre/HTTP/includes.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Component.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Component/VAlarm.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Component/VCalendar.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Component/VEvent.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Component/VJournal.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Component/VTodo.php mode change 100644 => 100755 3rdparty/Sabre/VObject/DateTimeParser.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Element.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Element/DateTime.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Element/MultiDateTime.php mode change 100644 => 100755 3rdparty/Sabre/VObject/ElementList.php mode change 100644 => 100755 3rdparty/Sabre/VObject/FreeBusyGenerator.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Node.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Parameter.php mode change 100644 => 100755 3rdparty/Sabre/VObject/ParseException.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Property.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Property/DateTime.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Property/MultiDateTime.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Reader.php mode change 100644 => 100755 3rdparty/Sabre/VObject/RecurrenceIterator.php mode change 100644 => 100755 3rdparty/Sabre/VObject/Version.php mode change 100644 => 100755 3rdparty/Sabre/VObject/WindowsTimezoneMap.php mode change 100644 => 100755 3rdparty/Sabre/VObject/includes.php mode change 100644 => 100755 3rdparty/Sabre/autoload.php mode change 100644 => 100755 3rdparty/css/chosen-sprite.png mode change 100644 => 100755 3rdparty/css/chosen.css mode change 100644 => 100755 3rdparty/css/chosen/chosen.css mode change 100644 => 100755 3rdparty/js/chosen/chosen.jquery.js mode change 100644 => 100755 3rdparty/js/chosen/chosen.jquery.min.js create mode 100644 3rdparty/miniColors/GPL-LICENSE.txt create mode 100644 3rdparty/miniColors/MIT-LICENSE.txt create mode 100755 3rdparty/miniColors/css/images/colors.png create mode 100755 3rdparty/miniColors/css/images/trigger.png create mode 100755 3rdparty/miniColors/css/jquery.miniColors.css create mode 100755 3rdparty/miniColors/js/jquery.miniColors.js create mode 100755 3rdparty/miniColors/js/jquery.miniColors.min.js rename {apps/user_openid => 3rdparty/openid}/class.openid.v3.php (100%) rename {apps/user_openid => 3rdparty/openid}/phpmyid.php (100%) delete mode 100644 3rdparty/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE delete mode 100644 3rdparty/simpletest/LICENSE delete mode 100644 3rdparty/simpletest/README delete mode 100644 3rdparty/simpletest/VERSION delete mode 100644 3rdparty/simpletest/arguments.php delete mode 100644 3rdparty/simpletest/authentication.php delete mode 100644 3rdparty/simpletest/autorun.php delete mode 100644 3rdparty/simpletest/browser.php delete mode 100644 3rdparty/simpletest/collector.php delete mode 100644 3rdparty/simpletest/compatibility.php delete mode 100644 3rdparty/simpletest/cookies.php delete mode 100644 3rdparty/simpletest/default_reporter.php delete mode 100644 3rdparty/simpletest/detached.php delete mode 100644 3rdparty/simpletest/docs/en/authentication_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/browser_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/docs.css delete mode 100644 3rdparty/simpletest/docs/en/expectation_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/form_testing_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/group_test_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/index.html delete mode 100644 3rdparty/simpletest/docs/en/mock_objects_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/overview.html delete mode 100644 3rdparty/simpletest/docs/en/partial_mocks_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/reporter_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/unit_test_documentation.html delete mode 100644 3rdparty/simpletest/docs/en/web_tester_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/authentication_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/browser_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/docs.css delete mode 100644 3rdparty/simpletest/docs/fr/expectation_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/form_testing_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/group_test_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/index.html delete mode 100644 3rdparty/simpletest/docs/fr/mock_objects_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/overview.html delete mode 100644 3rdparty/simpletest/docs/fr/partial_mocks_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/reporter_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/unit_test_documentation.html delete mode 100644 3rdparty/simpletest/docs/fr/web_tester_documentation.html delete mode 100644 3rdparty/simpletest/dumper.php delete mode 100644 3rdparty/simpletest/eclipse.php delete mode 100644 3rdparty/simpletest/encoding.php delete mode 100644 3rdparty/simpletest/errors.php delete mode 100644 3rdparty/simpletest/exceptions.php delete mode 100644 3rdparty/simpletest/expectation.php delete mode 100644 3rdparty/simpletest/extensions/pear_test_case.php delete mode 100644 3rdparty/simpletest/extensions/testdox.php delete mode 100644 3rdparty/simpletest/extensions/testdox/test.php delete mode 100644 3rdparty/simpletest/form.php delete mode 100644 3rdparty/simpletest/frames.php delete mode 100644 3rdparty/simpletest/http.php delete mode 100644 3rdparty/simpletest/invoker.php delete mode 100644 3rdparty/simpletest/mock_objects.php delete mode 100644 3rdparty/simpletest/page.php delete mode 100644 3rdparty/simpletest/php_parser.php delete mode 100644 3rdparty/simpletest/recorder.php delete mode 100644 3rdparty/simpletest/reflection_php4.php delete mode 100644 3rdparty/simpletest/reflection_php5.php delete mode 100644 3rdparty/simpletest/remote.php delete mode 100644 3rdparty/simpletest/reporter.php delete mode 100644 3rdparty/simpletest/scorer.php delete mode 100644 3rdparty/simpletest/selector.php delete mode 100644 3rdparty/simpletest/shell_tester.php delete mode 100644 3rdparty/simpletest/simpletest.php delete mode 100644 3rdparty/simpletest/socket.php delete mode 100644 3rdparty/simpletest/tag.php delete mode 100644 3rdparty/simpletest/test_case.php delete mode 100644 3rdparty/simpletest/tidy_parser.php delete mode 100644 3rdparty/simpletest/unit_tester.php delete mode 100644 3rdparty/simpletest/url.php delete mode 100644 3rdparty/simpletest/user_agent.php delete mode 100644 3rdparty/simpletest/web_tester.php delete mode 100644 3rdparty/simpletest/xml.php mode change 100644 => 100755 3rdparty/timepicker/GPL-LICENSE.txt mode change 100644 => 100755 3rdparty/timepicker/MIT-LICENSE.txt mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_diagonals-thick_18_b81900_40x40.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_diagonals-thick_20_666666_40x40.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_flat_10_000000_40x100.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_glass_100_f6f6f6_1x400.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_glass_100_fdf5ce_1x400.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_glass_65_ffffff_1x400.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_gloss-wave_35_f6a828_500x100.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_highlight-soft_100_eeeeee_1x100.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-bg_highlight-soft_75_ffe45c_1x100.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-icons_222222_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-icons_228ef1_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-icons_ef8c08_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-icons_ffd27a_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/images/ui-icons_ffffff_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/jquery-1.5.1.min.js mode change 100644 => 100755 3rdparty/timepicker/css/include/jquery-ui-1.8.14.custom.css mode change 100644 => 100755 3rdparty/timepicker/css/include/jquery.ui.core.min.js mode change 100644 => 100755 3rdparty/timepicker/css/include/jquery.ui.position.min.js mode change 100644 => 100755 3rdparty/timepicker/css/include/jquery.ui.tabs.min.js mode change 100644 => 100755 3rdparty/timepicker/css/include/jquery.ui.widget.min.js mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_flat_10_000000_40x100.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-icons_222222_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-icons_228ef1_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-icons_ef8c08_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-icons_ffd27a_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/include/ui-lightness/images/ui-icons_ffffff_256x240.png mode change 100644 => 100755 3rdparty/timepicker/css/jquery.ui.timepicker.css mode change 100644 => 100755 3rdparty/timepicker/js/i18n/i18n.html create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-cs.js mode change 100644 => 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-de.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-es.js mode change 100644 => 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-fr.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-hr.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-it.js mode change 100644 => 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-ja.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-nl.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-pl.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-pt-BR.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-sl.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-sv.js create mode 100755 3rdparty/timepicker/js/i18n/jquery.ui.timepicker-tr.js mode change 100644 => 100755 3rdparty/timepicker/js/jquery.ui.timepicker.js mode change 100644 => 100755 3rdparty/timepicker/releases.txt delete mode 100644 apps/.gitkeep delete mode 100644 apps/admin_audit/appinfo/app.php delete mode 100644 apps/admin_audit/appinfo/info.xml delete mode 100644 apps/admin_audit/lib/hooks_handlers.php delete mode 100644 apps/admin_dependencies_chk/appinfo/app.php delete mode 100644 apps/admin_dependencies_chk/appinfo/info.xml delete mode 100644 apps/admin_dependencies_chk/appinfo/version delete mode 100644 apps/admin_dependencies_chk/css/style.css delete mode 100644 apps/admin_dependencies_chk/settings.php delete mode 100644 apps/admin_dependencies_chk/templates/settings.php delete mode 100644 apps/admin_migrate/appinfo/app.php delete mode 100644 apps/admin_migrate/appinfo/info.xml delete mode 100644 apps/admin_migrate/appinfo/version delete mode 100644 apps/admin_migrate/settings.php delete mode 100644 apps/admin_migrate/templates/settings.php delete mode 100644 apps/bookmarks/addBm.php delete mode 100644 apps/bookmarks/ajax/addBookmark.php delete mode 100644 apps/bookmarks/ajax/delBookmark.php delete mode 100644 apps/bookmarks/ajax/editBookmark.php delete mode 100644 apps/bookmarks/ajax/recordClick.php delete mode 100644 apps/bookmarks/ajax/updateList.php delete mode 100644 apps/bookmarks/appinfo/app.php delete mode 100644 apps/bookmarks/appinfo/database.xml delete mode 100644 apps/bookmarks/appinfo/info.xml delete mode 100644 apps/bookmarks/appinfo/migrate.php delete mode 100644 apps/bookmarks/appinfo/version delete mode 100644 apps/bookmarks/bookmarksHelper.php delete mode 100644 apps/bookmarks/css/bookmarks.css delete mode 100644 apps/bookmarks/img/bookmarks.png delete mode 100644 apps/bookmarks/index.php delete mode 100644 apps/bookmarks/js/addBm.js delete mode 100644 apps/bookmarks/js/bookmarks.js delete mode 100644 apps/bookmarks/js/bookmarksearch.js delete mode 100644 apps/bookmarks/l10n/xgettextfiles delete mode 100644 apps/bookmarks/lib/bookmarks.php delete mode 100644 apps/bookmarks/lib/search.php delete mode 100644 apps/bookmarks/settings.php delete mode 100644 apps/bookmarks/templates/addBm.php delete mode 100644 apps/bookmarks/templates/bookmarklet.php delete mode 100644 apps/bookmarks/templates/list.php delete mode 100644 apps/bookmarks/templates/settings.php delete mode 100644 apps/calendar/ajax/cache/rescan.php delete mode 100644 apps/calendar/ajax/cache/status.php delete mode 100644 apps/calendar/ajax/calendar/activation.php delete mode 100644 apps/calendar/ajax/calendar/delete.php delete mode 100644 apps/calendar/ajax/calendar/edit.form.php delete mode 100644 apps/calendar/ajax/calendar/edit.php delete mode 100644 apps/calendar/ajax/calendar/new.form.php delete mode 100644 apps/calendar/ajax/calendar/new.php delete mode 100644 apps/calendar/ajax/calendar/overview.php delete mode 100644 apps/calendar/ajax/calendar/update.php delete mode 100644 apps/calendar/ajax/categories/rescan.php delete mode 100644 apps/calendar/ajax/changeview.php delete mode 100644 apps/calendar/ajax/event/delete.php delete mode 100644 apps/calendar/ajax/event/edit.form.php delete mode 100644 apps/calendar/ajax/event/edit.php delete mode 100644 apps/calendar/ajax/event/move.php delete mode 100644 apps/calendar/ajax/event/new.form.php delete mode 100644 apps/calendar/ajax/event/new.php delete mode 100644 apps/calendar/ajax/event/resize.php delete mode 100644 apps/calendar/ajax/events.php delete mode 100644 apps/calendar/ajax/import/dialog.php delete mode 100644 apps/calendar/ajax/import/dropimport.php delete mode 100644 apps/calendar/ajax/import/import.php delete mode 100644 apps/calendar/ajax/settings/getfirstday.php delete mode 100644 apps/calendar/ajax/settings/gettimezonedetection.php delete mode 100644 apps/calendar/ajax/settings/guesstimezone.php delete mode 100644 apps/calendar/ajax/settings/setfirstday.php delete mode 100644 apps/calendar/ajax/settings/settimeformat.php delete mode 100644 apps/calendar/ajax/settings/settimezone.php delete mode 100644 apps/calendar/ajax/settings/timeformat.php delete mode 100644 apps/calendar/ajax/settings/timezonedetection.php delete mode 100644 apps/calendar/ajax/share/activation.php delete mode 100644 apps/calendar/ajax/share/changepermission.php delete mode 100644 apps/calendar/ajax/share/dropdown.php delete mode 100644 apps/calendar/ajax/share/share.php delete mode 100644 apps/calendar/ajax/share/unshare.php delete mode 100644 apps/calendar/appinfo/app.php delete mode 100644 apps/calendar/appinfo/database.xml delete mode 100644 apps/calendar/appinfo/info.xml delete mode 100644 apps/calendar/appinfo/remote.php delete mode 100644 apps/calendar/appinfo/update.php delete mode 100644 apps/calendar/appinfo/version delete mode 100644 apps/calendar/caldav.php delete mode 100644 apps/calendar/css/style.css delete mode 100644 apps/calendar/export.php delete mode 100644 apps/calendar/img/Icon License delete mode 100644 apps/calendar/img/icon.png delete mode 100644 apps/calendar/img/icon.svg delete mode 100644 apps/calendar/index.php delete mode 100644 apps/calendar/js/calendar.js delete mode 100644 apps/calendar/js/geo.js delete mode 100644 apps/calendar/js/loader.js delete mode 100644 apps/calendar/js/settings.js delete mode 100644 apps/calendar/l10n/ar.php delete mode 100644 apps/calendar/l10n/bg_BG.php delete mode 100644 apps/calendar/l10n/ca.php delete mode 100644 apps/calendar/l10n/cs_CZ.php delete mode 100644 apps/calendar/l10n/da.php delete mode 100644 apps/calendar/l10n/de.php delete mode 100644 apps/calendar/l10n/el.php delete mode 100644 apps/calendar/l10n/eo.php delete mode 100644 apps/calendar/l10n/es.php delete mode 100644 apps/calendar/l10n/et_EE.php delete mode 100644 apps/calendar/l10n/eu.php delete mode 100644 apps/calendar/l10n/fa.php delete mode 100644 apps/calendar/l10n/fi_FI.php delete mode 100644 apps/calendar/l10n/fr.php delete mode 100644 apps/calendar/l10n/gl.php delete mode 100644 apps/calendar/l10n/he.php delete mode 100644 apps/calendar/l10n/hr.php delete mode 100644 apps/calendar/l10n/hu_HU.php delete mode 100644 apps/calendar/l10n/hy.php delete mode 100644 apps/calendar/l10n/ia.php delete mode 100644 apps/calendar/l10n/id.php delete mode 100644 apps/calendar/l10n/it.php delete mode 100644 apps/calendar/l10n/ja_JP.php delete mode 100644 apps/calendar/l10n/ko.php delete mode 100644 apps/calendar/l10n/lb.php delete mode 100644 apps/calendar/l10n/lt_LT.php delete mode 100644 apps/calendar/l10n/mk.php delete mode 100644 apps/calendar/l10n/ms_MY.php delete mode 100644 apps/calendar/l10n/nb_NO.php delete mode 100644 apps/calendar/l10n/nl.php delete mode 100644 apps/calendar/l10n/nn_NO.php delete mode 100644 apps/calendar/l10n/pl.php delete mode 100644 apps/calendar/l10n/pt_BR.php delete mode 100644 apps/calendar/l10n/pt_PT.php delete mode 100644 apps/calendar/l10n/ro.php delete mode 100644 apps/calendar/l10n/ru.php delete mode 100644 apps/calendar/l10n/sk_SK.php delete mode 100644 apps/calendar/l10n/sl.php delete mode 100644 apps/calendar/l10n/sr.php delete mode 100644 apps/calendar/l10n/sr@latin.php delete mode 100644 apps/calendar/l10n/sv.php delete mode 100644 apps/calendar/l10n/th_TH.php delete mode 100644 apps/calendar/l10n/tr.php delete mode 100644 apps/calendar/l10n/uk.php delete mode 100644 apps/calendar/l10n/xgettextfiles delete mode 100644 apps/calendar/l10n/zh_CN.php delete mode 100644 apps/calendar/l10n/zh_TW.php delete mode 100644 apps/calendar/lib/alarm.php delete mode 100644 apps/calendar/lib/app.php delete mode 100644 apps/calendar/lib/attendees.php delete mode 100644 apps/calendar/lib/calendar.php delete mode 100644 apps/calendar/lib/connector_sabre.php delete mode 100644 apps/calendar/lib/export.php delete mode 100644 apps/calendar/lib/hooks.php delete mode 100644 apps/calendar/lib/object.php delete mode 100644 apps/calendar/lib/repeat.php delete mode 100644 apps/calendar/lib/search.php delete mode 100644 apps/calendar/lib/share.php delete mode 100644 apps/calendar/settings.php delete mode 100644 apps/calendar/share.php delete mode 100644 apps/calendar/templates/calendar.php delete mode 100644 apps/calendar/templates/part.choosecalendar.php delete mode 100644 apps/calendar/templates/part.choosecalendar.rowfields.php delete mode 100644 apps/calendar/templates/part.choosecalendar.rowfields.shared.php delete mode 100644 apps/calendar/templates/part.editcalendar.php delete mode 100644 apps/calendar/templates/part.editevent.php delete mode 100644 apps/calendar/templates/part.eventform.php delete mode 100644 apps/calendar/templates/part.import.php delete mode 100644 apps/calendar/templates/part.newevent.php delete mode 100644 apps/calendar/templates/part.showevent.php delete mode 100644 apps/calendar/templates/settings.php delete mode 100644 apps/calendar/templates/share.dropdown.php delete mode 100644 apps/contacts/ajax/activation.php delete mode 100644 apps/contacts/ajax/addbook.php delete mode 100644 apps/contacts/ajax/addcontact.php delete mode 100644 apps/contacts/ajax/addproperty.php delete mode 100644 apps/contacts/ajax/categories/categoriesfor.php delete mode 100644 apps/contacts/ajax/categories/delete.php delete mode 100644 apps/contacts/ajax/categories/list.php delete mode 100644 apps/contacts/ajax/categories/rescan.php delete mode 100644 apps/contacts/ajax/chooseaddressbook.php delete mode 100644 apps/contacts/ajax/contactdetails.php delete mode 100644 apps/contacts/ajax/contacts.php delete mode 100644 apps/contacts/ajax/createaddressbook.php delete mode 100644 apps/contacts/ajax/cropphoto.php delete mode 100644 apps/contacts/ajax/currentphoto.php delete mode 100644 apps/contacts/ajax/deletebook.php delete mode 100644 apps/contacts/ajax/deletecard.php delete mode 100644 apps/contacts/ajax/deleteproperty.php delete mode 100644 apps/contacts/ajax/editaddress.php delete mode 100644 apps/contacts/ajax/editaddressbook.php delete mode 100644 apps/contacts/ajax/editname.php delete mode 100644 apps/contacts/ajax/importaddressbook.php delete mode 100644 apps/contacts/ajax/importdialog.php delete mode 100644 apps/contacts/ajax/loadcard.php delete mode 100644 apps/contacts/ajax/loadintro.php delete mode 100644 apps/contacts/ajax/loadphoto.php delete mode 100644 apps/contacts/ajax/loghandler.php delete mode 100644 apps/contacts/ajax/movetoaddressbook.php delete mode 100644 apps/contacts/ajax/oc_photo.php delete mode 100644 apps/contacts/ajax/savecrop.php delete mode 100644 apps/contacts/ajax/saveproperty.php delete mode 100644 apps/contacts/ajax/updateaddressbook.php delete mode 100644 apps/contacts/ajax/uploadimport.php delete mode 100644 apps/contacts/ajax/uploadphoto.php delete mode 100644 apps/contacts/appinfo/app.php delete mode 100644 apps/contacts/appinfo/database.xml delete mode 100644 apps/contacts/appinfo/info.xml delete mode 100644 apps/contacts/appinfo/migrate.php delete mode 100644 apps/contacts/appinfo/remote.php delete mode 100644 apps/contacts/appinfo/update.php delete mode 100644 apps/contacts/appinfo/version delete mode 100644 apps/contacts/carddav.php delete mode 100644 apps/contacts/css/contacts.css delete mode 100644 apps/contacts/css/jquery.Jcrop.css delete mode 100644 apps/contacts/css/jquery.combobox.css delete mode 100644 apps/contacts/export.php delete mode 100644 apps/contacts/img/Jcrop.gif delete mode 100644 apps/contacts/img/contact-new.png delete mode 100644 apps/contacts/img/contact-new.svg delete mode 100644 apps/contacts/img/globe.svg delete mode 100644 apps/contacts/img/person.png delete mode 100644 apps/contacts/img/person.svg delete mode 100644 apps/contacts/img/person_large.png delete mode 100644 apps/contacts/import.php delete mode 100644 apps/contacts/index.php delete mode 100644 apps/contacts/js/contacts.js delete mode 100644 apps/contacts/js/expanding.js delete mode 100644 apps/contacts/js/jquery.Jcrop.js delete mode 100644 apps/contacts/js/jquery.Jcrop.min.js delete mode 100644 apps/contacts/js/jquery.combobox.js delete mode 100644 apps/contacts/js/jquery.multi-autocomplete.js delete mode 100644 apps/contacts/js/loader.js delete mode 100644 apps/contacts/l10n/ar.php delete mode 100644 apps/contacts/l10n/ca.php delete mode 100644 apps/contacts/l10n/cs_CZ.php delete mode 100644 apps/contacts/l10n/da.php delete mode 100644 apps/contacts/l10n/de.php delete mode 100644 apps/contacts/l10n/el.php delete mode 100644 apps/contacts/l10n/eo.php delete mode 100644 apps/contacts/l10n/es.php delete mode 100644 apps/contacts/l10n/et_EE.php delete mode 100644 apps/contacts/l10n/eu.php delete mode 100644 apps/contacts/l10n/fa.php delete mode 100644 apps/contacts/l10n/fi_FI.php delete mode 100644 apps/contacts/l10n/fr.php delete mode 100644 apps/contacts/l10n/gl.php delete mode 100644 apps/contacts/l10n/he.php delete mode 100644 apps/contacts/l10n/hr.php delete mode 100644 apps/contacts/l10n/hu_HU.php delete mode 100644 apps/contacts/l10n/ia.php delete mode 100644 apps/contacts/l10n/it.php delete mode 100644 apps/contacts/l10n/ja_JP.php delete mode 100644 apps/contacts/l10n/ko.php delete mode 100644 apps/contacts/l10n/lb.php delete mode 100644 apps/contacts/l10n/lt_LT.php delete mode 100644 apps/contacts/l10n/mk.php delete mode 100644 apps/contacts/l10n/ms_MY.php delete mode 100644 apps/contacts/l10n/nb_NO.php delete mode 100644 apps/contacts/l10n/nl.php delete mode 100644 apps/contacts/l10n/nn_NO.php delete mode 100644 apps/contacts/l10n/pl.php delete mode 100644 apps/contacts/l10n/pt_BR.php delete mode 100644 apps/contacts/l10n/pt_PT.php delete mode 100644 apps/contacts/l10n/ro.php delete mode 100644 apps/contacts/l10n/ru.php delete mode 100644 apps/contacts/l10n/sk_SK.php delete mode 100644 apps/contacts/l10n/sl.php delete mode 100644 apps/contacts/l10n/sr.php delete mode 100644 apps/contacts/l10n/sr@latin.php delete mode 100644 apps/contacts/l10n/sv.php delete mode 100644 apps/contacts/l10n/th_TH.php delete mode 100644 apps/contacts/l10n/tr.php delete mode 100644 apps/contacts/l10n/uk.php delete mode 100644 apps/contacts/l10n/xgettextfiles delete mode 100644 apps/contacts/l10n/zh_CN.php delete mode 100644 apps/contacts/l10n/zh_TW.php delete mode 100644 apps/contacts/lib/VCFExportPlugin.php delete mode 100644 apps/contacts/lib/addressbook.php delete mode 100644 apps/contacts/lib/app.php delete mode 100644 apps/contacts/lib/connector_sabre.php delete mode 100644 apps/contacts/lib/hooks.php delete mode 100644 apps/contacts/lib/search.php delete mode 100644 apps/contacts/lib/vcard.php delete mode 100644 apps/contacts/photo.php delete mode 100644 apps/contacts/settings.php delete mode 100644 apps/contacts/templates/index.php delete mode 100644 apps/contacts/templates/part.chooseaddressbook.php delete mode 100644 apps/contacts/templates/part.chooseaddressbook.rowfields.php delete mode 100644 apps/contacts/templates/part.contact.php delete mode 100644 apps/contacts/templates/part.cropphoto.php delete mode 100644 apps/contacts/templates/part.edit_address_dialog.php delete mode 100644 apps/contacts/templates/part.edit_categories_dialog.php delete mode 100644 apps/contacts/templates/part.edit_name_dialog.php delete mode 100644 apps/contacts/templates/part.editaddressbook.php delete mode 100644 apps/contacts/templates/part.import.php delete mode 100644 apps/contacts/templates/part.importaddressbook.php delete mode 100644 apps/contacts/templates/part.no_contacts.php delete mode 100644 apps/contacts/templates/settings.php delete mode 100644 apps/contacts/thumbnail.php delete mode 100644 apps/contacts/tmpphoto.php delete mode 100644 apps/external/ajax/setsites.php delete mode 100644 apps/external/appinfo/app.php delete mode 100644 apps/external/appinfo/info.xml delete mode 100644 apps/external/appinfo/version delete mode 100644 apps/external/css/style.css delete mode 100644 apps/external/img/external.png delete mode 100644 apps/external/img/external.svg delete mode 100644 apps/external/index.php delete mode 100644 apps/external/js/admin.js delete mode 100644 apps/external/lib/external.php delete mode 100644 apps/external/settings.php delete mode 100644 apps/external/templates/frame.php delete mode 100644 apps/external/templates/settings.php create mode 100644 apps/files/appinfo/filesync.php create mode 100644 apps/files/l10n/es_AR.php create mode 100644 apps/files/l10n/lv.php create mode 100644 apps/files/l10n/oc.php create mode 100644 apps/files/l10n/ru_RU.php create mode 100644 apps/files/l10n/si_LK.php create mode 100644 apps/files/l10n/vi.php create mode 100644 apps/files/l10n/zh_CN.GB2312.php delete mode 100644 apps/files_archive/appinfo/app.php delete mode 100644 apps/files_archive/appinfo/info.xml delete mode 100644 apps/files_archive/appinfo/version delete mode 100644 apps/files_archive/js/archive.js delete mode 100644 apps/files_archive/lib/storage.php delete mode 100644 apps/files_archive/tests/data/lorem.txt delete mode 100644 apps/files_archive/tests/storage.php rename apps/{contacts => files_encryption}/l10n/.gitkeep (100%) create mode 100644 apps/files_encryption/l10n/ca.php create mode 100644 apps/files_encryption/l10n/cs_CZ.php create mode 100644 apps/files_encryption/l10n/da.php create mode 100644 apps/files_encryption/l10n/de.php create mode 100644 apps/files_encryption/l10n/el.php create mode 100644 apps/files_encryption/l10n/eo.php create mode 100644 apps/files_encryption/l10n/es.php create mode 100644 apps/files_encryption/l10n/es_AR.php create mode 100644 apps/files_encryption/l10n/et_EE.php create mode 100644 apps/files_encryption/l10n/eu.php create mode 100644 apps/files_encryption/l10n/fa.php create mode 100644 apps/files_encryption/l10n/fi_FI.php create mode 100644 apps/files_encryption/l10n/fr.php create mode 100644 apps/files_encryption/l10n/gl.php create mode 100644 apps/files_encryption/l10n/hu_HU.php create mode 100644 apps/files_encryption/l10n/it.php create mode 100644 apps/files_encryption/l10n/ja_JP.php create mode 100644 apps/files_encryption/l10n/ku_IQ.php create mode 100644 apps/files_encryption/l10n/lt_LT.php create mode 100644 apps/files_encryption/l10n/nb_NO.php create mode 100644 apps/files_encryption/l10n/nl.php create mode 100644 apps/files_encryption/l10n/pl.php create mode 100644 apps/files_encryption/l10n/pt_BR.php create mode 100644 apps/files_encryption/l10n/pt_PT.php create mode 100644 apps/files_encryption/l10n/ro.php create mode 100644 apps/files_encryption/l10n/ru.php create mode 100644 apps/files_encryption/l10n/ru_RU.php create mode 100644 apps/files_encryption/l10n/sk_SK.php create mode 100644 apps/files_encryption/l10n/sl.php create mode 100644 apps/files_encryption/l10n/sv.php create mode 100644 apps/files_encryption/l10n/th_TH.php create mode 100644 apps/files_encryption/l10n/vi.php create mode 100644 apps/files_encryption/l10n/zh_CN.GB2312.php create mode 100644 apps/files_encryption/l10n/zh_CN.php create mode 100644 apps/files_encryption/l10n/zh_TW.php create mode 100644 apps/files_encryption/tests/out.txt rename apps/{files_texteditor/js/aceeditor/mode-text-uncompressed.js => files_external/l10n/.gitkeep} (100%) create mode 100644 apps/files_external/l10n/ca.php create mode 100644 apps/files_external/l10n/cs_CZ.php create mode 100644 apps/files_external/l10n/da.php create mode 100644 apps/files_external/l10n/de.php create mode 100644 apps/files_external/l10n/el.php create mode 100644 apps/files_external/l10n/eo.php create mode 100644 apps/files_external/l10n/es.php create mode 100644 apps/files_external/l10n/es_AR.php create mode 100644 apps/files_external/l10n/et_EE.php create mode 100644 apps/files_external/l10n/eu.php create mode 100644 apps/files_external/l10n/fi_FI.php create mode 100644 apps/files_external/l10n/fr.php create mode 100644 apps/files_external/l10n/gl.php create mode 100644 apps/files_external/l10n/he.php create mode 100644 apps/files_external/l10n/it.php create mode 100644 apps/files_external/l10n/ja_JP.php create mode 100644 apps/files_external/l10n/lt_LT.php create mode 100644 apps/files_external/l10n/nb_NO.php create mode 100644 apps/files_external/l10n/nl.php create mode 100644 apps/files_external/l10n/pl.php create mode 100644 apps/files_external/l10n/pt_BR.php create mode 100644 apps/files_external/l10n/pt_PT.php create mode 100644 apps/files_external/l10n/ro.php create mode 100644 apps/files_external/l10n/ru.php create mode 100644 apps/files_external/l10n/ru_RU.php create mode 100644 apps/files_external/l10n/sk_SK.php create mode 100644 apps/files_external/l10n/sl.php create mode 100644 apps/files_external/l10n/sv.php create mode 100644 apps/files_external/l10n/th_TH.php create mode 100644 apps/files_external/l10n/uk.php create mode 100644 apps/files_external/l10n/vi.php create mode 100644 apps/files_external/l10n/zh_CN.GB2312.php create mode 100644 apps/files_external/tests/dropbox.php delete mode 100644 apps/files_imageviewer/appinfo/app.php delete mode 100644 apps/files_imageviewer/appinfo/info.xml delete mode 100644 apps/files_imageviewer/appinfo/version delete mode 100644 apps/files_imageviewer/css/jquery.fancybox-1.3.4.css delete mode 100644 apps/files_imageviewer/img/blank.gif delete mode 100644 apps/files_imageviewer/img/fancy_close.png delete mode 100644 apps/files_imageviewer/img/fancy_loading.png delete mode 100644 apps/files_imageviewer/img/fancy_nav_left.png delete mode 100644 apps/files_imageviewer/img/fancy_nav_right.png delete mode 100644 apps/files_imageviewer/img/fancy_shadow_e.png delete mode 100644 apps/files_imageviewer/img/fancy_shadow_n.png delete mode 100644 apps/files_imageviewer/img/fancy_shadow_ne.png delete mode 100644 apps/files_imageviewer/img/fancy_shadow_nw.png delete mode 100644 apps/files_imageviewer/img/fancy_shadow_s.png delete mode 100644 apps/files_imageviewer/img/fancy_shadow_se.png delete mode 100644 apps/files_imageviewer/img/fancy_shadow_sw.png delete mode 100644 apps/files_imageviewer/img/fancy_shadow_w.png delete mode 100644 apps/files_imageviewer/img/fancy_title_left.png delete mode 100644 apps/files_imageviewer/img/fancy_title_main.png delete mode 100644 apps/files_imageviewer/img/fancy_title_over.png delete mode 100644 apps/files_imageviewer/img/fancy_title_right.png delete mode 100644 apps/files_imageviewer/img/fancybox-x.png delete mode 100644 apps/files_imageviewer/img/fancybox-y.png delete mode 100644 apps/files_imageviewer/img/fancybox.png delete mode 100644 apps/files_imageviewer/js/jquery.fancybox-1.3.4.js delete mode 100644 apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js delete mode 100644 apps/files_imageviewer/js/jquery.mousewheel-3.0.4.js delete mode 100644 apps/files_imageviewer/js/jquery.mousewheel-3.0.4.pack.js delete mode 100644 apps/files_imageviewer/js/lightbox.js delete mode 100644 apps/files_pdfviewer/appinfo/app.php delete mode 100644 apps/files_pdfviewer/appinfo/info.xml delete mode 100644 apps/files_pdfviewer/appinfo/version delete mode 100644 apps/files_pdfviewer/css/history.png delete mode 100644 apps/files_pdfviewer/css/viewer.css delete mode 100644 apps/files_pdfviewer/js/pdfjs/LICENSE delete mode 100644 apps/files_pdfviewer/js/pdfjs/README delete mode 100644 apps/files_pdfviewer/js/pdfjs/build/pdf.js delete mode 100644 apps/files_pdfviewer/js/pdfjs/compatibility.js delete mode 100755 apps/files_pdfviewer/js/pdfjs/update.sh delete mode 100644 apps/files_pdfviewer/js/pdfjs/viewer.js delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/bookmark.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/check.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/comment.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/document-print.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/download.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/go-down.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/go-up.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/nav-outline.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/nav-thumbs.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/pin-down.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/pin-up.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/zoom-in.svg delete mode 100644 apps/files_pdfviewer/js/pdfjs/web/images/zoom-out.svg delete mode 100644 apps/files_pdfviewer/js/pdfview.js delete mode 100644 apps/files_pdfviewer/js/viewer.js delete mode 100644 apps/files_sharing/ajax/email.php delete mode 100644 apps/files_sharing/ajax/getitem.php delete mode 100644 apps/files_sharing/ajax/getstatuses.php delete mode 100644 apps/files_sharing/ajax/setpermissions.php delete mode 100644 apps/files_sharing/ajax/share.php delete mode 100644 apps/files_sharing/ajax/toggleresharing.php delete mode 100644 apps/files_sharing/ajax/unshare.php delete mode 100644 apps/files_sharing/ajax/userautocomplete.php delete mode 100644 apps/files_sharing/appinfo/database.xml create mode 100644 apps/files_sharing/appinfo/update.php create mode 100644 apps/files_sharing/css/public.css delete mode 100644 apps/files_sharing/css/sharing.css delete mode 100644 apps/files_sharing/get.php delete mode 100644 apps/files_sharing/js/list.js create mode 100644 apps/files_sharing/js/public.js delete mode 100644 apps/files_sharing/js/settings.js rename apps/{files_texteditor/js/aceeditor/mode-text.js => files_sharing/l10n/.gitkeep} (100%) create mode 100644 apps/files_sharing/l10n/ca.php create mode 100644 apps/files_sharing/l10n/cs_CZ.php create mode 100644 apps/files_sharing/l10n/da.php create mode 100644 apps/files_sharing/l10n/de.php create mode 100644 apps/files_sharing/l10n/el.php create mode 100644 apps/files_sharing/l10n/eo.php create mode 100644 apps/files_sharing/l10n/es.php create mode 100644 apps/files_sharing/l10n/es_AR.php create mode 100644 apps/files_sharing/l10n/et_EE.php create mode 100644 apps/files_sharing/l10n/eu.php create mode 100644 apps/files_sharing/l10n/fa.php create mode 100644 apps/files_sharing/l10n/fi_FI.php create mode 100644 apps/files_sharing/l10n/fr.php create mode 100644 apps/files_sharing/l10n/gl.php create mode 100644 apps/files_sharing/l10n/he.php create mode 100644 apps/files_sharing/l10n/hu_HU.php create mode 100644 apps/files_sharing/l10n/it.php create mode 100644 apps/files_sharing/l10n/ja_JP.php create mode 100644 apps/files_sharing/l10n/ku_IQ.php create mode 100644 apps/files_sharing/l10n/lt_LT.php create mode 100644 apps/files_sharing/l10n/nb_NO.php create mode 100644 apps/files_sharing/l10n/nl.php create mode 100644 apps/files_sharing/l10n/pl.php create mode 100644 apps/files_sharing/l10n/pt_BR.php create mode 100644 apps/files_sharing/l10n/pt_PT.php create mode 100644 apps/files_sharing/l10n/ro.php create mode 100644 apps/files_sharing/l10n/ru.php create mode 100644 apps/files_sharing/l10n/ru_RU.php create mode 100644 apps/files_sharing/l10n/sk_SK.php create mode 100644 apps/files_sharing/l10n/sl.php create mode 100644 apps/files_sharing/l10n/sv.php create mode 100644 apps/files_sharing/l10n/th_TH.php create mode 100644 apps/files_sharing/l10n/uk.php create mode 100644 apps/files_sharing/l10n/vi.php create mode 100644 apps/files_sharing/l10n/zh_CN.GB2312.php create mode 100644 apps/files_sharing/l10n/zh_CN.php create mode 100644 apps/files_sharing/l10n/zh_TW.php create mode 100644 apps/files_sharing/lib/share/file.php create mode 100644 apps/files_sharing/lib/share/folder.php create mode 100644 apps/files_sharing/lib/sharedstorage.php delete mode 100644 apps/files_sharing/lib_share.php delete mode 100644 apps/files_sharing/list.php create mode 100644 apps/files_sharing/public.php delete mode 100644 apps/files_sharing/settings.php delete mode 100644 apps/files_sharing/sharedstorage.php create mode 100644 apps/files_sharing/templates/authenticate.php delete mode 100644 apps/files_sharing/templates/list.php create mode 100644 apps/files_sharing/templates/public.php delete mode 100644 apps/files_sharing/templates/settings.php delete mode 100644 apps/files_sharing_log/appinfo/app.php delete mode 100644 apps/files_sharing_log/appinfo/database.xml delete mode 100644 apps/files_sharing_log/appinfo/info.xml delete mode 100644 apps/files_sharing_log/appinfo/version delete mode 100644 apps/files_sharing_log/css/style.css delete mode 100644 apps/files_sharing_log/index.php delete mode 100644 apps/files_sharing_log/log.php delete mode 100644 apps/files_sharing_log/templates/index.php delete mode 100644 apps/files_texteditor/ajax/loadfile.php delete mode 100644 apps/files_texteditor/ajax/mtime.php delete mode 100644 apps/files_texteditor/ajax/savefile.php delete mode 100644 apps/files_texteditor/appinfo/app.php delete mode 100644 apps/files_texteditor/appinfo/info.xml delete mode 100644 apps/files_texteditor/appinfo/version delete mode 100644 apps/files_texteditor/css/DroidSansMono/DroidSansMono-webfont.eot delete mode 100644 apps/files_texteditor/css/DroidSansMono/DroidSansMono-webfont.svg delete mode 100644 apps/files_texteditor/css/DroidSansMono/DroidSansMono-webfont.ttf delete mode 100644 apps/files_texteditor/css/DroidSansMono/DroidSansMono-webfont.woff delete mode 100644 apps/files_texteditor/css/DroidSansMono/Google Android License.txt delete mode 100644 apps/files_texteditor/css/DroidSansMono/demo.html delete mode 100644 apps/files_texteditor/css/DroidSansMono/stylesheet.css delete mode 100644 apps/files_texteditor/css/style.css delete mode 100644 apps/files_texteditor/js/aceeditor/LICENSE delete mode 100644 apps/files_texteditor/js/aceeditor/ace-compat-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/ace-compat.js delete mode 100644 apps/files_texteditor/js/aceeditor/ace-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/ace.js delete mode 100644 apps/files_texteditor/js/aceeditor/keybinding-emacs-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/keybinding-emacs.js delete mode 100644 apps/files_texteditor/js/aceeditor/keybinding-vim-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/keybinding-vim.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-c_cpp-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-c_cpp.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-clojure-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-clojure.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-coffee-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-coffee.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-coldfusion-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-coldfusion.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-csharp-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-csharp.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-css-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-css.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-groovy-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-groovy.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-haxe-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-haxe.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-html-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-html.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-java-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-java.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-javascript-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-javascript.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-json-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-json.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-latex-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-latex.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-less-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-less.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-liquid-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-liquid.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-lua-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-lua.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-markdown-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-markdown.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-ocaml-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-ocaml.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-perl-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-perl.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-pgsql-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-pgsql.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-php-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-php.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-powershell-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-powershell.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-python-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-python.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-ruby-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-ruby.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-scad-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-scad.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-scala-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-scala.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-scss-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-scss.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-sh-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-sh.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-sql-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-sql.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-svg-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-svg.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-textile-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-textile.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-xml-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-xml.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-xquery-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/mode-xquery.js delete mode 100644 apps/files_texteditor/js/aceeditor/theme-clouds-uncompressed.js delete mode 100644 apps/files_texteditor/js/aceeditor/theme-clouds.js delete mode 100644 apps/files_texteditor/js/aceeditor/worker-coffee.js delete mode 100644 apps/files_texteditor/js/aceeditor/worker-css.js delete mode 100644 apps/files_texteditor/js/aceeditor/worker-javascript.js delete mode 100644 apps/files_texteditor/js/aceeditor/worker-json.js delete mode 100644 apps/files_texteditor/js/editor.js create mode 100644 apps/files_versions/appinfo/api.php create mode 100644 apps/files_versions/appinfo/update.php create mode 100644 apps/files_versions/l10n/.gitkeep create mode 100644 apps/files_versions/l10n/ca.php create mode 100644 apps/files_versions/l10n/cs_CZ.php create mode 100644 apps/files_versions/l10n/da.php create mode 100644 apps/files_versions/l10n/de.php create mode 100644 apps/files_versions/l10n/el.php create mode 100644 apps/files_versions/l10n/eo.php create mode 100644 apps/files_versions/l10n/es.php create mode 100644 apps/files_versions/l10n/es_AR.php create mode 100644 apps/files_versions/l10n/et_EE.php create mode 100644 apps/files_versions/l10n/eu.php create mode 100644 apps/files_versions/l10n/fa.php create mode 100644 apps/files_versions/l10n/fi_FI.php create mode 100644 apps/files_versions/l10n/fr.php create mode 100644 apps/files_versions/l10n/gl.php create mode 100644 apps/files_versions/l10n/he.php create mode 100644 apps/files_versions/l10n/it.php create mode 100644 apps/files_versions/l10n/ja_JP.php create mode 100644 apps/files_versions/l10n/ku_IQ.php create mode 100644 apps/files_versions/l10n/lt_LT.php create mode 100644 apps/files_versions/l10n/nb_NO.php create mode 100644 apps/files_versions/l10n/nl.php create mode 100644 apps/files_versions/l10n/pl.php create mode 100644 apps/files_versions/l10n/pt_BR.php create mode 100644 apps/files_versions/l10n/pt_PT.php create mode 100644 apps/files_versions/l10n/ro.php create mode 100644 apps/files_versions/l10n/ru.php create mode 100644 apps/files_versions/l10n/ru_RU.php create mode 100644 apps/files_versions/l10n/sk_SK.php create mode 100644 apps/files_versions/l10n/sl.php create mode 100644 apps/files_versions/l10n/sv.php create mode 100644 apps/files_versions/l10n/th_TH.php create mode 100644 apps/files_versions/l10n/vi.php create mode 100644 apps/files_versions/l10n/zh_CN.GB2312.php create mode 100644 apps/files_versions/l10n/zh_CN.php delete mode 100644 apps/gallery/ajax/createAlbum.php delete mode 100644 apps/gallery/ajax/galleryOp.php delete mode 100644 apps/gallery/ajax/sharing.php delete mode 100644 apps/gallery/ajax/thumbnail.php delete mode 100644 apps/gallery/appinfo/app.php delete mode 100644 apps/gallery/appinfo/database.xml delete mode 100644 apps/gallery/appinfo/info.xml delete mode 100644 apps/gallery/appinfo/update.php delete mode 100644 apps/gallery/appinfo/version delete mode 100644 apps/gallery/css/sharing.css delete mode 100644 apps/gallery/css/styles.css delete mode 100644 apps/gallery/css/supersized.css delete mode 100644 apps/gallery/css/supersized.shutter.css delete mode 100644 apps/gallery/img/breadcrumb.png delete mode 100644 apps/gallery/img/delete.png delete mode 100644 apps/gallery/img/loading.gif delete mode 100644 apps/gallery/img/rename.png delete mode 100644 apps/gallery/img/share.png delete mode 100644 apps/gallery/img/supersized/back.png delete mode 100644 apps/gallery/img/supersized/bg-black.png delete mode 100644 apps/gallery/img/supersized/bg-hover.png delete mode 100644 apps/gallery/img/supersized/button-tray-down.png delete mode 100644 apps/gallery/img/supersized/button-tray-up.png delete mode 100644 apps/gallery/img/supersized/forward.png delete mode 100644 apps/gallery/img/supersized/nav-bg.png delete mode 100644 apps/gallery/img/supersized/nav-dot.png delete mode 100644 apps/gallery/img/supersized/pause.png delete mode 100644 apps/gallery/img/supersized/play.png delete mode 100644 apps/gallery/img/supersized/progress-back.png delete mode 100644 apps/gallery/img/supersized/progress-bar.png delete mode 100644 apps/gallery/img/supersized/progress.gif delete mode 100644 apps/gallery/img/supersized/supersized-logo.png delete mode 100644 apps/gallery/img/supersized/thumb-back.png delete mode 100644 apps/gallery/img/supersized/thumb-forward.png delete mode 100644 apps/gallery/index.php delete mode 100644 apps/gallery/js/albums.js delete mode 100644 apps/gallery/js/jquery.easing.min.js delete mode 100644 apps/gallery/js/pictures.js delete mode 100644 apps/gallery/js/scanner.js delete mode 100644 apps/gallery/js/sharing.js delete mode 100644 apps/gallery/js/slideshow.js delete mode 100644 apps/gallery/js/supersized.3.2.7.js delete mode 100644 apps/gallery/js/supersized.3.2.7.min.js delete mode 100644 apps/gallery/js/supersized.shutter.js delete mode 100644 apps/gallery/js/supersized.shutter.min.js delete mode 100644 apps/gallery/l10n/ar.php delete mode 100644 apps/gallery/l10n/ca.php delete mode 100644 apps/gallery/l10n/cs_CZ.php delete mode 100644 apps/gallery/l10n/da.php delete mode 100644 apps/gallery/l10n/de.php delete mode 100644 apps/gallery/l10n/el.php delete mode 100644 apps/gallery/l10n/eo.php delete mode 100644 apps/gallery/l10n/es.php delete mode 100644 apps/gallery/l10n/et_EE.php delete mode 100644 apps/gallery/l10n/eu.php delete mode 100644 apps/gallery/l10n/fa.php delete mode 100644 apps/gallery/l10n/fi_FI.php delete mode 100644 apps/gallery/l10n/fr.php delete mode 100644 apps/gallery/l10n/gl.php delete mode 100644 apps/gallery/l10n/hr.php delete mode 100644 apps/gallery/l10n/hu_HU.php delete mode 100644 apps/gallery/l10n/ia.php delete mode 100644 apps/gallery/l10n/id.php delete mode 100644 apps/gallery/l10n/it.php delete mode 100644 apps/gallery/l10n/ja_JP.php delete mode 100644 apps/gallery/l10n/ko.php delete mode 100644 apps/gallery/l10n/lb.php delete mode 100644 apps/gallery/l10n/lt_LT.php delete mode 100644 apps/gallery/l10n/mk.php delete mode 100644 apps/gallery/l10n/ms_MY.php delete mode 100644 apps/gallery/l10n/nb_NO.php delete mode 100644 apps/gallery/l10n/nl.php delete mode 100644 apps/gallery/l10n/nn_NO.php delete mode 100644 apps/gallery/l10n/pl.php delete mode 100644 apps/gallery/l10n/pt_BR.php delete mode 100644 apps/gallery/l10n/pt_PT.php delete mode 100644 apps/gallery/l10n/ro.php delete mode 100644 apps/gallery/l10n/ru.php delete mode 100644 apps/gallery/l10n/sk_SK.php delete mode 100644 apps/gallery/l10n/sl.php delete mode 100644 apps/gallery/l10n/sr.php delete mode 100644 apps/gallery/l10n/sv.php delete mode 100644 apps/gallery/l10n/th_TH.php delete mode 100644 apps/gallery/l10n/tr.php delete mode 100644 apps/gallery/l10n/uk.php delete mode 100644 apps/gallery/l10n/zh_CN.php delete mode 100644 apps/gallery/l10n/zh_TW.php delete mode 100644 apps/gallery/lib/album.php delete mode 100644 apps/gallery/lib/hooks_handlers.php delete mode 100644 apps/gallery/lib/images_utils.php delete mode 100644 apps/gallery/lib/managers.php delete mode 100644 apps/gallery/lib/photo.php delete mode 100644 apps/gallery/lib/scanner.php delete mode 100644 apps/gallery/lib/sharing.php delete mode 100644 apps/gallery/lib/tiles.php delete mode 100644 apps/gallery/lib/tiles_test.php delete mode 100644 apps/gallery/sharing.php delete mode 100644 apps/gallery/templates/index.php delete mode 100644 apps/gallery/templates/view_album.php delete mode 100644 apps/media/ajax/api.php delete mode 100644 apps/media/ajax/autoupdate.php delete mode 100644 apps/media/appinfo/app.php delete mode 100644 apps/media/appinfo/database.xml delete mode 100644 apps/media/appinfo/info.xml delete mode 100644 apps/media/appinfo/version delete mode 100644 apps/media/css/music.css delete mode 100644 apps/media/css/player.css delete mode 100644 apps/media/index.php delete mode 100644 apps/media/js/Jplayer.swf delete mode 100644 apps/media/js/collection.js delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/Jplayer.as delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/Jplayer.fla delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/add-on/jplayer.playlist.js delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/add-on/jquery.jplayer.inspector.js delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/happyworm/jPlayer/JplayerEvent.as delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/happyworm/jPlayer/JplayerMp3.as delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/happyworm/jPlayer/JplayerMp4.as delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/happyworm/jPlayer/JplayerStatus.as delete mode 100644 apps/media/js/jQuery.jPlayer.2.1.0.source/jquery.jplayer.js delete mode 100644 apps/media/js/jquery.jplayer.min.js delete mode 100644 apps/media/js/loader.js delete mode 100644 apps/media/js/music.js delete mode 100644 apps/media/js/player.js delete mode 100644 apps/media/js/playlist.js delete mode 100644 apps/media/js/scanner.js delete mode 100644 apps/media/l10n/ar.php delete mode 100644 apps/media/l10n/bg_BG.php delete mode 100644 apps/media/l10n/ca.php delete mode 100644 apps/media/l10n/cs_CZ.php delete mode 100644 apps/media/l10n/da.php delete mode 100644 apps/media/l10n/de.php delete mode 100644 apps/media/l10n/el.php delete mode 100644 apps/media/l10n/eo.php delete mode 100644 apps/media/l10n/es.php delete mode 100644 apps/media/l10n/et_EE.php delete mode 100644 apps/media/l10n/eu.php delete mode 100644 apps/media/l10n/fa.php delete mode 100644 apps/media/l10n/fi_FI.php delete mode 100644 apps/media/l10n/fr.php delete mode 100644 apps/media/l10n/gl.php delete mode 100644 apps/media/l10n/he.php delete mode 100644 apps/media/l10n/hr.php delete mode 100644 apps/media/l10n/hu_HU.php delete mode 100644 apps/media/l10n/ia.php delete mode 100644 apps/media/l10n/id.php delete mode 100644 apps/media/l10n/it.php delete mode 100644 apps/media/l10n/ja_JP.php delete mode 100644 apps/media/l10n/ko.php delete mode 100644 apps/media/l10n/lb.php delete mode 100644 apps/media/l10n/lt_LT.php delete mode 100644 apps/media/l10n/mk.php delete mode 100644 apps/media/l10n/ms_MY.php delete mode 100644 apps/media/l10n/nb_NO.php delete mode 100644 apps/media/l10n/nl.php delete mode 100644 apps/media/l10n/nn_NO.php delete mode 100644 apps/media/l10n/pl.php delete mode 100644 apps/media/l10n/pt_BR.php delete mode 100644 apps/media/l10n/pt_PT.php delete mode 100644 apps/media/l10n/ro.php delete mode 100644 apps/media/l10n/ru.php delete mode 100644 apps/media/l10n/sk_SK.php delete mode 100644 apps/media/l10n/sl.php delete mode 100644 apps/media/l10n/sr.php delete mode 100644 apps/media/l10n/sr@latin.php delete mode 100644 apps/media/l10n/sv.php delete mode 100644 apps/media/l10n/th_TH.php delete mode 100644 apps/media/l10n/tr.php delete mode 100644 apps/media/l10n/xgettextfiles delete mode 100644 apps/media/l10n/zh_CN.php delete mode 100644 apps/media/l10n/zh_TW.php delete mode 100644 apps/media/lib_ampache.php delete mode 100644 apps/media/lib_collection.php delete mode 100644 apps/media/lib_media.php delete mode 100644 apps/media/lib_scanner.php delete mode 100644 apps/media/remote.php delete mode 100644 apps/media/server/xml.server.php delete mode 100644 apps/media/settings.php delete mode 100644 apps/media/templates/music.php delete mode 100644 apps/media/templates/player.php delete mode 100644 apps/media/templates/settings.php delete mode 100644 apps/remoteStorage/BearerAuth.php delete mode 100644 apps/remoteStorage/WebDAV.php delete mode 100644 apps/remoteStorage/ajax/revokeToken.php delete mode 100644 apps/remoteStorage/appinfo/app.php delete mode 100644 apps/remoteStorage/appinfo/database.xml delete mode 100644 apps/remoteStorage/appinfo/info.xml delete mode 100644 apps/remoteStorage/appinfo/version delete mode 100644 apps/remoteStorage/appinfo/webfinger.php delete mode 100644 apps/remoteStorage/auth.php delete mode 100644 apps/remoteStorage/lib_remoteStorage.php delete mode 100644 apps/remoteStorage/oauth_ro_auth.php delete mode 100644 apps/remoteStorage/remoteStorage.png delete mode 100644 apps/remoteStorage/settings.php delete mode 100644 apps/remoteStorage/templates/settings.php delete mode 100644 apps/tasks/ajax/addtask.php delete mode 100644 apps/tasks/ajax/addtaskform.php delete mode 100644 apps/tasks/ajax/delete.php delete mode 100644 apps/tasks/ajax/edittask.php delete mode 100644 apps/tasks/ajax/edittaskform.php delete mode 100644 apps/tasks/ajax/getdetails.php delete mode 100644 apps/tasks/ajax/gettasks.php delete mode 100644 apps/tasks/ajax/update_property.php delete mode 100644 apps/tasks/appinfo/app.php delete mode 100644 apps/tasks/appinfo/info.xml delete mode 100644 apps/tasks/css/style.css delete mode 100644 apps/tasks/img/icon.png delete mode 100644 apps/tasks/img/icon.svg delete mode 100644 apps/tasks/index.php delete mode 100644 apps/tasks/js/tasks.js delete mode 100644 apps/tasks/lib/app.php delete mode 100644 apps/tasks/lib/vtodo.php delete mode 100644 apps/tasks/templates/part.addtaskform.php delete mode 100644 apps/tasks/templates/part.details.php delete mode 100644 apps/tasks/templates/part.edittaskform.php delete mode 100644 apps/tasks/templates/part.property.php delete mode 100644 apps/tasks/templates/part.taskform.php delete mode 100644 apps/tasks/templates/part.tasks.php delete mode 100644 apps/tasks/templates/tasks.php create mode 100644 apps/user_ldap/ajax/testConfiguration.php create mode 100644 apps/user_ldap/css/settings.css create mode 100644 apps/user_ldap/l10n/.gitkeep create mode 100644 apps/user_ldap/l10n/ca.php create mode 100644 apps/user_ldap/l10n/cs_CZ.php create mode 100644 apps/user_ldap/l10n/da.php create mode 100644 apps/user_ldap/l10n/de.php create mode 100644 apps/user_ldap/l10n/el.php create mode 100644 apps/user_ldap/l10n/eo.php create mode 100644 apps/user_ldap/l10n/es.php create mode 100644 apps/user_ldap/l10n/es_AR.php create mode 100644 apps/user_ldap/l10n/et_EE.php create mode 100644 apps/user_ldap/l10n/eu.php create mode 100644 apps/user_ldap/l10n/fa.php create mode 100644 apps/user_ldap/l10n/fi_FI.php create mode 100644 apps/user_ldap/l10n/fr.php create mode 100644 apps/user_ldap/l10n/it.php create mode 100644 apps/user_ldap/l10n/ja_JP.php create mode 100644 apps/user_ldap/l10n/lt_LT.php create mode 100644 apps/user_ldap/l10n/pl.php create mode 100644 apps/user_ldap/l10n/pt_BR.php create mode 100644 apps/user_ldap/l10n/pt_PT.php create mode 100644 apps/user_ldap/l10n/ro.php create mode 100644 apps/user_ldap/l10n/ru.php create mode 100644 apps/user_ldap/l10n/ru_RU.php create mode 100644 apps/user_ldap/l10n/sl.php create mode 100644 apps/user_ldap/l10n/sv.php create mode 100644 apps/user_ldap/l10n/th_TH.php create mode 100644 apps/user_ldap/l10n/uk.php create mode 100644 apps/user_ldap/l10n/vi.php create mode 100644 apps/user_ldap/l10n/zh_CN.GB2312.php create mode 100644 apps/user_ldap/l10n/zh_CN.php create mode 100644 apps/user_ldap/lib/access.php create mode 100644 apps/user_ldap/lib/connection.php create mode 100644 apps/user_ldap/lib/jobs.php delete mode 100644 apps/user_ldap/lib_ldap.php delete mode 100644 apps/user_migrate/ajax/export.php delete mode 100644 apps/user_migrate/appinfo/app.php delete mode 100644 apps/user_migrate/appinfo/info.xml delete mode 100644 apps/user_migrate/appinfo/version delete mode 100644 apps/user_migrate/js/export.js delete mode 100644 apps/user_migrate/settings.php delete mode 100644 apps/user_migrate/templates/settings.php delete mode 100644 apps/user_openid/appinfo/app.php delete mode 100644 apps/user_openid/appinfo/info.xml delete mode 100644 apps/user_openid/appinfo/version delete mode 100644 apps/user_openid/js/settings.js delete mode 100644 apps/user_openid/settings.php delete mode 100644 apps/user_openid/templates/nomode.php delete mode 100644 apps/user_openid/templates/settings.php delete mode 100644 apps/user_openid/user.php delete mode 100644 apps/user_openid/user_openid.php create mode 100755 apps/user_webdavauth/appinfo/app.php create mode 100755 apps/user_webdavauth/appinfo/info.xml create mode 100755 apps/user_webdavauth/settings.php create mode 100755 apps/user_webdavauth/templates/settings.php create mode 100755 apps/user_webdavauth/user_webdavauth.php delete mode 100644 apps/user_webfinger/appinfo/app.php delete mode 100644 apps/user_webfinger/appinfo/info.xml delete mode 100644 apps/user_webfinger/appinfo/version delete mode 100644 apps/user_webfinger/host-meta.php delete mode 100644 apps/user_webfinger/webfinger.php create mode 100755 autotest.sh delete mode 100644 core/ajax/grouplist.php create mode 100644 core/ajax/requesttoken.php create mode 100644 core/ajax/share.php delete mode 100644 core/ajax/userlist.php delete mode 100644 core/ajax/validateuser.php create mode 100644 core/css/share.css create mode 100644 core/img/actions/clock.png create mode 100755 core/img/actions/clock.svg create mode 100644 core/img/actions/lock.png create mode 100755 core/img/actions/lock.svg create mode 100644 core/img/rating/s1.png create mode 100644 core/img/rating/s10.png create mode 100644 core/img/rating/s11.png create mode 100644 core/img/rating/s2.png create mode 100644 core/img/rating/s3.png create mode 100644 core/img/rating/s4.png create mode 100644 core/img/rating/s5.png create mode 100644 core/img/rating/s6.png create mode 100644 core/img/rating/s7.png create mode 100644 core/img/rating/s8.png create mode 100644 core/img/rating/s9.png rename {apps/contacts => core}/js/LICENSE.jquery.inview (100%) create mode 100644 core/js/backgroundjobs.js rename {apps/contacts => core}/js/jquery.inview.js (96%) rename {apps/contacts => core}/js/jquery.inview.txt (100%) create mode 100644 core/js/requesttoken.js create mode 100644 core/js/share.js create mode 100644 core/l10n/es_AR.php create mode 100644 core/l10n/hi.php create mode 100644 core/l10n/ignorelist create mode 100644 core/l10n/ku_IQ.php create mode 100644 core/l10n/lv.php create mode 100644 core/l10n/oc.php create mode 100644 core/l10n/ru_RU.php create mode 100644 core/l10n/si_LK.php create mode 100644 core/l10n/vi.php create mode 100644 core/l10n/zh_CN.GB2312.php create mode 100644 core/templates/exception.php create mode 100644 core/templates/layout.base.php create mode 100644 core/templates/verify.php create mode 100644 cron.php create mode 100644 l10n/af/admin_dependencies_chk.po create mode 100644 l10n/af/admin_migrate.po create mode 100644 l10n/af/bookmarks.po create mode 100644 l10n/af/files_encryption.po create mode 100644 l10n/af/files_external.po create mode 100644 l10n/af/files_odfviewer.po create mode 100644 l10n/af/files_pdfviewer.po create mode 100644 l10n/af/files_sharing.po create mode 100644 l10n/af/files_texteditor.po create mode 100644 l10n/af/files_versions.po create mode 100644 l10n/af/impress.po create mode 100644 l10n/af/lib.po create mode 100644 l10n/af/tasks.po create mode 100644 l10n/af/user_ldap.po create mode 100644 l10n/af/user_migrate.po create mode 100644 l10n/af/user_openid.po create mode 100644 l10n/ar/admin_dependencies_chk.po create mode 100644 l10n/ar/admin_migrate.po create mode 100644 l10n/ar/bookmarks.po create mode 100644 l10n/ar/files_encryption.po create mode 100644 l10n/ar/files_external.po create mode 100644 l10n/ar/files_odfviewer.po create mode 100644 l10n/ar/files_pdfviewer.po create mode 100644 l10n/ar/files_sharing.po create mode 100644 l10n/ar/files_texteditor.po create mode 100644 l10n/ar/files_versions.po create mode 100644 l10n/ar/impress.po create mode 100644 l10n/ar/lib.po create mode 100644 l10n/ar/tasks.po create mode 100644 l10n/ar/user_ldap.po create mode 100644 l10n/ar/user_migrate.po create mode 100644 l10n/ar/user_openid.po create mode 100644 l10n/ar_SA/admin_dependencies_chk.po create mode 100644 l10n/ar_SA/admin_migrate.po create mode 100644 l10n/ar_SA/bookmarks.po create mode 100644 l10n/ar_SA/calendar.po create mode 100644 l10n/ar_SA/contacts.po create mode 100644 l10n/ar_SA/core.po create mode 100644 l10n/ar_SA/files.po create mode 100644 l10n/ar_SA/files_encryption.po create mode 100644 l10n/ar_SA/files_external.po create mode 100644 l10n/ar_SA/files_odfviewer.po create mode 100644 l10n/ar_SA/files_pdfviewer.po create mode 100644 l10n/ar_SA/files_sharing.po create mode 100644 l10n/ar_SA/files_texteditor.po create mode 100644 l10n/ar_SA/files_versions.po create mode 100644 l10n/ar_SA/gallery.po create mode 100644 l10n/ar_SA/impress.po create mode 100644 l10n/ar_SA/lib.po create mode 100644 l10n/ar_SA/media.po create mode 100644 l10n/ar_SA/settings.po create mode 100644 l10n/ar_SA/tasks.po create mode 100644 l10n/ar_SA/user_ldap.po create mode 100644 l10n/ar_SA/user_migrate.po create mode 100644 l10n/ar_SA/user_openid.po create mode 100644 l10n/bg_BG/admin_dependencies_chk.po create mode 100644 l10n/bg_BG/admin_migrate.po create mode 100644 l10n/bg_BG/bookmarks.po create mode 100644 l10n/bg_BG/files_encryption.po create mode 100644 l10n/bg_BG/files_external.po create mode 100644 l10n/bg_BG/files_odfviewer.po create mode 100644 l10n/bg_BG/files_pdfviewer.po create mode 100644 l10n/bg_BG/files_sharing.po create mode 100644 l10n/bg_BG/files_texteditor.po create mode 100644 l10n/bg_BG/files_versions.po create mode 100644 l10n/bg_BG/impress.po create mode 100644 l10n/bg_BG/lib.po create mode 100644 l10n/bg_BG/tasks.po create mode 100644 l10n/bg_BG/user_ldap.po create mode 100644 l10n/bg_BG/user_migrate.po create mode 100644 l10n/bg_BG/user_openid.po create mode 100644 l10n/ca/admin_dependencies_chk.po create mode 100644 l10n/ca/admin_migrate.po create mode 100644 l10n/ca/bookmarks.po create mode 100644 l10n/ca/files_encryption.po create mode 100644 l10n/ca/files_external.po create mode 100644 l10n/ca/files_odfviewer.po create mode 100644 l10n/ca/files_pdfviewer.po create mode 100644 l10n/ca/files_sharing.po create mode 100644 l10n/ca/files_texteditor.po create mode 100644 l10n/ca/files_versions.po create mode 100644 l10n/ca/impress.po create mode 100644 l10n/ca/lib.po create mode 100644 l10n/ca/tasks.po create mode 100644 l10n/ca/user_ldap.po create mode 100644 l10n/ca/user_migrate.po create mode 100644 l10n/ca/user_openid.po create mode 100644 l10n/cs_CZ/admin_dependencies_chk.po create mode 100644 l10n/cs_CZ/admin_migrate.po create mode 100644 l10n/cs_CZ/bookmarks.po create mode 100644 l10n/cs_CZ/files_encryption.po create mode 100644 l10n/cs_CZ/files_external.po create mode 100644 l10n/cs_CZ/files_odfviewer.po create mode 100644 l10n/cs_CZ/files_pdfviewer.po create mode 100644 l10n/cs_CZ/files_sharing.po create mode 100644 l10n/cs_CZ/files_texteditor.po create mode 100644 l10n/cs_CZ/files_versions.po create mode 100644 l10n/cs_CZ/impress.po create mode 100644 l10n/cs_CZ/lib.po create mode 100644 l10n/cs_CZ/tasks.po create mode 100644 l10n/cs_CZ/user_ldap.po create mode 100644 l10n/cs_CZ/user_migrate.po create mode 100644 l10n/cs_CZ/user_openid.po create mode 100644 l10n/da/admin_dependencies_chk.po create mode 100644 l10n/da/admin_migrate.po create mode 100644 l10n/da/bookmarks.po create mode 100644 l10n/da/files_encryption.po create mode 100644 l10n/da/files_external.po create mode 100644 l10n/da/files_odfviewer.po create mode 100644 l10n/da/files_pdfviewer.po create mode 100644 l10n/da/files_sharing.po create mode 100644 l10n/da/files_texteditor.po create mode 100644 l10n/da/files_versions.po create mode 100644 l10n/da/impress.po create mode 100644 l10n/da/lib.po create mode 100644 l10n/da/tasks.po create mode 100644 l10n/da/user_ldap.po create mode 100644 l10n/da/user_migrate.po create mode 100644 l10n/da/user_openid.po create mode 100644 l10n/de/admin_dependencies_chk.po create mode 100644 l10n/de/admin_migrate.po create mode 100644 l10n/de/bookmarks.po create mode 100644 l10n/de/files_encryption.po create mode 100644 l10n/de/files_external.po create mode 100644 l10n/de/files_odfviewer.po create mode 100644 l10n/de/files_pdfviewer.po create mode 100644 l10n/de/files_sharing.po create mode 100644 l10n/de/files_texteditor.po create mode 100644 l10n/de/files_versions.po create mode 100644 l10n/de/impress.po create mode 100644 l10n/de/lib.po create mode 100644 l10n/de/tasks.po create mode 100644 l10n/de/user_ldap.po create mode 100644 l10n/de/user_migrate.po create mode 100644 l10n/de/user_openid.po delete mode 100644 l10n/de_DE/calendar.po delete mode 100644 l10n/de_DE/core.po delete mode 100644 l10n/de_DE/files.po delete mode 100644 l10n/de_DE/media.po delete mode 100644 l10n/de_DE/settings.po create mode 100644 l10n/el/admin_dependencies_chk.po create mode 100644 l10n/el/admin_migrate.po create mode 100644 l10n/el/bookmarks.po create mode 100644 l10n/el/files_encryption.po create mode 100644 l10n/el/files_external.po create mode 100644 l10n/el/files_odfviewer.po create mode 100644 l10n/el/files_pdfviewer.po create mode 100644 l10n/el/files_sharing.po create mode 100644 l10n/el/files_texteditor.po create mode 100644 l10n/el/files_versions.po create mode 100644 l10n/el/impress.po create mode 100644 l10n/el/lib.po create mode 100644 l10n/el/tasks.po create mode 100644 l10n/el/user_ldap.po create mode 100644 l10n/el/user_migrate.po create mode 100644 l10n/el/user_openid.po create mode 100644 l10n/eo/admin_dependencies_chk.po create mode 100644 l10n/eo/admin_migrate.po create mode 100644 l10n/eo/bookmarks.po create mode 100644 l10n/eo/files_encryption.po create mode 100644 l10n/eo/files_external.po create mode 100644 l10n/eo/files_odfviewer.po create mode 100644 l10n/eo/files_pdfviewer.po create mode 100644 l10n/eo/files_sharing.po create mode 100644 l10n/eo/files_texteditor.po create mode 100644 l10n/eo/files_versions.po create mode 100644 l10n/eo/impress.po create mode 100644 l10n/eo/lib.po create mode 100644 l10n/eo/tasks.po create mode 100644 l10n/eo/user_ldap.po create mode 100644 l10n/eo/user_migrate.po create mode 100644 l10n/eo/user_openid.po create mode 100644 l10n/es/admin_dependencies_chk.po create mode 100644 l10n/es/admin_migrate.po create mode 100644 l10n/es/bookmarks.po create mode 100644 l10n/es/files_encryption.po create mode 100644 l10n/es/files_external.po create mode 100644 l10n/es/files_odfviewer.po create mode 100644 l10n/es/files_pdfviewer.po create mode 100644 l10n/es/files_sharing.po create mode 100644 l10n/es/files_texteditor.po create mode 100644 l10n/es/files_versions.po create mode 100644 l10n/es/impress.po create mode 100644 l10n/es/lib.po create mode 100644 l10n/es/tasks.po create mode 100644 l10n/es/user_ldap.po create mode 100644 l10n/es/user_migrate.po create mode 100644 l10n/es/user_openid.po create mode 100644 l10n/es_AR/core.po create mode 100644 l10n/es_AR/files.po create mode 100644 l10n/es_AR/files_encryption.po create mode 100644 l10n/es_AR/files_external.po create mode 100644 l10n/es_AR/files_sharing.po create mode 100644 l10n/es_AR/files_versions.po create mode 100644 l10n/es_AR/lib.po create mode 100644 l10n/es_AR/settings.po create mode 100644 l10n/es_AR/user_ldap.po create mode 100644 l10n/et_EE/admin_dependencies_chk.po create mode 100644 l10n/et_EE/admin_migrate.po create mode 100644 l10n/et_EE/bookmarks.po create mode 100644 l10n/et_EE/files_encryption.po create mode 100644 l10n/et_EE/files_external.po create mode 100644 l10n/et_EE/files_odfviewer.po create mode 100644 l10n/et_EE/files_pdfviewer.po create mode 100644 l10n/et_EE/files_sharing.po create mode 100644 l10n/et_EE/files_texteditor.po create mode 100644 l10n/et_EE/files_versions.po create mode 100644 l10n/et_EE/impress.po create mode 100644 l10n/et_EE/lib.po create mode 100644 l10n/et_EE/tasks.po create mode 100644 l10n/et_EE/user_ldap.po create mode 100644 l10n/et_EE/user_migrate.po create mode 100644 l10n/et_EE/user_openid.po create mode 100644 l10n/eu/admin_dependencies_chk.po create mode 100644 l10n/eu/admin_migrate.po create mode 100644 l10n/eu/bookmarks.po create mode 100644 l10n/eu/files_encryption.po create mode 100644 l10n/eu/files_external.po create mode 100644 l10n/eu/files_odfviewer.po create mode 100644 l10n/eu/files_pdfviewer.po create mode 100644 l10n/eu/files_sharing.po create mode 100644 l10n/eu/files_texteditor.po create mode 100644 l10n/eu/files_versions.po create mode 100644 l10n/eu/impress.po create mode 100644 l10n/eu/lib.po create mode 100644 l10n/eu/tasks.po create mode 100644 l10n/eu/user_ldap.po create mode 100644 l10n/eu/user_migrate.po create mode 100644 l10n/eu/user_openid.po create mode 100644 l10n/eu_ES/admin_dependencies_chk.po create mode 100644 l10n/eu_ES/admin_migrate.po create mode 100644 l10n/eu_ES/bookmarks.po create mode 100644 l10n/eu_ES/calendar.po create mode 100644 l10n/eu_ES/contacts.po create mode 100644 l10n/eu_ES/core.po create mode 100644 l10n/eu_ES/files.po create mode 100644 l10n/eu_ES/files_encryption.po create mode 100644 l10n/eu_ES/files_external.po create mode 100644 l10n/eu_ES/files_odfviewer.po create mode 100644 l10n/eu_ES/files_pdfviewer.po create mode 100644 l10n/eu_ES/files_sharing.po create mode 100644 l10n/eu_ES/files_texteditor.po create mode 100644 l10n/eu_ES/files_versions.po create mode 100644 l10n/eu_ES/gallery.po create mode 100644 l10n/eu_ES/impress.po create mode 100644 l10n/eu_ES/lib.po create mode 100644 l10n/eu_ES/media.po create mode 100644 l10n/eu_ES/settings.po create mode 100644 l10n/eu_ES/tasks.po create mode 100644 l10n/eu_ES/user_ldap.po create mode 100644 l10n/eu_ES/user_migrate.po create mode 100644 l10n/eu_ES/user_openid.po create mode 100644 l10n/fa/admin_dependencies_chk.po create mode 100644 l10n/fa/admin_migrate.po create mode 100644 l10n/fa/bookmarks.po create mode 100644 l10n/fa/files_encryption.po create mode 100644 l10n/fa/files_external.po create mode 100644 l10n/fa/files_odfviewer.po create mode 100644 l10n/fa/files_pdfviewer.po create mode 100644 l10n/fa/files_sharing.po create mode 100644 l10n/fa/files_texteditor.po create mode 100644 l10n/fa/files_versions.po create mode 100644 l10n/fa/impress.po create mode 100644 l10n/fa/lib.po create mode 100644 l10n/fa/tasks.po create mode 100644 l10n/fa/user_ldap.po create mode 100644 l10n/fa/user_migrate.po create mode 100644 l10n/fa/user_openid.po create mode 100644 l10n/fi/admin_dependencies_chk.po create mode 100644 l10n/fi/admin_migrate.po create mode 100644 l10n/fi/bookmarks.po create mode 100644 l10n/fi/calendar.po create mode 100644 l10n/fi/contacts.po create mode 100644 l10n/fi/core.po create mode 100644 l10n/fi/files.po create mode 100644 l10n/fi/files_encryption.po create mode 100644 l10n/fi/files_external.po create mode 100644 l10n/fi/files_odfviewer.po create mode 100644 l10n/fi/files_pdfviewer.po create mode 100644 l10n/fi/files_sharing.po create mode 100644 l10n/fi/files_texteditor.po create mode 100644 l10n/fi/files_versions.po create mode 100644 l10n/fi/gallery.po create mode 100644 l10n/fi/impress.po create mode 100644 l10n/fi/lib.po create mode 100644 l10n/fi/media.po create mode 100644 l10n/fi/settings.po create mode 100644 l10n/fi/tasks.po create mode 100644 l10n/fi/user_ldap.po create mode 100644 l10n/fi/user_migrate.po create mode 100644 l10n/fi/user_openid.po create mode 100644 l10n/fi_FI/admin_dependencies_chk.po create mode 100644 l10n/fi_FI/admin_migrate.po create mode 100644 l10n/fi_FI/bookmarks.po create mode 100644 l10n/fi_FI/files_encryption.po create mode 100644 l10n/fi_FI/files_external.po create mode 100644 l10n/fi_FI/files_odfviewer.po create mode 100644 l10n/fi_FI/files_pdfviewer.po create mode 100644 l10n/fi_FI/files_sharing.po create mode 100644 l10n/fi_FI/files_texteditor.po create mode 100644 l10n/fi_FI/files_versions.po create mode 100644 l10n/fi_FI/impress.po create mode 100644 l10n/fi_FI/lib.po create mode 100644 l10n/fi_FI/tasks.po create mode 100644 l10n/fi_FI/user_ldap.po create mode 100644 l10n/fi_FI/user_migrate.po create mode 100644 l10n/fi_FI/user_openid.po create mode 100644 l10n/fr/admin_dependencies_chk.po create mode 100644 l10n/fr/admin_migrate.po create mode 100644 l10n/fr/bookmarks.po create mode 100644 l10n/fr/files_encryption.po create mode 100644 l10n/fr/files_external.po create mode 100644 l10n/fr/files_odfviewer.po create mode 100644 l10n/fr/files_pdfviewer.po create mode 100644 l10n/fr/files_sharing.po create mode 100644 l10n/fr/files_texteditor.po create mode 100644 l10n/fr/files_versions.po create mode 100644 l10n/fr/impress.po create mode 100644 l10n/fr/lib.po create mode 100644 l10n/fr/tasks.po create mode 100644 l10n/fr/user_ldap.po create mode 100644 l10n/fr/user_migrate.po create mode 100644 l10n/fr/user_openid.po create mode 100644 l10n/gl/admin_dependencies_chk.po create mode 100644 l10n/gl/admin_migrate.po create mode 100644 l10n/gl/bookmarks.po create mode 100644 l10n/gl/files_encryption.po create mode 100644 l10n/gl/files_external.po create mode 100644 l10n/gl/files_odfviewer.po create mode 100644 l10n/gl/files_pdfviewer.po create mode 100644 l10n/gl/files_sharing.po create mode 100644 l10n/gl/files_texteditor.po create mode 100644 l10n/gl/files_versions.po create mode 100644 l10n/gl/impress.po create mode 100644 l10n/gl/lib.po create mode 100644 l10n/gl/tasks.po create mode 100644 l10n/gl/user_ldap.po create mode 100644 l10n/gl/user_migrate.po create mode 100644 l10n/gl/user_openid.po create mode 100644 l10n/he/admin_dependencies_chk.po create mode 100644 l10n/he/admin_migrate.po create mode 100644 l10n/he/bookmarks.po create mode 100644 l10n/he/files_encryption.po create mode 100644 l10n/he/files_external.po create mode 100644 l10n/he/files_odfviewer.po create mode 100644 l10n/he/files_pdfviewer.po create mode 100644 l10n/he/files_sharing.po create mode 100644 l10n/he/files_texteditor.po create mode 100644 l10n/he/files_versions.po create mode 100644 l10n/he/impress.po create mode 100644 l10n/he/lib.po create mode 100644 l10n/he/tasks.po create mode 100644 l10n/he/user_ldap.po create mode 100644 l10n/he/user_migrate.po create mode 100644 l10n/he/user_openid.po create mode 100644 l10n/hi/core.po create mode 100644 l10n/hi/files.po create mode 100644 l10n/hi/files_encryption.po create mode 100644 l10n/hi/files_external.po create mode 100644 l10n/hi/files_sharing.po create mode 100644 l10n/hi/files_versions.po create mode 100644 l10n/hi/lib.po create mode 100644 l10n/hi/settings.po create mode 100644 l10n/hi/user_ldap.po create mode 100644 l10n/hr/admin_dependencies_chk.po create mode 100644 l10n/hr/admin_migrate.po create mode 100644 l10n/hr/bookmarks.po create mode 100644 l10n/hr/files_encryption.po create mode 100644 l10n/hr/files_external.po create mode 100644 l10n/hr/files_odfviewer.po create mode 100644 l10n/hr/files_pdfviewer.po create mode 100644 l10n/hr/files_sharing.po create mode 100644 l10n/hr/files_texteditor.po create mode 100644 l10n/hr/files_versions.po create mode 100644 l10n/hr/impress.po create mode 100644 l10n/hr/lib.po create mode 100644 l10n/hr/tasks.po create mode 100644 l10n/hr/user_ldap.po create mode 100644 l10n/hr/user_migrate.po create mode 100644 l10n/hr/user_openid.po create mode 100644 l10n/hu_HU/admin_dependencies_chk.po create mode 100644 l10n/hu_HU/admin_migrate.po create mode 100644 l10n/hu_HU/bookmarks.po create mode 100644 l10n/hu_HU/files_encryption.po create mode 100644 l10n/hu_HU/files_external.po create mode 100644 l10n/hu_HU/files_odfviewer.po create mode 100644 l10n/hu_HU/files_pdfviewer.po create mode 100644 l10n/hu_HU/files_sharing.po create mode 100644 l10n/hu_HU/files_texteditor.po create mode 100644 l10n/hu_HU/files_versions.po create mode 100644 l10n/hu_HU/impress.po create mode 100644 l10n/hu_HU/lib.po create mode 100644 l10n/hu_HU/tasks.po create mode 100644 l10n/hu_HU/user_ldap.po create mode 100644 l10n/hu_HU/user_migrate.po create mode 100644 l10n/hu_HU/user_openid.po create mode 100644 l10n/hy/admin_dependencies_chk.po create mode 100644 l10n/hy/admin_migrate.po create mode 100644 l10n/hy/bookmarks.po create mode 100644 l10n/hy/files_encryption.po create mode 100644 l10n/hy/files_external.po create mode 100644 l10n/hy/files_odfviewer.po create mode 100644 l10n/hy/files_pdfviewer.po create mode 100644 l10n/hy/files_sharing.po create mode 100644 l10n/hy/files_texteditor.po create mode 100644 l10n/hy/files_versions.po create mode 100644 l10n/hy/impress.po create mode 100644 l10n/hy/lib.po create mode 100644 l10n/hy/tasks.po create mode 100644 l10n/hy/user_ldap.po create mode 100644 l10n/hy/user_migrate.po create mode 100644 l10n/hy/user_openid.po create mode 100644 l10n/ia/admin_dependencies_chk.po create mode 100644 l10n/ia/admin_migrate.po create mode 100644 l10n/ia/bookmarks.po create mode 100644 l10n/ia/files_encryption.po create mode 100644 l10n/ia/files_external.po create mode 100644 l10n/ia/files_odfviewer.po create mode 100644 l10n/ia/files_pdfviewer.po create mode 100644 l10n/ia/files_sharing.po create mode 100644 l10n/ia/files_texteditor.po create mode 100644 l10n/ia/files_versions.po create mode 100644 l10n/ia/impress.po create mode 100644 l10n/ia/lib.po create mode 100644 l10n/ia/tasks.po create mode 100644 l10n/ia/user_ldap.po create mode 100644 l10n/ia/user_migrate.po create mode 100644 l10n/ia/user_openid.po create mode 100644 l10n/id/admin_dependencies_chk.po create mode 100644 l10n/id/admin_migrate.po create mode 100644 l10n/id/bookmarks.po create mode 100644 l10n/id/files_encryption.po create mode 100644 l10n/id/files_external.po create mode 100644 l10n/id/files_odfviewer.po create mode 100644 l10n/id/files_pdfviewer.po create mode 100644 l10n/id/files_sharing.po create mode 100644 l10n/id/files_texteditor.po create mode 100644 l10n/id/files_versions.po create mode 100644 l10n/id/impress.po create mode 100644 l10n/id/lib.po create mode 100644 l10n/id/tasks.po create mode 100644 l10n/id/user_ldap.po create mode 100644 l10n/id/user_migrate.po create mode 100644 l10n/id/user_openid.po create mode 100644 l10n/id_ID/admin_dependencies_chk.po create mode 100644 l10n/id_ID/admin_migrate.po create mode 100644 l10n/id_ID/bookmarks.po create mode 100644 l10n/id_ID/calendar.po create mode 100644 l10n/id_ID/contacts.po create mode 100644 l10n/id_ID/core.po create mode 100644 l10n/id_ID/files.po create mode 100644 l10n/id_ID/files_encryption.po create mode 100644 l10n/id_ID/files_external.po create mode 100644 l10n/id_ID/files_odfviewer.po create mode 100644 l10n/id_ID/files_pdfviewer.po create mode 100644 l10n/id_ID/files_sharing.po create mode 100644 l10n/id_ID/files_texteditor.po create mode 100644 l10n/id_ID/files_versions.po create mode 100644 l10n/id_ID/gallery.po create mode 100644 l10n/id_ID/impress.po create mode 100644 l10n/id_ID/lib.po create mode 100644 l10n/id_ID/media.po create mode 100644 l10n/id_ID/settings.po create mode 100644 l10n/id_ID/tasks.po create mode 100644 l10n/id_ID/user_ldap.po create mode 100644 l10n/id_ID/user_migrate.po create mode 100644 l10n/id_ID/user_openid.po create mode 100644 l10n/it/admin_dependencies_chk.po create mode 100644 l10n/it/admin_migrate.po create mode 100644 l10n/it/bookmarks.po create mode 100644 l10n/it/files_encryption.po create mode 100644 l10n/it/files_external.po create mode 100644 l10n/it/files_odfviewer.po create mode 100644 l10n/it/files_pdfviewer.po create mode 100644 l10n/it/files_sharing.po create mode 100644 l10n/it/files_texteditor.po create mode 100644 l10n/it/files_versions.po create mode 100644 l10n/it/impress.po create mode 100644 l10n/it/lib.po create mode 100644 l10n/it/tasks.po create mode 100644 l10n/it/user_ldap.po create mode 100644 l10n/it/user_migrate.po create mode 100644 l10n/it/user_openid.po create mode 100644 l10n/ja_JP/admin_dependencies_chk.po create mode 100644 l10n/ja_JP/admin_migrate.po create mode 100644 l10n/ja_JP/bookmarks.po create mode 100644 l10n/ja_JP/files_encryption.po create mode 100644 l10n/ja_JP/files_external.po create mode 100644 l10n/ja_JP/files_odfviewer.po create mode 100644 l10n/ja_JP/files_pdfviewer.po create mode 100644 l10n/ja_JP/files_sharing.po create mode 100644 l10n/ja_JP/files_texteditor.po create mode 100644 l10n/ja_JP/files_versions.po create mode 100644 l10n/ja_JP/impress.po create mode 100644 l10n/ja_JP/lib.po create mode 100644 l10n/ja_JP/tasks.po create mode 100644 l10n/ja_JP/user_ldap.po create mode 100644 l10n/ja_JP/user_migrate.po create mode 100644 l10n/ja_JP/user_openid.po create mode 100644 l10n/ko/admin_dependencies_chk.po create mode 100644 l10n/ko/admin_migrate.po create mode 100644 l10n/ko/bookmarks.po create mode 100644 l10n/ko/files_encryption.po create mode 100644 l10n/ko/files_external.po create mode 100644 l10n/ko/files_odfviewer.po create mode 100644 l10n/ko/files_pdfviewer.po create mode 100644 l10n/ko/files_sharing.po create mode 100644 l10n/ko/files_texteditor.po create mode 100644 l10n/ko/files_versions.po create mode 100644 l10n/ko/impress.po create mode 100644 l10n/ko/lib.po create mode 100644 l10n/ko/tasks.po create mode 100644 l10n/ko/user_ldap.po create mode 100644 l10n/ko/user_migrate.po create mode 100644 l10n/ko/user_openid.po create mode 100644 l10n/ku_IQ/core.po create mode 100644 l10n/ku_IQ/files.po create mode 100644 l10n/ku_IQ/files_encryption.po create mode 100644 l10n/ku_IQ/files_external.po create mode 100644 l10n/ku_IQ/files_sharing.po create mode 100644 l10n/ku_IQ/files_versions.po create mode 100644 l10n/ku_IQ/lib.po create mode 100644 l10n/ku_IQ/settings.po create mode 100644 l10n/ku_IQ/user_ldap.po create mode 100644 l10n/lb/admin_dependencies_chk.po create mode 100644 l10n/lb/admin_migrate.po create mode 100644 l10n/lb/bookmarks.po create mode 100644 l10n/lb/files_encryption.po create mode 100644 l10n/lb/files_external.po create mode 100644 l10n/lb/files_odfviewer.po create mode 100644 l10n/lb/files_pdfviewer.po create mode 100644 l10n/lb/files_sharing.po create mode 100644 l10n/lb/files_texteditor.po create mode 100644 l10n/lb/files_versions.po create mode 100644 l10n/lb/impress.po create mode 100644 l10n/lb/lib.po create mode 100644 l10n/lb/tasks.po create mode 100644 l10n/lb/user_ldap.po create mode 100644 l10n/lb/user_migrate.po create mode 100644 l10n/lb/user_openid.po create mode 100644 l10n/lt_LT/admin_dependencies_chk.po create mode 100644 l10n/lt_LT/admin_migrate.po create mode 100644 l10n/lt_LT/bookmarks.po create mode 100644 l10n/lt_LT/files_encryption.po create mode 100644 l10n/lt_LT/files_external.po create mode 100644 l10n/lt_LT/files_odfviewer.po create mode 100644 l10n/lt_LT/files_pdfviewer.po create mode 100644 l10n/lt_LT/files_sharing.po create mode 100644 l10n/lt_LT/files_texteditor.po create mode 100644 l10n/lt_LT/files_versions.po create mode 100644 l10n/lt_LT/impress.po create mode 100644 l10n/lt_LT/lib.po create mode 100644 l10n/lt_LT/tasks.po create mode 100644 l10n/lt_LT/user_ldap.po create mode 100644 l10n/lt_LT/user_migrate.po create mode 100644 l10n/lt_LT/user_openid.po create mode 100644 l10n/lv/admin_dependencies_chk.po create mode 100644 l10n/lv/admin_migrate.po create mode 100644 l10n/lv/bookmarks.po create mode 100644 l10n/lv/calendar.po create mode 100644 l10n/lv/contacts.po create mode 100644 l10n/lv/core.po create mode 100644 l10n/lv/files.po create mode 100644 l10n/lv/files_encryption.po create mode 100644 l10n/lv/files_external.po create mode 100644 l10n/lv/files_odfviewer.po create mode 100644 l10n/lv/files_pdfviewer.po create mode 100644 l10n/lv/files_sharing.po create mode 100644 l10n/lv/files_texteditor.po create mode 100644 l10n/lv/files_versions.po create mode 100644 l10n/lv/gallery.po create mode 100644 l10n/lv/impress.po create mode 100644 l10n/lv/lib.po create mode 100644 l10n/lv/media.po create mode 100644 l10n/lv/settings.po create mode 100644 l10n/lv/tasks.po create mode 100644 l10n/lv/user_ldap.po create mode 100644 l10n/lv/user_migrate.po create mode 100644 l10n/lv/user_openid.po create mode 100644 l10n/mk/admin_dependencies_chk.po create mode 100644 l10n/mk/admin_migrate.po create mode 100644 l10n/mk/bookmarks.po create mode 100644 l10n/mk/files_encryption.po create mode 100644 l10n/mk/files_external.po create mode 100644 l10n/mk/files_odfviewer.po create mode 100644 l10n/mk/files_pdfviewer.po create mode 100644 l10n/mk/files_sharing.po create mode 100644 l10n/mk/files_texteditor.po create mode 100644 l10n/mk/files_versions.po create mode 100644 l10n/mk/impress.po create mode 100644 l10n/mk/lib.po create mode 100644 l10n/mk/tasks.po create mode 100644 l10n/mk/user_ldap.po create mode 100644 l10n/mk/user_migrate.po create mode 100644 l10n/mk/user_openid.po create mode 100644 l10n/ms_MY/admin_dependencies_chk.po create mode 100644 l10n/ms_MY/admin_migrate.po create mode 100644 l10n/ms_MY/bookmarks.po create mode 100644 l10n/ms_MY/files_encryption.po create mode 100644 l10n/ms_MY/files_external.po create mode 100644 l10n/ms_MY/files_odfviewer.po create mode 100644 l10n/ms_MY/files_pdfviewer.po create mode 100644 l10n/ms_MY/files_sharing.po create mode 100644 l10n/ms_MY/files_texteditor.po create mode 100644 l10n/ms_MY/files_versions.po create mode 100644 l10n/ms_MY/impress.po create mode 100644 l10n/ms_MY/lib.po create mode 100644 l10n/ms_MY/tasks.po create mode 100644 l10n/ms_MY/user_ldap.po create mode 100644 l10n/ms_MY/user_migrate.po create mode 100644 l10n/ms_MY/user_openid.po create mode 100644 l10n/nb_NO/admin_dependencies_chk.po create mode 100644 l10n/nb_NO/admin_migrate.po create mode 100644 l10n/nb_NO/bookmarks.po create mode 100644 l10n/nb_NO/files_encryption.po create mode 100644 l10n/nb_NO/files_external.po create mode 100644 l10n/nb_NO/files_odfviewer.po create mode 100644 l10n/nb_NO/files_pdfviewer.po create mode 100644 l10n/nb_NO/files_sharing.po create mode 100644 l10n/nb_NO/files_texteditor.po create mode 100644 l10n/nb_NO/files_versions.po create mode 100644 l10n/nb_NO/impress.po create mode 100644 l10n/nb_NO/lib.po create mode 100644 l10n/nb_NO/tasks.po create mode 100644 l10n/nb_NO/user_ldap.po create mode 100644 l10n/nb_NO/user_migrate.po create mode 100644 l10n/nb_NO/user_openid.po create mode 100644 l10n/nl/admin_dependencies_chk.po create mode 100644 l10n/nl/admin_migrate.po create mode 100644 l10n/nl/bookmarks.po create mode 100644 l10n/nl/files_encryption.po create mode 100644 l10n/nl/files_external.po create mode 100644 l10n/nl/files_odfviewer.po create mode 100644 l10n/nl/files_pdfviewer.po create mode 100644 l10n/nl/files_sharing.po create mode 100644 l10n/nl/files_texteditor.po create mode 100644 l10n/nl/files_versions.po create mode 100644 l10n/nl/impress.po create mode 100644 l10n/nl/lib.po create mode 100644 l10n/nl/tasks.po create mode 100644 l10n/nl/user_ldap.po create mode 100644 l10n/nl/user_migrate.po create mode 100644 l10n/nl/user_openid.po create mode 100644 l10n/nn_NO/admin_dependencies_chk.po create mode 100644 l10n/nn_NO/admin_migrate.po create mode 100644 l10n/nn_NO/bookmarks.po create mode 100644 l10n/nn_NO/files_encryption.po create mode 100644 l10n/nn_NO/files_external.po create mode 100644 l10n/nn_NO/files_odfviewer.po create mode 100644 l10n/nn_NO/files_pdfviewer.po create mode 100644 l10n/nn_NO/files_sharing.po create mode 100644 l10n/nn_NO/files_texteditor.po create mode 100644 l10n/nn_NO/files_versions.po create mode 100644 l10n/nn_NO/impress.po create mode 100644 l10n/nn_NO/lib.po create mode 100644 l10n/nn_NO/tasks.po create mode 100644 l10n/nn_NO/user_ldap.po create mode 100644 l10n/nn_NO/user_migrate.po create mode 100644 l10n/nn_NO/user_openid.po create mode 100644 l10n/oc/core.po create mode 100644 l10n/oc/files.po create mode 100644 l10n/oc/files_encryption.po create mode 100644 l10n/oc/files_external.po create mode 100644 l10n/oc/files_sharing.po create mode 100644 l10n/oc/files_versions.po create mode 100644 l10n/oc/lib.po create mode 100644 l10n/oc/settings.po create mode 100644 l10n/oc/user_ldap.po create mode 100644 l10n/pl/admin_dependencies_chk.po create mode 100644 l10n/pl/admin_migrate.po create mode 100644 l10n/pl/bookmarks.po create mode 100644 l10n/pl/files_encryption.po create mode 100644 l10n/pl/files_external.po create mode 100644 l10n/pl/files_odfviewer.po create mode 100644 l10n/pl/files_pdfviewer.po create mode 100644 l10n/pl/files_sharing.po create mode 100644 l10n/pl/files_texteditor.po create mode 100644 l10n/pl/files_versions.po create mode 100644 l10n/pl/impress.po create mode 100644 l10n/pl/lib.po create mode 100644 l10n/pl/tasks.po create mode 100644 l10n/pl/user_ldap.po create mode 100644 l10n/pl/user_migrate.po create mode 100644 l10n/pl/user_openid.po create mode 100644 l10n/pl_PL/core.po create mode 100644 l10n/pl_PL/files.po create mode 100644 l10n/pl_PL/files_encryption.po create mode 100644 l10n/pl_PL/files_external.po create mode 100644 l10n/pl_PL/files_sharing.po create mode 100644 l10n/pl_PL/files_versions.po create mode 100644 l10n/pl_PL/lib.po create mode 100644 l10n/pl_PL/settings.po create mode 100644 l10n/pl_PL/user_ldap.po create mode 100644 l10n/pt_BR/admin_dependencies_chk.po create mode 100644 l10n/pt_BR/admin_migrate.po create mode 100644 l10n/pt_BR/bookmarks.po create mode 100644 l10n/pt_BR/files_encryption.po create mode 100644 l10n/pt_BR/files_external.po create mode 100644 l10n/pt_BR/files_odfviewer.po create mode 100644 l10n/pt_BR/files_pdfviewer.po create mode 100644 l10n/pt_BR/files_sharing.po create mode 100644 l10n/pt_BR/files_texteditor.po create mode 100644 l10n/pt_BR/files_versions.po create mode 100644 l10n/pt_BR/impress.po create mode 100644 l10n/pt_BR/lib.po create mode 100644 l10n/pt_BR/tasks.po create mode 100644 l10n/pt_BR/user_ldap.po create mode 100644 l10n/pt_BR/user_migrate.po create mode 100644 l10n/pt_BR/user_openid.po create mode 100644 l10n/pt_PT/admin_dependencies_chk.po create mode 100644 l10n/pt_PT/admin_migrate.po create mode 100644 l10n/pt_PT/bookmarks.po create mode 100644 l10n/pt_PT/files_encryption.po create mode 100644 l10n/pt_PT/files_external.po create mode 100644 l10n/pt_PT/files_odfviewer.po create mode 100644 l10n/pt_PT/files_pdfviewer.po create mode 100644 l10n/pt_PT/files_sharing.po create mode 100644 l10n/pt_PT/files_texteditor.po create mode 100644 l10n/pt_PT/files_versions.po create mode 100644 l10n/pt_PT/impress.po create mode 100644 l10n/pt_PT/lib.po create mode 100644 l10n/pt_PT/tasks.po create mode 100644 l10n/pt_PT/user_ldap.po create mode 100644 l10n/pt_PT/user_migrate.po create mode 100644 l10n/pt_PT/user_openid.po create mode 100644 l10n/ro/admin_dependencies_chk.po create mode 100644 l10n/ro/admin_migrate.po create mode 100644 l10n/ro/bookmarks.po create mode 100644 l10n/ro/files_encryption.po create mode 100644 l10n/ro/files_external.po create mode 100644 l10n/ro/files_odfviewer.po create mode 100644 l10n/ro/files_pdfviewer.po create mode 100644 l10n/ro/files_sharing.po create mode 100644 l10n/ro/files_texteditor.po create mode 100644 l10n/ro/files_versions.po create mode 100644 l10n/ro/impress.po create mode 100644 l10n/ro/lib.po create mode 100644 l10n/ro/tasks.po create mode 100644 l10n/ro/user_ldap.po create mode 100644 l10n/ro/user_migrate.po create mode 100644 l10n/ro/user_openid.po create mode 100644 l10n/ru/admin_dependencies_chk.po create mode 100644 l10n/ru/admin_migrate.po create mode 100644 l10n/ru/bookmarks.po create mode 100644 l10n/ru/files_encryption.po create mode 100644 l10n/ru/files_external.po create mode 100644 l10n/ru/files_odfviewer.po create mode 100644 l10n/ru/files_pdfviewer.po create mode 100644 l10n/ru/files_sharing.po create mode 100644 l10n/ru/files_texteditor.po create mode 100644 l10n/ru/files_versions.po create mode 100644 l10n/ru/impress.po create mode 100644 l10n/ru/lib.po create mode 100644 l10n/ru/tasks.po create mode 100644 l10n/ru/user_ldap.po create mode 100644 l10n/ru/user_migrate.po create mode 100644 l10n/ru/user_openid.po create mode 100644 l10n/ru_RU/core.po create mode 100644 l10n/ru_RU/files.po create mode 100644 l10n/ru_RU/files_encryption.po create mode 100644 l10n/ru_RU/files_external.po create mode 100644 l10n/ru_RU/files_sharing.po create mode 100644 l10n/ru_RU/files_versions.po create mode 100644 l10n/ru_RU/lib.po create mode 100644 l10n/ru_RU/settings.po create mode 100644 l10n/ru_RU/user_ldap.po create mode 100644 l10n/si_LK/core.po create mode 100644 l10n/si_LK/files.po create mode 100644 l10n/si_LK/files_encryption.po create mode 100644 l10n/si_LK/files_external.po create mode 100644 l10n/si_LK/files_sharing.po create mode 100644 l10n/si_LK/files_versions.po create mode 100644 l10n/si_LK/lib.po create mode 100644 l10n/si_LK/settings.po create mode 100644 l10n/si_LK/user_ldap.po create mode 100644 l10n/sk_SK/admin_dependencies_chk.po create mode 100644 l10n/sk_SK/admin_migrate.po create mode 100644 l10n/sk_SK/bookmarks.po create mode 100644 l10n/sk_SK/files_encryption.po create mode 100644 l10n/sk_SK/files_external.po create mode 100644 l10n/sk_SK/files_odfviewer.po create mode 100644 l10n/sk_SK/files_pdfviewer.po create mode 100644 l10n/sk_SK/files_sharing.po create mode 100644 l10n/sk_SK/files_texteditor.po create mode 100644 l10n/sk_SK/files_versions.po create mode 100644 l10n/sk_SK/impress.po create mode 100644 l10n/sk_SK/lib.po create mode 100644 l10n/sk_SK/tasks.po create mode 100644 l10n/sk_SK/user_ldap.po create mode 100644 l10n/sk_SK/user_migrate.po create mode 100644 l10n/sk_SK/user_openid.po create mode 100644 l10n/sl/admin_dependencies_chk.po create mode 100644 l10n/sl/admin_migrate.po create mode 100644 l10n/sl/bookmarks.po create mode 100644 l10n/sl/files_encryption.po create mode 100644 l10n/sl/files_external.po create mode 100644 l10n/sl/files_odfviewer.po create mode 100644 l10n/sl/files_pdfviewer.po create mode 100644 l10n/sl/files_sharing.po create mode 100644 l10n/sl/files_texteditor.po create mode 100644 l10n/sl/files_versions.po create mode 100644 l10n/sl/impress.po create mode 100644 l10n/sl/lib.po create mode 100644 l10n/sl/tasks.po create mode 100644 l10n/sl/user_ldap.po create mode 100644 l10n/sl/user_migrate.po create mode 100644 l10n/sl/user_openid.po create mode 100644 l10n/so/admin_dependencies_chk.po create mode 100644 l10n/so/admin_migrate.po create mode 100644 l10n/so/bookmarks.po create mode 100644 l10n/so/calendar.po create mode 100644 l10n/so/contacts.po create mode 100644 l10n/so/core.po create mode 100644 l10n/so/files.po create mode 100644 l10n/so/files_encryption.po create mode 100644 l10n/so/files_external.po create mode 100644 l10n/so/files_odfviewer.po create mode 100644 l10n/so/files_pdfviewer.po create mode 100644 l10n/so/files_sharing.po create mode 100644 l10n/so/files_texteditor.po create mode 100644 l10n/so/files_versions.po create mode 100644 l10n/so/gallery.po create mode 100644 l10n/so/impress.po create mode 100644 l10n/so/lib.po create mode 100644 l10n/so/media.po create mode 100644 l10n/so/settings.po create mode 100644 l10n/so/tasks.po create mode 100644 l10n/so/user_ldap.po create mode 100644 l10n/so/user_migrate.po create mode 100644 l10n/so/user_openid.po create mode 100644 l10n/sr/admin_dependencies_chk.po create mode 100644 l10n/sr/admin_migrate.po create mode 100644 l10n/sr/bookmarks.po create mode 100644 l10n/sr/files_encryption.po create mode 100644 l10n/sr/files_external.po create mode 100644 l10n/sr/files_odfviewer.po create mode 100644 l10n/sr/files_pdfviewer.po create mode 100644 l10n/sr/files_sharing.po create mode 100644 l10n/sr/files_texteditor.po create mode 100644 l10n/sr/files_versions.po create mode 100644 l10n/sr/impress.po create mode 100644 l10n/sr/lib.po create mode 100644 l10n/sr/tasks.po create mode 100644 l10n/sr/user_ldap.po create mode 100644 l10n/sr/user_migrate.po create mode 100644 l10n/sr/user_openid.po create mode 100644 l10n/sr@latin/admin_dependencies_chk.po create mode 100644 l10n/sr@latin/admin_migrate.po create mode 100644 l10n/sr@latin/bookmarks.po create mode 100644 l10n/sr@latin/files_encryption.po create mode 100644 l10n/sr@latin/files_external.po create mode 100644 l10n/sr@latin/files_odfviewer.po create mode 100644 l10n/sr@latin/files_pdfviewer.po create mode 100644 l10n/sr@latin/files_sharing.po create mode 100644 l10n/sr@latin/files_texteditor.po create mode 100644 l10n/sr@latin/files_versions.po create mode 100644 l10n/sr@latin/impress.po create mode 100644 l10n/sr@latin/lib.po create mode 100644 l10n/sr@latin/tasks.po create mode 100644 l10n/sr@latin/user_ldap.po create mode 100644 l10n/sr@latin/user_migrate.po create mode 100644 l10n/sr@latin/user_openid.po create mode 100644 l10n/sv/admin_dependencies_chk.po create mode 100644 l10n/sv/admin_migrate.po create mode 100644 l10n/sv/bookmarks.po create mode 100644 l10n/sv/files_encryption.po create mode 100644 l10n/sv/files_external.po create mode 100644 l10n/sv/files_odfviewer.po create mode 100644 l10n/sv/files_pdfviewer.po create mode 100644 l10n/sv/files_sharing.po create mode 100644 l10n/sv/files_texteditor.po create mode 100644 l10n/sv/files_versions.po create mode 100644 l10n/sv/impress.po create mode 100644 l10n/sv/lib.po create mode 100644 l10n/sv/tasks.po create mode 100644 l10n/sv/user_ldap.po create mode 100644 l10n/sv/user_migrate.po create mode 100644 l10n/sv/user_openid.po create mode 100644 l10n/ta_LK/core.po create mode 100644 l10n/ta_LK/files.po create mode 100644 l10n/ta_LK/files_encryption.po create mode 100644 l10n/ta_LK/files_external.po create mode 100644 l10n/ta_LK/files_sharing.po create mode 100644 l10n/ta_LK/files_versions.po create mode 100644 l10n/ta_LK/lib.po create mode 100644 l10n/ta_LK/settings.po create mode 100644 l10n/ta_LK/user_ldap.po delete mode 100644 l10n/templates/bookmarks.pot delete mode 100644 l10n/templates/calendar.pot delete mode 100644 l10n/templates/contacts.pot create mode 100644 l10n/templates/files_encryption.pot create mode 100644 l10n/templates/files_external.pot create mode 100644 l10n/templates/files_sharing.pot create mode 100644 l10n/templates/files_versions.pot delete mode 100644 l10n/templates/gallery.pot create mode 100644 l10n/templates/lib.pot delete mode 100644 l10n/templates/media.pot create mode 100644 l10n/templates/user_ldap.pot create mode 100644 l10n/th_TH/admin_dependencies_chk.po create mode 100644 l10n/th_TH/admin_migrate.po create mode 100644 l10n/th_TH/bookmarks.po create mode 100644 l10n/th_TH/files_encryption.po create mode 100644 l10n/th_TH/files_external.po create mode 100644 l10n/th_TH/files_odfviewer.po create mode 100644 l10n/th_TH/files_pdfviewer.po create mode 100644 l10n/th_TH/files_sharing.po create mode 100644 l10n/th_TH/files_texteditor.po create mode 100644 l10n/th_TH/files_versions.po create mode 100644 l10n/th_TH/impress.po create mode 100644 l10n/th_TH/lib.po create mode 100644 l10n/th_TH/tasks.po create mode 100644 l10n/th_TH/user_ldap.po create mode 100644 l10n/th_TH/user_migrate.po create mode 100644 l10n/th_TH/user_openid.po create mode 100644 l10n/tr/admin_dependencies_chk.po create mode 100644 l10n/tr/admin_migrate.po create mode 100644 l10n/tr/bookmarks.po create mode 100644 l10n/tr/files_encryption.po create mode 100644 l10n/tr/files_external.po create mode 100644 l10n/tr/files_odfviewer.po create mode 100644 l10n/tr/files_pdfviewer.po create mode 100644 l10n/tr/files_sharing.po create mode 100644 l10n/tr/files_texteditor.po create mode 100644 l10n/tr/files_versions.po create mode 100644 l10n/tr/impress.po create mode 100644 l10n/tr/lib.po create mode 100644 l10n/tr/tasks.po create mode 100644 l10n/tr/user_ldap.po create mode 100644 l10n/tr/user_migrate.po create mode 100644 l10n/tr/user_openid.po create mode 100644 l10n/uk/admin_dependencies_chk.po create mode 100644 l10n/uk/admin_migrate.po create mode 100644 l10n/uk/bookmarks.po create mode 100644 l10n/uk/files_encryption.po create mode 100644 l10n/uk/files_external.po create mode 100644 l10n/uk/files_odfviewer.po create mode 100644 l10n/uk/files_pdfviewer.po create mode 100644 l10n/uk/files_sharing.po create mode 100644 l10n/uk/files_texteditor.po create mode 100644 l10n/uk/files_versions.po create mode 100644 l10n/uk/impress.po create mode 100644 l10n/uk/lib.po create mode 100644 l10n/uk/tasks.po create mode 100644 l10n/uk/user_ldap.po create mode 100644 l10n/uk/user_migrate.po create mode 100644 l10n/uk/user_openid.po create mode 100644 l10n/vi/admin_dependencies_chk.po create mode 100644 l10n/vi/admin_migrate.po create mode 100644 l10n/vi/bookmarks.po create mode 100644 l10n/vi/calendar.po create mode 100644 l10n/vi/contacts.po create mode 100644 l10n/vi/core.po create mode 100644 l10n/vi/files.po create mode 100644 l10n/vi/files_encryption.po create mode 100644 l10n/vi/files_external.po create mode 100644 l10n/vi/files_odfviewer.po create mode 100644 l10n/vi/files_pdfviewer.po create mode 100644 l10n/vi/files_sharing.po create mode 100644 l10n/vi/files_texteditor.po create mode 100644 l10n/vi/files_versions.po create mode 100644 l10n/vi/gallery.po create mode 100644 l10n/vi/impress.po create mode 100644 l10n/vi/lib.po create mode 100644 l10n/vi/media.po create mode 100644 l10n/vi/settings.po create mode 100644 l10n/vi/tasks.po create mode 100644 l10n/vi/user_ldap.po create mode 100644 l10n/vi/user_migrate.po create mode 100644 l10n/vi/user_openid.po create mode 100644 l10n/zh_CN.GB2312/admin_dependencies_chk.po create mode 100644 l10n/zh_CN.GB2312/admin_migrate.po create mode 100644 l10n/zh_CN.GB2312/bookmarks.po create mode 100644 l10n/zh_CN.GB2312/calendar.po create mode 100644 l10n/zh_CN.GB2312/contacts.po create mode 100644 l10n/zh_CN.GB2312/core.po create mode 100644 l10n/zh_CN.GB2312/files.po create mode 100644 l10n/zh_CN.GB2312/files_encryption.po create mode 100644 l10n/zh_CN.GB2312/files_external.po create mode 100644 l10n/zh_CN.GB2312/files_odfviewer.po create mode 100644 l10n/zh_CN.GB2312/files_pdfviewer.po create mode 100644 l10n/zh_CN.GB2312/files_sharing.po create mode 100644 l10n/zh_CN.GB2312/files_texteditor.po create mode 100644 l10n/zh_CN.GB2312/files_versions.po create mode 100644 l10n/zh_CN.GB2312/gallery.po create mode 100644 l10n/zh_CN.GB2312/impress.po create mode 100644 l10n/zh_CN.GB2312/lib.po create mode 100644 l10n/zh_CN.GB2312/media.po create mode 100644 l10n/zh_CN.GB2312/settings.po create mode 100644 l10n/zh_CN.GB2312/tasks.po create mode 100644 l10n/zh_CN.GB2312/user_ldap.po create mode 100644 l10n/zh_CN.GB2312/user_migrate.po create mode 100644 l10n/zh_CN.GB2312/user_openid.po create mode 100644 l10n/zh_CN/admin_dependencies_chk.po create mode 100644 l10n/zh_CN/admin_migrate.po create mode 100644 l10n/zh_CN/bookmarks.po create mode 100644 l10n/zh_CN/files_encryption.po create mode 100644 l10n/zh_CN/files_external.po create mode 100644 l10n/zh_CN/files_odfviewer.po create mode 100644 l10n/zh_CN/files_pdfviewer.po create mode 100644 l10n/zh_CN/files_sharing.po create mode 100644 l10n/zh_CN/files_texteditor.po create mode 100644 l10n/zh_CN/files_versions.po create mode 100644 l10n/zh_CN/impress.po create mode 100644 l10n/zh_CN/lib.po create mode 100644 l10n/zh_CN/tasks.po create mode 100644 l10n/zh_CN/user_ldap.po create mode 100644 l10n/zh_CN/user_migrate.po create mode 100644 l10n/zh_CN/user_openid.po create mode 100644 l10n/zh_TW/admin_dependencies_chk.po create mode 100644 l10n/zh_TW/admin_migrate.po create mode 100644 l10n/zh_TW/bookmarks.po create mode 100644 l10n/zh_TW/files_encryption.po create mode 100644 l10n/zh_TW/files_external.po create mode 100644 l10n/zh_TW/files_odfviewer.po create mode 100644 l10n/zh_TW/files_pdfviewer.po create mode 100644 l10n/zh_TW/files_sharing.po create mode 100644 l10n/zh_TW/files_texteditor.po create mode 100644 l10n/zh_TW/files_versions.po create mode 100644 l10n/zh_TW/impress.po create mode 100644 l10n/zh_TW/lib.po create mode 100644 l10n/zh_TW/tasks.po create mode 100644 l10n/zh_TW/user_ldap.po create mode 100644 l10n/zh_TW/user_migrate.po create mode 100644 l10n/zh_TW/user_openid.po create mode 100644 lib/backgroundjob/queuedtask.php create mode 100644 lib/backgroundjob/regulartask.php create mode 100644 lib/backgroundjob/worker.php create mode 100644 lib/filechunking.php create mode 100644 lib/fileproxy/fileoperations.php create mode 100644 lib/group/interface.php create mode 100644 lib/l10n/ca.php create mode 100644 lib/l10n/cs_CZ.php create mode 100644 lib/l10n/da.php create mode 100644 lib/l10n/de.php create mode 100644 lib/l10n/el.php create mode 100644 lib/l10n/eo.php create mode 100644 lib/l10n/es.php create mode 100644 lib/l10n/es_AR.php create mode 100644 lib/l10n/et_EE.php create mode 100644 lib/l10n/eu.php create mode 100644 lib/l10n/fa.php create mode 100644 lib/l10n/fi_FI.php create mode 100644 lib/l10n/fr.php create mode 100644 lib/l10n/gl.php create mode 100644 lib/l10n/he.php create mode 100644 lib/l10n/hu_HU.php create mode 100644 lib/l10n/it.php create mode 100644 lib/l10n/ja_JP.php create mode 100644 lib/l10n/lt_LT.php create mode 100644 lib/l10n/nb_NO.php create mode 100644 lib/l10n/nl.php create mode 100644 lib/l10n/oc.php create mode 100644 lib/l10n/pl.php create mode 100644 lib/l10n/pt_BR.php create mode 100644 lib/l10n/pt_PT.php create mode 100644 lib/l10n/ro.php create mode 100644 lib/l10n/ru.php create mode 100644 lib/l10n/ru_RU.php create mode 100644 lib/l10n/sk_SK.php create mode 100644 lib/l10n/sl.php create mode 100644 lib/l10n/sv.php create mode 100644 lib/l10n/th_TH.php create mode 100644 lib/l10n/uk.php create mode 100644 lib/l10n/vi.php create mode 100644 lib/l10n/zh_CN.GB2312.php create mode 100644 lib/l10n/zh_CN.php create mode 100644 lib/l10n/zh_TW.php delete mode 100644 lib/mimetypes.fixlist.php create mode 100644 lib/public/backgroundjob.php create mode 100644 lib/public/groupinterface.php create mode 100644 lib/public/share.php create mode 100644 lib/public/userinterface.php create mode 100644 lib/subadmin.php create mode 100644 lib/user/interface.php delete mode 100644 search/index.php delete mode 100644 search/templates/index.php create mode 100644 settings/ajax/apps/ocs.php create mode 100644 settings/ajax/togglesubadmins.php create mode 100644 settings/ajax/userlist.php create mode 100644 settings/l10n/es_AR.php create mode 100644 settings/l10n/lv.php create mode 100644 settings/l10n/oc.php create mode 100644 settings/l10n/ru_RU.php create mode 100644 settings/l10n/si_LK.php create mode 100644 settings/l10n/uk.php create mode 100644 settings/l10n/vi.php create mode 100644 settings/l10n/zh_CN.GB2312.php delete mode 100644 settings/log.php mode change 100755 => 100644 settings/templates/admin.php create mode 100644 tests/apps.php create mode 100644 tests/bootstrap.php rename {apps/files_archive/tests => tests}/data/data.tar.gz (100%) rename {apps/files_archive/tests => tests}/data/data.zip (100%) create mode 100644 tests/data/db_structure.xml create mode 100644 tests/data/db_structure2.xml delete mode 100644 tests/index.php create mode 100644 tests/lib/db.php create mode 100644 tests/lib/dbschema.php create mode 100644 tests/lib/geo.php create mode 100644 tests/lib/helper.php create mode 100644 tests/lib/share/backend.php create mode 100644 tests/lib/share/share.php create mode 100644 tests/lib/util.php create mode 100644 tests/phpunit.xml delete mode 100644 webapps.php diff --git a/.gitignore b/.gitignore index ae63693170..4749dea19d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,10 +19,12 @@ _darcs/* CVS/* .svn/* RCS/* +*.backup* # kdevelop .kdev *.kdev4 +*.kate-swp # Lokalize *lokalize* diff --git a/.tx/config b/.tx/config deleted file mode 100644 index b51860f8b2..0000000000 --- a/.tx/config +++ /dev/null @@ -1,182 +0,0 @@ -[main] -host = https://www.transifex.net - -[owncloud.core] -file_filter = l10n//core.po -host = http://www.transifex.net -source_file = l10n/templates/core.pot -source_lang = en -trans.bg_BG = l10n/bg_BG/core.po -trans.ca = l10n/ca/core.po -trans.cs_CZ = l10n/cs_CZ/core.po -trans.da = l10n/da/core.po -trans.de = l10n/de/core.po -trans.el = l10n/el/core.po -trans.es = l10n/es/core.po -trans.et_EE = l10n/et_EE/core.po -trans.fr = l10n/fr/core.po -trans.id = l10n/id/core.po -trans.it = l10n/it/core.po -trans.lb = l10n/lb/core.po -trans.ms_MY = l10n/ms_MY/core.po -trans.nb_NO = l10n/nb_NO/core.po -trans.nl = l10n/nl/core.po -trans.pl = l10n/pl/core.po -trans.pt_BR = l10n/pt_BR/core.po -trans.pt_PT = l10n/pt_PT/core.po -trans.ro = l10n/ro/core.po -trans.ru = l10n/ru/core.po -trans.sr = l10n/sr/core.po -trans.sr@latin = l10n/sr@latin/core.po -trans.sv = l10n/sv/core.po -trans.zh_CN = l10n/zh_CN/core.po - -[owncloud.settings] -file_filter = l10n//settings.po -host = http://www.transifex.net -source_file = l10n/templates/settings.pot -source_lang = en -trans.bg_BG = l10n/bg_BG/settings.po -trans.ca = l10n/ca/settings.po -trans.cs_CZ = l10n/cs_CZ/settings.po -trans.da = l10n/da/settings.po -trans.de = l10n/de/settings.po -trans.el = l10n/el/settings.po -trans.es = l10n/es/settings.po -trans.et_EE = l10n/et_EE/settings.po -trans.fr = l10n/fr/settings.po -trans.id = l10n/id/settings.po -trans.it = l10n/it/settings.po -trans.lb = l10n/lb/settings.po -trans.ms_MY = l10n/ms_MY/settings.po -trans.nb_NO = l10n/nb_NO/settings.po -trans.nl = l10n/nl/settings.po -trans.pl = l10n/pl/settings.po -trans.pt_BR = l10n/pt_BR/settings.po -trans.pt_PT = l10n/pt_PT/settings.po -trans.ro = l10n/ro/settings.po -trans.ru = l10n/ru/settings.po -trans.sr = l10n/sr/settings.po -trans.sr@latin = l10n/sr@latin/settings.po -trans.sv = l10n/sv/settings.po -trans.zh_CN = l10n/zh_CN/settings.po - -[owncloud.files] -file_filter = translations/owncloud.files/.po -host = http://www.transifex.net -source_file = l10n/templates/files.pot -source_lang = en -trans.bg_BG = l10n/bg_BG/files.po -trans.ca = l10n/ca/files.po -trans.cs_CZ = l10n/cs_CZ/files.po -trans.da = l10n/da/files.po -trans.de = l10n/de/files.po -trans.el = l10n/el/files.po -trans.es = l10n/es/files.po -trans.et_EE = l10n/et_EE/files.po -trans.fr = l10n/fr/files.po -trans.id = l10n/id/files.po -trans.it = l10n/it/files.po -trans.lb = l10n/lb/files.po -trans.ms_MY = l10n/ms_MY/files.po -trans.nb_NO = l10n/nb_NO/files.po -trans.nl = l10n/nl/files.po -trans.pl = l10n/pl/files.po -trans.pt_BR = l10n/pt_BR/files.po -trans.pt_PT = l10n/pt_PT/files.po -trans.ro = l10n/ro/files.po -trans.ru = l10n/ru/files.po -trans.sr = l10n/sr/files.po -trans.sr@latin = l10n/sr@latin/files.po -trans.sv = l10n/sv/files.po -trans.zh_CN = l10n/zh_CN/files.po - -[owncloud.media] -file_filter = translations/owncloud.media/.po -host = http://www.transifex.net -source_file = l10n/templates/media.pot -source_lang = en -trans.bg_BG = l10n/bg_BG/media.po -trans.ca = l10n/ca/media.po -trans.cs_CZ = l10n/cs_CZ/media.po -trans.da = l10n/da/media.po -trans.de = l10n/de/media.po -trans.el = l10n/el/media.po -trans.es = l10n/es/media.po -trans.et_EE = l10n/et_EE/media.po -trans.fr = l10n/fr/media.po -trans.id = l10n/id/media.po -trans.it = l10n/it/media.po -trans.lb = l10n/lb/media.po -trans.ms_MY = l10n/ms_MY/media.po -trans.nb_NO = l10n/nb_NO/media.po -trans.nl = l10n/nl/media.po -trans.pl = l10n/pl/media.po -trans.pt_BR = l10n/pt_BR/media.po -trans.pt_PT = l10n/pt_PT/media.po -trans.ro = l10n/ro/media.po -trans.ru = l10n/ru/media.po -trans.sr = l10n/sr/media.po -trans.sr@latin = l10n/sr@latin/media.po -trans.sv = l10n/sv/media.po -trans.zh_CN = l10n/zh_CN/media.po - -[owncloud.calendar] -file_filter = l10n//calendar.po -host = http://www.transifex.net -source_file = l10n/templates/calendar.pot -source_lang = en -trans.bg_BG = l10n/bg_BG/calendar.po -trans.ca = l10n/ca/calendar.po -trans.cs_CZ = l10n/cs_CZ/calendar.po -trans.da = l10n/da/calendar.po -trans.de = l10n/de/calendar.po -trans.el = l10n/el/calendar.po -trans.es = l10n/es/calendar.po -trans.et_EE = l10n/et_EE/calendar.po -trans.fr = l10n/fr/calendar.po -trans.id = l10n/id/calendar.po -trans.it = l10n/it/calendar.po -trans.lb = l10n/lb/calendar.po -trans.ms_MY = l10n/ms_MY/calendar.po -trans.nb_NO = l10n/nb_NO/calendar.po -trans.nl = l10n/nl/calendar.po -trans.pl = l10n/pl/calendar.po -trans.pt_BR = l10n/pt_BR/calendar.po -trans.pt_PT = l10n/pt_PT/calendar.po -trans.ro = l10n/ro/calendar.po -trans.ru = l10n/ru/calendar.po -trans.sr = l10n/sr/calendar.po -trans.sr@latin = l10n/sr@latin/calendar.po -trans.sv = l10n/sv/calendar.po -trans.zh_CN = l10n/zh_CN/calendar.po - -[owncloud.contacts] -file_filter = translations/owncloud.contacts/.po -host = http://www.transifex.net -source_file = l10n/templates/contacts.pot -source_lang = en -trans.bg_BG = l10n/bg_BG/contacts.po -trans.ca = l10n/ca/contacts.po -trans.cs_CZ = l10n/cs_CZ/contacts.po -trans.da = l10n/da/contacts.po -trans.de = l10n/de/contacts.po -trans.el = l10n/el/contacts.po -trans.es = l10n/es/contacts.po -trans.et_EE = l10n/et_EE/contacts.po -trans.fr = l10n/fr/contacts.po -trans.id = l10n/id/contacts.po -trans.it = l10n/it/contacts.po -trans.lb = l10n/lb/contacts.po -trans.ms_MY = l10n/ms_MY/contacts.po -trans.nb_NO = l10n/nb_NO/contacts.po -trans.nl = l10n/nl/contacts.po -trans.pl = l10n/pl/contacts.po -trans.pt_BR = l10n/pt_BR/contacts.po -trans.pt_PT = l10n/pt_PT/contacts.po -trans.ro = l10n/ro/contacts.po -trans.ru = l10n/ru/contacts.po -trans.sr = l10n/sr/contacts.po -trans.sr@latin = l10n/sr@latin/contacts.po -trans.sv = l10n/sv/contacts.po -trans.zh_CN = l10n/zh_CN/contacts.po diff --git a/3rdparty/Archive/Tar.php b/3rdparty/Archive/Tar.php index e9969501a0..fd2d5d7d9b 100644 --- a/3rdparty/Archive/Tar.php +++ b/3rdparty/Archive/Tar.php @@ -35,7 +35,7 @@ * @author Vincent Blavet * @copyright 1997-2010 The Authors * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Tar.php 323476 2012-02-24 15:27:26Z mrook $ + * @version CVS: $Id: Tar.php 324840 2012-04-05 08:44:41Z mrook $ * @link http://pear.php.net/package/Archive_Tar */ @@ -50,7 +50,7 @@ define('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); * @package Archive_Tar * @author Vincent Blavet * @license http://www.opensource.org/licenses/bsd-license.php New BSD License -* @version $Revision: 323476 $ +* @version $Revision: 324840 $ */ class Archive_Tar extends PEAR { @@ -577,7 +577,7 @@ class Archive_Tar extends PEAR } // ----- Get the arguments - $v_att_list = func_get_args(); + $v_att_list = &func_get_args(); // ----- Read the attributes $i=0; @@ -649,14 +649,14 @@ class Archive_Tar extends PEAR // {{{ _error() function _error($p_message) { - $this->error_object = $this->raiseError($p_message); + $this->error_object = &$this->raiseError($p_message); } // }}} // {{{ _warning() function _warning($p_message) { - $this->error_object = $this->raiseError($p_message); + $this->error_object = &$this->raiseError($p_message); } // }}} @@ -981,7 +981,7 @@ class Archive_Tar extends PEAR // }}} // {{{ _addFile() - function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir,$v_stored_filename=null) + function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename=null) { if (!$this->_file) { $this->_error('Invalid file descriptor'); @@ -992,31 +992,32 @@ class Archive_Tar extends PEAR $this->_error('Invalid file name'); return false; } - if(is_null($v_stored_filename)){ - // ----- Calculate the stored filename - $p_filename = $this->_translateWinPath($p_filename, false); - $v_stored_filename = $p_filename; - if (strcmp($p_filename, $p_remove_dir) == 0) { - return true; - } - if ($p_remove_dir != '') { - if (substr($p_remove_dir, -1) != '/') - $p_remove_dir .= '/'; + // ownCloud change to make it possible to specify the filename to use + if(is_null($v_stored_filename)) { + // ----- Calculate the stored filename + $p_filename = $this->_translateWinPath($p_filename, false); + $v_stored_filename = $p_filename; + if (strcmp($p_filename, $p_remove_dir) == 0) { + return true; + } + if ($p_remove_dir != '') { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= '/'; - if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) - $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); - } - $v_stored_filename = $this->_translateWinPath($v_stored_filename); - if ($p_add_dir != '') { - if (substr($p_add_dir, -1) == '/') - $v_stored_filename = $p_add_dir.$v_stored_filename; - else - $v_stored_filename = $p_add_dir.'/'.$v_stored_filename; - } + if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) + $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); + } + $v_stored_filename = $this->_translateWinPath($v_stored_filename); + if ($p_add_dir != '') { + if (substr($p_add_dir, -1) == '/') + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir.'/'.$v_stored_filename; + } - $v_stored_filename = $this->_pathReduction($v_stored_filename); - } + $v_stored_filename = $this->_pathReduction($v_stored_filename); + } if ($this->_isArchive($p_filename)) { if (($v_file = @fopen($p_filename, "rb")) == 0) { @@ -1775,12 +1776,20 @@ class Archive_Tar extends PEAR } if ($this->_compress_type == 'gz') { + $end_blocks = 0; + while (!@gzeof($v_temp_tar)) { $v_buffer = @gzread($v_temp_tar, 512); if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { + $end_blocks++; // do not copy end blocks, we will re-make them // after appending continue; + } elseif ($end_blocks > 0) { + for ($i = 0; $i < $end_blocks; $i++) { + $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); + } + $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); @@ -1789,9 +1798,19 @@ class Archive_Tar extends PEAR @gzclose($v_temp_tar); } elseif ($this->_compress_type == 'bz2') { + $end_blocks = 0; + while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) { - if ($v_buffer == ARCHIVE_TAR_END_BLOCK) { + if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { + $end_blocks++; + // do not copy end blocks, we will re-make them + // after appending continue; + } elseif ($end_blocks > 0) { + for ($i = 0; $i < $end_blocks; $i++) { + $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); + } + $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); diff --git a/3rdparty/MDB2/Driver/Datatype/Common.php b/3rdparty/MDB2/Driver/Datatype/Common.php index 3b02c86acd..dd7f1c7e0a 100644 --- a/3rdparty/MDB2/Driver/Datatype/Common.php +++ b/3rdparty/MDB2/Driver/Datatype/Common.php @@ -1412,7 +1412,7 @@ class MDB2_Driver_Datatype_Common extends MDB2_Module_Common if (PEAR::isError($db)) { return $db; } - if (isset($db->function) && is_object($this->function) && is_a($db->function, 'MDB2_Driver_Function_Common')) { + if (isset($db->function) && is_object($db->function) && is_a($db->function, 'MDB2_Driver_Function_Common')) { return $db->function->now('timestamp'); } return 'CURRENT_TIMESTAMP'; diff --git a/3rdparty/MDB2/Driver/Datatype/oci8.php b/3rdparty/MDB2/Driver/Datatype/oci8.php new file mode 100644 index 0000000000..4d2e792a80 --- /dev/null +++ b/3rdparty/MDB2/Driver/Datatype/oci8.php @@ -0,0 +1,499 @@ + | +// +----------------------------------------------------------------------+ + +// $Id: oci8.php 295587 2010-02-28 17:16:38Z quipo $ + +require_once 'MDB2/Driver/Datatype/Common.php'; + +/** + * MDB2 OCI8 driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_Driver_Datatype_oci8 extends MDB2_Driver_Datatype_Common +{ + // {{{ _baseConvertResult() + + /** + * general type conversion method + * + * @param mixed $value refernce to a value to be converted + * @param string $type specifies which type to convert to + * @param boolean $rtrim [optional] when TRUE [default], apply rtrim() to text + * @return object a MDB2 error on failure + * @access protected + */ + function _baseConvertResult($value, $type, $rtrim = true) + { + if (null === $value) { + return null; + } + switch ($type) { + case 'text': + if (is_object($value) && is_a($value, 'OCI-Lob')) { + //LOB => fetch into variable + $clob = $this->_baseConvertResult($value, 'clob', $rtrim); + if (!PEAR::isError($clob) && is_resource($clob)) { + $clob_value = ''; + while (!feof($clob)) { + $clob_value .= fread($clob, 8192); + } + $this->destroyLOB($clob); + } + $value = $clob_value; + } + if ($rtrim) { + $value = rtrim($value); + } + return $value; + case 'date': + return substr($value, 0, strlen('YYYY-MM-DD')); + case 'time': + return substr($value, strlen('YYYY-MM-DD '), strlen('HH:MI:SS')); + } + return parent::_baseConvertResult($value, $type, $rtrim); + } + + // }}} + // {{{ getTypeDeclaration() + + /** + * Obtain DBMS specific SQL code portion needed to declare an text type + * field to be used in statements like CREATE TABLE. + * + * @param array $field associative array with the name of the properties + * of the field being declared as array indexes. Currently, the types + * of supported field properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * field. If this argument is missing the field should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this field. + * + * notnull + * Boolean flag that indicates whether this field is constrained + * to not be set to null. + * @return string DBMS specific SQL code portion that should be used to + * declare the specified field. + * @access public + */ + function getTypeDeclaration($field) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + switch ($field['type']) { + case 'text': + $length = !empty($field['length']) + ? $field['length'] : $db->options['default_text_field_length']; + $fixed = !empty($field['fixed']) ? $field['fixed'] : false; + return $fixed ? 'CHAR('.$length.')' : 'VARCHAR2('.$length.')'; + case 'clob': + return 'CLOB'; + case 'blob': + return 'BLOB'; + case 'integer': + if (!empty($field['length'])) { + switch((int)$field['length']) { + case 1: $digit = 3; break; + case 2: $digit = 5; break; + case 3: $digit = 8; break; + case 4: $digit = 10; break; + case 5: $digit = 13; break; + case 6: $digit = 15; break; + case 7: $digit = 17; break; + case 8: $digit = 20; break; + default: $digit = 10; + } + return 'NUMBER('.$digit.')'; + } + return 'INT'; + case 'boolean': + return 'NUMBER(1)'; + case 'date': + case 'time': + case 'timestamp': + return 'DATE'; + case 'float': + return 'NUMBER'; + case 'decimal': + $scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places']; + return 'NUMBER(*,'.$scale.')'; + } + } + + // }}} + // {{{ _quoteCLOB() + + /** + * Convert a text value into a DBMS specific format that is suitable to + * compose query statements. + * + * @param string $value text string value that is intended to be converted. + * @param bool $quote determines if the value should be quoted and escaped + * @param bool $escape_wildcards if to escape escape wildcards + * @return string text string that represents the given argument value in + * a DBMS specific format. + * @access protected + */ + function _quoteCLOB($value, $quote, $escape_wildcards) + { + return 'EMPTY_CLOB()'; + } + + // }}} + // {{{ _quoteBLOB() + + /** + * Convert a text value into a DBMS specific format that is suitable to + * compose query statements. + * + * @param string $value text string value that is intended to be converted. + * @param bool $quote determines if the value should be quoted and escaped + * @param bool $escape_wildcards if to escape escape wildcards + * @return string text string that represents the given argument value in + * a DBMS specific format. + * @access protected + */ + function _quoteBLOB($value, $quote, $escape_wildcards) + { + return 'EMPTY_BLOB()'; + } + + // }}} + // {{{ _quoteDate() + + /** + * Convert a text value into a DBMS specific format that is suitable to + * compose query statements. + * + * @param string $value text string value that is intended to be converted. + * @param bool $quote determines if the value should be quoted and escaped + * @param bool $escape_wildcards if to escape escape wildcards + * @return string text string that represents the given argument value in + * a DBMS specific format. + * @access protected + */ + function _quoteDate($value, $quote, $escape_wildcards) + { + return $this->_quoteText("$value 00:00:00", $quote, $escape_wildcards); + } + + // }}} + // {{{ _quoteTimestamp() + + /** + * Convert a text value into a DBMS specific format that is suitable to + * compose query statements. + * + * @param string $value text string value that is intended to be converted. + * @param bool $quote determines if the value should be quoted and escaped + * @param bool $escape_wildcards if to escape escape wildcards + * @return string text string that represents the given argument value in + * a DBMS specific format. + * @access protected + */ + //function _quoteTimestamp($value, $quote, $escape_wildcards) + //{ + // return $this->_quoteText($value, $quote, $escape_wildcards); + //} + + // }}} + // {{{ _quoteTime() + + /** + * Convert a text value into a DBMS specific format that is suitable to + * compose query statements. + * + * @param string $value text string value that is intended to be converted. + * @param bool $quote determines if the value should be quoted and escaped + * @param bool $escape_wildcards if to escape escape wildcards + * @return string text string that represents the given argument value in + * a DBMS specific format. + * @access protected + */ + function _quoteTime($value, $quote, $escape_wildcards) + { + return $this->_quoteText("0001-01-01 $value", $quote, $escape_wildcards); + } + + // }}} + // {{{ writeLOBToFile() + + /** + * retrieve LOB from the database + * + * @param array $lob array + * @param string $file name of the file into which the LOb should be fetched + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access protected + */ + function writeLOBToFile($lob, $file) + { + if (preg_match('/^(\w+:\/\/)(.*)$/', $file, $match)) { + if ($match[1] == 'file://') { + $file = $match[2]; + } + } + $lob_data = stream_get_meta_data($lob); + $lob_index = $lob_data['wrapper_data']->lob_index; + $result = $this->lobs[$lob_index]['resource']->writetofile($file); + $this->lobs[$lob_index]['resource']->seek(0); + if (!$result) { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + return $db->raiseError(null, null, null, + 'Unable to write LOB to file', __FUNCTION__); + } + return MDB2_OK; + } + + // }}} + // {{{ _retrieveLOB() + + /** + * retrieve LOB from the database + * + * @param array $lob array + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access protected + */ + function _retrieveLOB(&$lob) + { + if (!is_object($lob['resource'])) { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'attemped to retrieve LOB from non existing or NULL column', __FUNCTION__); + } + + if (!$lob['loaded'] +# && !method_exists($lob['resource'], 'read') + ) { + $lob['value'] = $lob['resource']->load(); + $lob['resource']->seek(0); + } + $lob['loaded'] = true; + return MDB2_OK; + } + + // }}} + // {{{ _readLOB() + + /** + * Read data from large object input stream. + * + * @param array $lob array + * @param blob $data reference to a variable that will hold data to be + * read from the large object input stream + * @param int $length integer value that indicates the largest ammount of + * data to be read from the large object input stream. + * @return mixed length on success, a MDB2 error on failure + * @access protected + */ + function _readLOB($lob, $length) + { + if ($lob['loaded']) { + return parent::_readLOB($lob, $length); + } + + if (!is_object($lob['resource'])) { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'attemped to retrieve LOB from non existing or NULL column', __FUNCTION__); + } + + $data = $lob['resource']->read($length); + if (!is_string($data)) { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + return $db->raiseError(null, null, null, + 'Unable to read LOB', __FUNCTION__); + } + return $data; + } + + // }}} + // {{{ patternEscapeString() + + /** + * build string to define escape pattern string + * + * @access public + * + * + * @return string define escape pattern + */ + function patternEscapeString() + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + return " ESCAPE '". $db->string_quoting['escape_pattern'] ."'"; + } + + // }}} + // {{{ _mapNativeDatatype() + + /** + * Maps a native array description of a field to a MDB2 datatype and length + * + * @param array $field native field description + * @return array containing the various possible types, length, sign, fixed + * @access public + */ + function _mapNativeDatatype($field) + { + $db_type = strtolower($field['type']); + $type = array(); + $length = $unsigned = $fixed = null; + if (!empty($field['length'])) { + $length = $field['length']; + } + switch ($db_type) { + case 'integer': + case 'pls_integer': + case 'binary_integer': + $type[] = 'integer'; + if ($length == '1') { + $type[] = 'boolean'; + if (preg_match('/^(is|has)/', $field['name'])) { + $type = array_reverse($type); + } + } + break; + case 'varchar': + case 'varchar2': + case 'nvarchar2': + $fixed = false; + case 'char': + case 'nchar': + $type[] = 'text'; + if ($length == '1') { + $type[] = 'boolean'; + if (preg_match('/^(is|has)/', $field['name'])) { + $type = array_reverse($type); + } + } + if ($fixed !== false) { + $fixed = true; + } + break; + case 'date': + case 'timestamp': + $type[] = 'timestamp'; + $length = null; + break; + case 'float': + $type[] = 'float'; + break; + case 'number': + if (!empty($field['scale'])) { + $type[] = 'decimal'; + $length = $length.','.$field['scale']; + } else { + $type[] = 'integer'; + if ($length == '1') { + $type[] = 'boolean'; + if (preg_match('/^(is|has)/', $field['name'])) { + $type = array_reverse($type); + } + } + } + break; + case 'long': + $type[] = 'text'; + case 'clob': + case 'nclob': + $type[] = 'clob'; + break; + case 'blob': + case 'raw': + case 'long raw': + case 'bfile': + $type[] = 'blob'; + $length = null; + break; + case 'rowid': + case 'urowid': + default: + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'unknown database attribute type: '.$db_type, __FUNCTION__); + } + + if ((int)$length <= 0) { + $length = null; + } + + return array($type, $length, $unsigned, $fixed); + } +} + +?> \ No newline at end of file diff --git a/3rdparty/MDB2/Driver/Function/oci8.php b/3rdparty/MDB2/Driver/Function/oci8.php new file mode 100644 index 0000000000..757d17fcb8 --- /dev/null +++ b/3rdparty/MDB2/Driver/Function/oci8.php @@ -0,0 +1,187 @@ + | +// +----------------------------------------------------------------------+ + +// $Id: oci8.php 295587 2010-02-28 17:16:38Z quipo $ + +require_once 'MDB2/Driver/Function/Common.php'; + +/** + * MDB2 oci8 driver for the function modules + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_Driver_Function_oci8 extends MDB2_Driver_Function_Common +{ + // {{{ executeStoredProc() + + /** + * Execute a stored procedure and return any results + * + * @param string $name string that identifies the function to execute + * @param mixed $params array that contains the paramaters to pass the stored proc + * @param mixed $types array that contains the types of the columns in + * the result set + * @param mixed $result_class string which specifies which result class to use + * @param mixed $result_wrap_class string which specifies which class to wrap results in + * @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = 'EXEC '.$name; + $query .= $params ? '('.implode(', ', $params).')' : '()'; + return $db->query($query, $types, $result_class, $result_wrap_class); + } + + // }}} + // {{{ functionTable() + + /** + * return string for internal table used when calling only a function + * + * @return string for internal table used when calling only a function + * @access public + */ + function functionTable() + { + return ' FROM dual'; + } + + // }}} + // {{{ now() + + /** + * Return string to call a variable with the current timestamp inside an SQL statement + * There are three special variables for current date and time: + * - CURRENT_TIMESTAMP (date and time, TIMESTAMP type) + * - CURRENT_DATE (date, DATE type) + * - CURRENT_TIME (time, TIME type) + * + * @return string to call a variable with the current timestamp + * @access public + */ + function now($type = 'timestamp') + { + switch ($type) { + case 'date': + case 'time': + case 'timestamp': + default: + return 'TO_CHAR(CURRENT_TIMESTAMP, \'YYYY-MM-DD HH24:MI:SS\')'; + } + } + + // }}} + // {{{ unixtimestamp() + + /** + * return string to call a function to get the unix timestamp from a iso timestamp + * + * @param string $expression + * + * @return string to call a variable with the timestamp + * @access public + */ + function unixtimestamp($expression) + { + $utc_offset = 'CAST(SYS_EXTRACT_UTC(SYSTIMESTAMP) AS DATE) - CAST(SYSTIMESTAMP AS DATE)'; + $epoch_date = 'to_date(\'19700101\', \'YYYYMMDD\')'; + return '(CAST('.$expression.' AS DATE) - '.$epoch_date.' + '.$utc_offset.') * 86400 seconds'; + } + + // }}} + // {{{ substring() + + /** + * return string to call a function to get a substring inside an SQL statement + * + * @return string to call a function to get a substring + * @access public + */ + function substring($value, $position = 1, $length = null) + { + if (null !== $length) { + return "SUBSTR($value, $position, $length)"; + } + return "SUBSTR($value, $position)"; + } + + // }}} + // {{{ random() + + /** + * return string to call a function to get random value inside an SQL statement + * + * @return return string to generate float between 0 and 1 + * @access public + */ + function random() + { + return 'dbms_random.value'; + } + + // }}}} + // {{{ guid() + + /** + * Returns global unique identifier + * + * @return string to get global unique identifier + * @access public + */ + function guid() + { + return 'SYS_GUID()'; + } + + // }}}} +} +?> \ No newline at end of file diff --git a/3rdparty/MDB2/Driver/Manager/oci8.php b/3rdparty/MDB2/Driver/Manager/oci8.php new file mode 100644 index 0000000000..90ae8eb230 --- /dev/null +++ b/3rdparty/MDB2/Driver/Manager/oci8.php @@ -0,0 +1,1340 @@ + | +// +----------------------------------------------------------------------+ + +// $Id: oci8.php 295587 2010-02-28 17:16:38Z quipo $ + +require_once 'MDB2/Driver/Manager/Common.php'; + +/** + * MDB2 oci8 driver for the management modules + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_Driver_Manager_oci8 extends MDB2_Driver_Manager_Common +{ + // {{{ createDatabase() + + /** + * create a new database + * + * @param string $name name of the database that should be created + * @param array $options array with charset, collation info + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createDatabase($name, $options = array()) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $username = $db->options['database_name_prefix'].$name; + $password = $db->dsn['password'] ? $db->dsn['password'] : $name; + $tablespace = $db->options['default_tablespace'] + ? ' DEFAULT TABLESPACE '.$db->options['default_tablespace'] : ''; + + $query = 'CREATE USER '.$username.' IDENTIFIED BY '.$password.$tablespace; + $result = $db->standaloneQuery($query, null, true); + if (PEAR::isError($result)) { + return $result; + } + $query = 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO '.$username; + $result = $db->standaloneQuery($query, null, true); + if (PEAR::isError($result)) { + $query = 'DROP USER '.$username.' CASCADE'; + $result2 = $db->standaloneQuery($query, null, true); + if (PEAR::isError($result2)) { + return $db->raiseError($result2, null, null, + 'could not setup the database user', __FUNCTION__); + } + return $result; + } + return MDB2_OK; + } + + // }}} + // {{{ alterDatabase() + + /** + * alter an existing database + * + * IMPORTANT: the safe way to change the db charset is to do a full import/export! + * If - and only if - the new character set is a strict superset of the current + * character set, it is possible to use the ALTER DATABASE CHARACTER SET to + * expedite the change in the database character set. + * + * @param string $name name of the database that is intended to be changed + * @param array $options array with name, charset info + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function alterDatabase($name, $options = array()) + { + //disabled + //return parent::alterDatabase($name, $options); + + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (!empty($options['name'])) { + $query = 'ALTER DATABASE ' . $db->quoteIdentifier($name, true) + .' RENAME GLOBAL_NAME TO ' . $db->quoteIdentifier($options['name'], true); + $result = $db->standaloneQuery($query); + if (PEAR::isError($result)) { + return $result; + } + } + + if (!empty($options['charset'])) { + $queries = array(); + $queries[] = 'SHUTDOWN IMMEDIATE'; //or NORMAL + $queries[] = 'STARTUP MOUNT'; + $queries[] = 'ALTER SYSTEM ENABLE RESTRICTED SESSION'; + $queries[] = 'ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0'; + $queries[] = 'ALTER DATABASE OPEN'; + $queries[] = 'ALTER DATABASE CHARACTER SET ' . $options['charset']; + $queries[] = 'ALTER DATABASE NATIONAL CHARACTER SET ' . $options['charset']; + $queries[] = 'SHUTDOWN IMMEDIATE'; //or NORMAL + $queries[] = 'STARTUP'; + + foreach ($queries as $query) { + $result = $db->standaloneQuery($query); + if (PEAR::isError($result)) { + return $result; + } + } + } + + return MDB2_OK; + } + + // }}} + // {{{ dropDatabase() + + /** + * drop an existing database + * + * @param object $db database object that is extended by this class + * @param string $name name of the database that should be dropped + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropDatabase($name) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $username = $db->options['database_name_prefix'].$name; + return $db->standaloneQuery('DROP USER '.$username.' CASCADE', null, true); + } + + + // }}} + // {{{ _makeAutoincrement() + + /** + * add an autoincrement sequence + trigger + * + * @param string $name name of the PK field + * @param string $table name of the table + * @param string $start start value for the sequence + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access private + */ + function _makeAutoincrement($name, $table, $start = 1) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $table_uppercase = strtoupper($table); + $index_name = $table_uppercase . '_AI_PK'; + $definition = array( + 'primary' => true, + 'fields' => array($name => true), + ); + $idxname_format = $db->getOption('idxname_format'); + $db->setOption('idxname_format', '%s'); + $result = $this->createConstraint($table, $index_name, $definition); + $db->setOption('idxname_format', $idxname_format); + if (PEAR::isError($result)) { + return $db->raiseError($result, null, null, + 'primary key for autoincrement PK could not be created', __FUNCTION__); + } + + if (null === $start) { + $db->beginTransaction(); + $query = 'SELECT MAX(' . $db->quoteIdentifier($name, true) . ') FROM ' . $db->quoteIdentifier($table, true); + $start = $this->db->queryOne($query, 'integer'); + if (PEAR::isError($start)) { + return $start; + } + ++$start; + $result = $this->createSequence($table, $start); + $db->commit(); + } else { + $result = $this->createSequence($table, $start); + } + if (PEAR::isError($result)) { + return $db->raiseError($result, null, null, + 'sequence for autoincrement PK could not be created', __FUNCTION__); + } + $seq_name = $db->getSequenceName($table); + $trigger_name = $db->quoteIdentifier($table_uppercase . '_AI_PK', true); + $seq_name_quoted = $db->quoteIdentifier($seq_name, true); + $table = $db->quoteIdentifier($table, true); + $name = $db->quoteIdentifier($name, true); + $trigger_sql = ' +CREATE TRIGGER '.$trigger_name.' + BEFORE INSERT + ON '.$table.' + FOR EACH ROW +DECLARE + last_Sequence NUMBER; + last_InsertID NUMBER; +BEGIN + SELECT '.$seq_name_quoted.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL; + IF (:NEW.'.$name.' IS NULL OR :NEW.'.$name.' = 0) THEN + SELECT '.$seq_name_quoted.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL; + ELSE + SELECT NVL(Last_Number, 0) INTO last_Sequence + FROM User_Sequences + WHERE UPPER(Sequence_Name) = UPPER(\''.$seq_name.'\'); + SELECT :NEW.'.$name.' INTO last_InsertID FROM DUAL; + WHILE (last_InsertID > last_Sequence) LOOP + SELECT '.$seq_name_quoted.'.NEXTVAL INTO last_Sequence FROM DUAL; + END LOOP; + END IF; +END; +'; + $result = $db->exec($trigger_sql); + if (PEAR::isError($result)) { + return $result; + } + return MDB2_OK; + } + + // }}} + // {{{ _dropAutoincrement() + + /** + * drop an existing autoincrement sequence + trigger + * + * @param string $table name of the table + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access private + */ + function _dropAutoincrement($table) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $table = strtoupper($table); + $trigger_name = $table . '_AI_PK'; + $trigger_name_quoted = $db->quote($trigger_name, 'text'); + $query = 'SELECT trigger_name FROM user_triggers'; + $query.= ' WHERE trigger_name='.$trigger_name_quoted.' OR trigger_name='.strtoupper($trigger_name_quoted); + $trigger = $db->queryOne($query); + if (PEAR::isError($trigger)) { + return $trigger; + } + + if ($trigger) { + $trigger_name = $db->quoteIdentifier($table . '_AI_PK', true); + $trigger_sql = 'DROP TRIGGER ' . $trigger_name; + $result = $db->exec($trigger_sql); + if (PEAR::isError($result)) { + return $db->raiseError($result, null, null, + 'trigger for autoincrement PK could not be dropped', __FUNCTION__); + } + + $result = $this->dropSequence($table); + if (PEAR::isError($result)) { + return $db->raiseError($result, null, null, + 'sequence for autoincrement PK could not be dropped', __FUNCTION__); + } + + $index_name = $table . '_AI_PK'; + $idxname_format = $db->getOption('idxname_format'); + $db->setOption('idxname_format', '%s'); + $result1 = $this->dropConstraint($table, $index_name); + $db->setOption('idxname_format', $idxname_format); + $result2 = $this->dropConstraint($table, $index_name); + if (PEAR::isError($result1) && PEAR::isError($result2)) { + return $db->raiseError($result1, null, null, + 'primary key for autoincrement PK could not be dropped', __FUNCTION__); + } + } + + return MDB2_OK; + } + + // }}} + // {{{ _getTemporaryTableQuery() + + /** + * A method to return the required SQL string that fits between CREATE ... TABLE + * to create the table as a temporary table. + * + * @return string The string required to be placed between "CREATE" and "TABLE" + * to generate a temporary table, if possible. + */ + function _getTemporaryTableQuery() + { + return 'GLOBAL TEMPORARY'; + } + + // }}} + // {{{ _getAdvancedFKOptions() + + /** + * Return the FOREIGN KEY query section dealing with non-standard options + * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... + * + * @param array $definition + * @return string + * @access protected + */ + function _getAdvancedFKOptions($definition) + { + $query = ''; + if (!empty($definition['ondelete']) && (strtoupper($definition['ondelete']) != 'NO ACTION')) { + $query .= ' ON DELETE '.$definition['ondelete']; + } + if (!empty($definition['deferrable'])) { + $query .= ' DEFERRABLE'; + } else { + $query .= ' NOT DEFERRABLE'; + } + if (!empty($definition['initiallydeferred'])) { + $query .= ' INITIALLY DEFERRED'; + } else { + $query .= ' INITIALLY IMMEDIATE'; + } + return $query; + } + + // }}} + // {{{ createTable() + + /** + * create a new table + * + * @param string $name Name of the database that should be created + * @param array $fields Associative array that contains the definition of each field of the new table + * The indexes of the array entries are the names of the fields of the table an + * the array entry values are associative arrays like those that are meant to be + * passed with the field definitions to get[Type]Declaration() functions. + * + * Example + * array( + * + * 'id' => array( + * 'type' => 'integer', + * 'unsigned' => 1 + * 'notnull' => 1 + * 'default' => 0 + * ), + * 'name' => array( + * 'type' => 'text', + * 'length' => 12 + * ), + * 'password' => array( + * 'type' => 'text', + * 'length' => 12 + * ) + * ); + * @param array $options An associative array of table options: + * array( + * 'comment' => 'Foo', + * 'temporary' => true|false, + * ); + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createTable($name, $fields, $options = array()) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + $db->beginNestedTransaction(); + $result = parent::createTable($name, $fields, $options); + if (!PEAR::isError($result)) { + foreach ($fields as $field_name => $field) { + if (!empty($field['autoincrement'])) { + $result = $this->_makeAutoincrement($field_name, $name); + } + } + } + $db->completeNestedTransaction(); + return $result; + } + + // }}} + // {{{ dropTable() + + /** + * drop an existing table + * + * @param string $name name of the table that should be dropped + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropTable($name) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + $db->beginNestedTransaction(); + $result = $this->_dropAutoincrement($name); + if (!PEAR::isError($result)) { + $result = parent::dropTable($name); + } + $db->completeNestedTransaction(); + return $result; + } + + // }}} + // {{{ truncateTable() + + /** + * Truncate an existing table (if the TRUNCATE TABLE syntax is not supported, + * it falls back to a DELETE FROM TABLE query) + * + * @param string $name name of the table that should be truncated + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function truncateTable($name) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $name = $db->quoteIdentifier($name, true); + return $db->exec("TRUNCATE TABLE $name"); + } + + // }}} + // {{{ vacuum() + + /** + * Optimize (vacuum) all the tables in the db (or only the specified table) + * and optionally run ANALYZE. + * + * @param string $table table name (all the tables if empty) + * @param array $options an array with driver-specific options: + * - timeout [int] (in seconds) [mssql-only] + * - analyze [boolean] [pgsql and mysql] + * - full [boolean] [pgsql-only] + * - freeze [boolean] [pgsql-only] + * + * @return mixed MDB2_OK success, a MDB2 error on failure + * @access public + */ + function vacuum($table = null, $options = array()) + { + // not needed in Oracle + return MDB2_OK; + } + + // }}} + // {{{ alterTable() + + /** + * alter an existing table + * + * @param string $name name of the table that is intended to be changed. + * @param array $changes associative array that contains the details of each type + * of change that is intended to be performed. The types of + * changes that are currently supported are defined as follows: + * + * name + * + * New name for the table. + * + * add + * + * Associative array with the names of fields to be added as + * indexes of the array. The value of each entry of the array + * should be set to another associative array with the properties + * of the fields to be added. The properties of the fields should + * be the same as defined by the MDB2 parser. + * + * + * remove + * + * Associative array with the names of fields to be removed as indexes + * of the array. Currently the values assigned to each entry are ignored. + * An empty array should be used for future compatibility. + * + * rename + * + * Associative array with the names of fields to be renamed as indexes + * of the array. The value of each entry of the array should be set to + * another associative array with the entry named name with the new + * field name and the entry named Declaration that is expected to contain + * the portion of the field declaration already in DBMS specific SQL code + * as it is used in the CREATE TABLE statement. + * + * change + * + * Associative array with the names of the fields to be changed as indexes + * of the array. Keep in mind that if it is intended to change either the + * name of a field and any other properties, the change array entries + * should have the new names of the fields as array indexes. + * + * The value of each entry of the array should be set to another associative + * array with the properties of the fields to that are meant to be changed as + * array entries. These entries should be assigned to the new values of the + * respective properties. The properties of the fields should be the same + * as defined by the MDB2 parser. + * + * Example + * array( + * 'name' => 'userlist', + * 'add' => array( + * 'quota' => array( + * 'type' => 'integer', + * 'unsigned' => 1 + * ) + * ), + * 'remove' => array( + * 'file_limit' => array(), + * 'time_limit' => array() + * ), + * 'change' => array( + * 'name' => array( + * 'length' => '20', + * 'definition' => array( + * 'type' => 'text', + * 'length' => 20, + * ), + * ) + * ), + * 'rename' => array( + * 'sex' => array( + * 'name' => 'gender', + * 'definition' => array( + * 'type' => 'text', + * 'length' => 1, + * 'default' => 'M', + * ), + * ) + * ) + * ) + * + * @param boolean $check indicates whether the function should just check if the DBMS driver + * can perform the requested table alterations if the value is true or + * actually perform them otherwise. + * @access public + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + */ + function alterTable($name, $changes, $check) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + foreach ($changes as $change_name => $change) { + switch ($change_name) { + case 'add': + case 'remove': + case 'change': + case 'name': + case 'rename': + break; + default: + return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null, + 'change type "'.$change_name.'" not yet supported', __FUNCTION__); + } + } + + if ($check) { + return MDB2_OK; + } + + $name = $db->quoteIdentifier($name, true); + + if (!empty($changes['add']) && is_array($changes['add'])) { + $fields = array(); + foreach ($changes['add'] as $field_name => $field) { + $fields[] = $db->getDeclaration($field['type'], $field_name, $field); + } + $result = $db->exec("ALTER TABLE $name ADD (". implode(', ', $fields).')'); + if (PEAR::isError($result)) { + return $result; + } + } + + if (!empty($changes['change']) && is_array($changes['change'])) { + $fields = array(); + foreach ($changes['change'] as $field_name => $field) { + //fix error "column to be modified to NOT NULL is already NOT NULL" + if (!array_key_exists('notnull', $field)) { + unset($field['definition']['notnull']); + } + $fields[] = $db->getDeclaration($field['definition']['type'], $field_name, $field['definition']); + } + $result = $db->exec("ALTER TABLE $name MODIFY (". implode(', ', $fields).')'); + if (PEAR::isError($result)) { + return $result; + } + } + + if (!empty($changes['rename']) && is_array($changes['rename'])) { + foreach ($changes['rename'] as $field_name => $field) { + $field_name = $db->quoteIdentifier($field_name, true); + $query = "ALTER TABLE $name RENAME COLUMN $field_name TO ".$db->quoteIdentifier($field['name']); + $result = $db->exec($query); + if (PEAR::isError($result)) { + return $result; + } + } + } + + if (!empty($changes['remove']) && is_array($changes['remove'])) { + $fields = array(); + foreach ($changes['remove'] as $field_name => $field) { + $fields[] = $db->quoteIdentifier($field_name, true); + } + $result = $db->exec("ALTER TABLE $name DROP COLUMN ". implode(', ', $fields)); + if (PEAR::isError($result)) { + return $result; + } + } + + if (!empty($changes['name'])) { + $change_name = $db->quoteIdentifier($changes['name'], true); + $result = $db->exec("ALTER TABLE $name RENAME TO ".$change_name); + if (PEAR::isError($result)) { + return $result; + } + } + + return MDB2_OK; + } + + // }}} + // {{{ _fetchCol() + + /** + * Utility method to fetch and format a column from a resultset + * + * @param resource $result + * @param boolean $fixname (used when listing indices or constraints) + * @return mixed array of names on success, a MDB2 error on failure + * @access private + */ + function _fetchCol($result, $fixname = false) + { + if (PEAR::isError($result)) { + return $result; + } + $col = $result->fetchCol(); + if (PEAR::isError($col)) { + return $col; + } + $result->free(); + + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if ($fixname) { + foreach ($col as $k => $v) { + $col[$k] = $this->_fixIndexName($v); + } + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE + && $db->options['field_case'] == CASE_LOWER + ) { + $col = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $col); + } + return $col; + } + + // }}} + // {{{ listDatabases() + + /** + * list all databases + * + * @return mixed array of database names on success, a MDB2 error on failure + * @access public + */ + function listDatabases() + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (!$db->options['emulate_database']) { + return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'database listing is only supported if the "emulate_database" option is enabled', __FUNCTION__); + } + + if ($db->options['database_name_prefix']) { + $query = 'SELECT SUBSTR(username, '; + $query.= (strlen($db->options['database_name_prefix'])+1); + $query.= ") FROM sys.dba_users WHERE username LIKE '"; + $query.= $db->options['database_name_prefix']."%'"; + } else { + $query = 'SELECT username FROM sys.dba_users'; + } + $result = $db->standaloneQuery($query, array('text'), false); + return $this->_fetchCol($result); + } + + // }}} + // {{{ listUsers() + + /** + * list all users + * + * @return mixed array of user names on success, a MDB2 error on failure + * @access public + */ + function listUsers() + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if ($db->options['emulate_database'] && $db->options['database_name_prefix']) { + $query = 'SELECT SUBSTR(username, '; + $query.= (strlen($db->options['database_name_prefix'])+1); + $query.= ") FROM sys.dba_users WHERE username NOT LIKE '"; + $query.= $db->options['database_name_prefix']."%'"; + } else { + $query = 'SELECT username FROM sys.dba_users'; + } + return $db->queryCol($query); + } + + // }}} + // {{{ listViews() + + /** + * list all views in the current database + * + * @param string owner, the current is default + * @return mixed array of view names on success, a MDB2 error on failure + * @access public + */ + function listViews($owner = null) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT view_name + FROM sys.all_views + WHERE owner=? OR owner=?'; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $result = $stmt->execute(array($owner, strtoupper($owner))); + return $this->_fetchCol($result); + } + + // }}} + // {{{ listFunctions() + + /** + * list all functions in the current database + * + * @param string owner, the current is default + * @return mixed array of function names on success, a MDB2 error on failure + * @access public + */ + function listFunctions($owner = null) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = "SELECT name + FROM sys.all_source + WHERE line = 1 + AND type = 'FUNCTION' + AND (owner=? OR owner=?)"; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $result = $stmt->execute(array($owner, strtoupper($owner))); + return $this->_fetchCol($result); + } + + // }}} + // {{{ listTableTriggers() + + /** + * list all triggers in the database that reference a given table + * + * @param string table for which all referenced triggers should be found + * @return mixed array of trigger names on success, a MDB2 error on failure + * @access public + */ + function listTableTriggers($table = null) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = "SELECT trigger_name + FROM sys.all_triggers + WHERE (table_name=? OR table_name=?) + AND (owner=? OR owner=?)"; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $args = array( + $table, + strtoupper($table), + $owner, + strtoupper($owner), + ); + $result = $stmt->execute($args); + return $this->_fetchCol($result); + } + + // }}} + // {{{ listTables() + + /** + * list all tables in the database + * + * @param string owner, the current is default + * @return mixed array of table names on success, a MDB2 error on failure + * @access public + */ + function listTables($owner = null) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT table_name + FROM sys.all_tables + WHERE owner=? OR owner=?'; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $result = $stmt->execute(array($owner, strtoupper($owner))); + return $this->_fetchCol($result); + } + + // }}} + // {{{ listTableFields() + + /** + * list all fields in a table in the current database + * + * @param string $table name of table that should be used in method + * @return mixed array of field names on success, a MDB2 error on failure + * @access public + */ + function listTableFields($table) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + list($owner, $table) = $this->splitTableSchema($table); + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT column_name + FROM all_tab_columns + WHERE (table_name=? OR table_name=?) + AND (owner=? OR owner=?) + ORDER BY column_id'; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $args = array( + $table, + strtoupper($table), + $owner, + strtoupper($owner), + ); + $result = $stmt->execute($args); + return $this->_fetchCol($result); + } + + // }}} + // {{{ listTableIndexes() + + /** + * list all indexes in a table + * + * @param string $table name of table that should be used in method + * @return mixed array of index names on success, a MDB2 error on failure + * @access public + */ + function listTableIndexes($table) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + list($owner, $table) = $this->splitTableSchema($table); + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT i.index_name name + FROM all_indexes i + LEFT JOIN all_constraints c + ON c.index_name = i.index_name + AND c.owner = i.owner + AND c.table_name = i.table_name + WHERE (i.table_name=? OR i.table_name=?) + AND (i.owner=? OR i.owner=?) + AND c.index_name IS NULL + AND i.generated=' .$db->quote('N', 'text'); + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $args = array( + $table, + strtoupper($table), + $owner, + strtoupper($owner), + ); + $result = $stmt->execute($args); + return $this->_fetchCol($result, true); + } + + // }}} + // {{{ createConstraint() + + /** + * create a constraint on a table + * + * @param string $table name of the table on which the constraint is to be created + * @param string $name name of the constraint to be created + * @param array $definition associative array that defines properties of the constraint to be created. + * Currently, only one property named FIELDS is supported. This property + * is also an associative with the names of the constraint fields as array + * constraints. Each entry of this array is set to another type of associative + * array that specifies properties of the constraint that are specific to + * each field. + * + * Example + * array( + * 'fields' => array( + * 'user_name' => array(), + * 'last_login' => array() + * ) + * ) + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createConstraint($table, $name, $definition) + { + $result = parent::createConstraint($table, $name, $definition); + if (PEAR::isError($result)) { + return $result; + } + if (!empty($definition['foreign'])) { + return $this->_createFKTriggers($table, array($name => $definition)); + } + return MDB2_OK; + } + + // }}} + // {{{ dropConstraint() + + /** + * drop existing constraint + * + * @param string $table name of table that should be used in method + * @param string $name name of the constraint to be dropped + * @param string $primary hint if the constraint is primary + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropConstraint($table, $name, $primary = false) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + //is it a FK constraint? If so, also delete the associated triggers + $db->loadModule('Reverse', null, true); + $definition = $db->reverse->getTableConstraintDefinition($table, $name); + if (!PEAR::isError($definition) && !empty($definition['foreign'])) { + //first drop the FK enforcing triggers + $result = $this->_dropFKTriggers($table, $name, $definition['references']['table']); + if (PEAR::isError($result)) { + return $result; + } + } + + return parent::dropConstraint($table, $name, $primary); + } + + // }}} + // {{{ _createFKTriggers() + + /** + * Create triggers to enforce the FOREIGN KEY constraint on the table + * + * @param string $table table name + * @param array $foreign_keys FOREIGN KEY definitions + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access private + */ + function _createFKTriggers($table, $foreign_keys) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + // create triggers to enforce FOREIGN KEY constraints + if ($db->supports('triggers') && !empty($foreign_keys)) { + $table = $db->quoteIdentifier($table, true); + foreach ($foreign_keys as $fkname => $fkdef) { + if (empty($fkdef)) { + continue; + } + $fkdef['onupdate'] = empty($fkdef['onupdate']) ? $db->options['default_fk_action_onupdate'] : strtoupper($fkdef['onupdate']); + if ('RESTRICT' == $fkdef['onupdate'] || 'NO ACTION' == $fkdef['onupdate']) { + // already handled by default + continue; + } + + $trigger_name = substr(strtolower($fkname.'_pk_upd_trg'), 0, $db->options['max_identifiers_length']); + $table_fields = array_keys($fkdef['fields']); + $referenced_fields = array_keys($fkdef['references']['fields']); + + //create the ON UPDATE trigger on the primary table + $restrict_action = ' IF (SELECT '; + $aliased_fields = array(); + foreach ($table_fields as $field) { + $aliased_fields[] = $table .'.'.$field .' AS '.$field; + } + $restrict_action .= implode(',', $aliased_fields) + .' FROM '.$table + .' WHERE '; + $conditions = array(); + $new_values = array(); + $null_values = array(); + for ($i=0; $iloadModule('Reverse', null, true); + $default_values = array(); + foreach ($table_fields as $table_field) { + $field_definition = $db->reverse->getTableFieldDefinition($table, $field); + if (PEAR::isError($field_definition)) { + return $field_definition; + } + $default_values[] = $table_field .' = '. $field_definition[0]['default']; + } + $setdefault_action = 'UPDATE '.$table.' SET '.implode(', ', $default_values).' WHERE '.implode(' AND ', $conditions). ';'; + } + + $query = 'CREATE TRIGGER %s' + .' %s ON '.$fkdef['references']['table'] + .' FOR EACH ROW ' + .' BEGIN '; + + if ('CASCADE' == $fkdef['onupdate']) { + $sql_update = sprintf($query, $trigger_name, 'BEFORE UPDATE', 'update') . $cascade_action; + } elseif ('SET NULL' == $fkdef['onupdate']) { + $sql_update = sprintf($query, $trigger_name, 'BEFORE UPDATE', 'update') . $setnull_action; + } elseif ('SET DEFAULT' == $fkdef['onupdate']) { + $sql_update = sprintf($query, $trigger_name, 'BEFORE UPDATE', 'update') . $setdefault_action; + } + $sql_update .= ' END;'; + $result = $db->exec($sql_update); + if (PEAR::isError($result)) { + if ($result->getCode() === MDB2_ERROR_ALREADY_EXISTS) { + return MDB2_OK; + } + return $result; + } + } + } + return MDB2_OK; + } + + // }}} + // {{{ _dropFKTriggers() + + /** + * Drop the triggers created to enforce the FOREIGN KEY constraint on the table + * + * @param string $table table name + * @param string $fkname FOREIGN KEY constraint name + * @param string $referenced_table referenced table name + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access private + */ + function _dropFKTriggers($table, $fkname, $referenced_table) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $triggers = $this->listTableTriggers($table); + $triggers2 = $this->listTableTriggers($referenced_table); + if (!PEAR::isError($triggers2) && !PEAR::isError($triggers)) { + $triggers = array_merge($triggers, $triggers2); + $trigger_name = substr(strtolower($fkname.'_pk_upd_trg'), 0, $db->options['max_identifiers_length']); + $pattern = '/^'.$trigger_name.'$/i'; + foreach ($triggers as $trigger) { + if (preg_match($pattern, $trigger)) { + $result = $db->exec('DROP TRIGGER '.$trigger); + if (PEAR::isError($result)) { + return $result; + } + } + } + } + return MDB2_OK; + } + + // }}} + // {{{ listTableConstraints() + + /** + * list all constraints in a table + * + * @param string $table name of table that should be used in method + * @return mixed array of constraint names on success, a MDB2 error on failure + * @access public + */ + function listTableConstraints($table) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + list($owner, $table) = $this->splitTableSchema($table); + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT constraint_name + FROM all_constraints + WHERE (table_name=? OR table_name=?) + AND (owner=? OR owner=?)'; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $args = array( + $table, + strtoupper($table), + $owner, + strtoupper($owner), + ); + $result = $stmt->execute($args); + return $this->_fetchCol($result, true); + } + + // }}} + // {{{ createSequence() + + /** + * create sequence + * + * @param object $db database object that is extended by this class + * @param string $seq_name name of the sequence to be created + * @param string $start start value of the sequence; default is 1 + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createSequence($seq_name, $start = 1) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true); + $query = "CREATE SEQUENCE $sequence_name START WITH $start INCREMENT BY 1 NOCACHE"; + $query.= ($start < 1 ? " MINVALUE $start" : ''); + return $db->exec($query); + } + + // }}} + // {{{ dropSequence() + + /** + * drop existing sequence + * + * @param object $db database object that is extended by this class + * @param string $seq_name name of the sequence to be dropped + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropSequence($seq_name) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true); + return $db->exec("DROP SEQUENCE $sequence_name"); + } + + // }}} + // {{{ listSequences() + + /** + * list all sequences in the current database + * + * @param string owner, the current is default + * @return mixed array of sequence names on success, a MDB2 error on failure + * @access public + */ + function listSequences($owner = null) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT sequence_name + FROM sys.all_sequences + WHERE (sequence_owner=? OR sequence_owner=?)'; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $result = $stmt->execute(array($owner, strtoupper($owner))); + if (PEAR::isError($result)) { + return $result; + } + $col = $result->fetchCol(); + if (PEAR::isError($col)) { + return $col; + } + $result->free(); + + foreach ($col as $k => $v) { + $col[$k] = $this->_fixSequenceName($v); + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE + && $db->options['field_case'] == CASE_LOWER + ) { + $col = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $col); + } + return $col; + } +} +?> \ No newline at end of file diff --git a/3rdparty/MDB2/Driver/Native/oci8.php b/3rdparty/MDB2/Driver/Native/oci8.php new file mode 100644 index 0000000000..d198f9687a --- /dev/null +++ b/3rdparty/MDB2/Driver/Native/oci8.php @@ -0,0 +1,60 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: oci8.php 215004 2006-06-18 21:59:05Z lsmith $ +// + +require_once 'MDB2/Driver/Native/Common.php'; + +/** + * MDB2 Oracle driver for the native module + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_Driver_Native_oci8 extends MDB2_Driver_Native_Common +{ +} +?> \ No newline at end of file diff --git a/3rdparty/MDB2/Driver/Reverse/oci8.php b/3rdparty/MDB2/Driver/Reverse/oci8.php new file mode 100644 index 0000000000..d89ad77137 --- /dev/null +++ b/3rdparty/MDB2/Driver/Reverse/oci8.php @@ -0,0 +1,625 @@ + | +// | Lorenzo Alberton | +// +----------------------------------------------------------------------+ +// +// $Id: oci8.php 295587 2010-02-28 17:16:38Z quipo $ +// + +require_once 'MDB2/Driver/Reverse/Common.php'; + +/** + * MDB2 Oracle driver for the schema reverse engineering module + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_Driver_Reverse_oci8 extends MDB2_Driver_Reverse_Common +{ + // {{{ getTableFieldDefinition() + + /** + * Get the structure of a field into an array + * + * @param string $table_name name of table that should be used in method + * @param string $field_name name of field that should be used in method + * @return mixed data array on success, a MDB2 error on failure + * @access public + */ + function getTableFieldDefinition($table_name, $field_name) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $result = $db->loadModule('Datatype', null, true); + if (PEAR::isError($result)) { + return $result; + } + + list($owner, $table) = $this->splitTableSchema($table_name); + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT column_name AS "name", + data_type AS "type", + nullable AS "nullable", + data_default AS "default", + COALESCE(data_precision, data_length) AS "length", + data_scale AS "scale" + FROM all_tab_columns + WHERE (table_name=? OR table_name=?) + AND (owner=? OR owner=?) + AND (column_name=? OR column_name=?) + ORDER BY column_id'; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $args = array( + $table, + strtoupper($table), + $owner, + strtoupper($owner), + $field_name, + strtoupper($field_name) + ); + $result = $stmt->execute($args); + if (PEAR::isError($result)) { + return $result; + } + $column = $result->fetchRow(MDB2_FETCHMODE_ASSOC); + if (PEAR::isError($column)) { + return $column; + } + $stmt->free(); + $result->free(); + + if (empty($column)) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + $field_name . ' is not a column in table ' . $table_name, __FUNCTION__); + } + + $column = array_change_key_case($column, CASE_LOWER); + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $column['name'] = strtolower($column['name']); + } else { + $column['name'] = strtoupper($column['name']); + } + } + $mapped_datatype = $db->datatype->mapNativeDatatype($column); + if (PEAR::isError($mapped_datatype)) { + return $mapped_datatype; + } + list($types, $length, $unsigned, $fixed) = $mapped_datatype; + $notnull = false; + if (!empty($column['nullable']) && $column['nullable'] == 'N') { + $notnull = true; + } + $default = false; + if (array_key_exists('default', $column)) { + $default = $column['default']; + if ($default === 'NULL') { + $default = null; + } + //ugly hack, but works for the reverse direction + if ($default == "''") { + $default = ''; + } + if ((null === $default) && $notnull) { + $default = ''; + } + } + + $definition[0] = array('notnull' => $notnull, 'nativetype' => $column['type']); + if (null !== $length) { + $definition[0]['length'] = $length; + } + if (null !== $unsigned) { + $definition[0]['unsigned'] = $unsigned; + } + if (null !== $fixed) { + $definition[0]['fixed'] = $fixed; + } + if ($default !== false) { + $definition[0]['default'] = $default; + } + foreach ($types as $key => $type) { + $definition[$key] = $definition[0]; + if ($type == 'clob' || $type == 'blob') { + unset($definition[$key]['default']); + } + $definition[$key]['type'] = $type; + $definition[$key]['mdb2type'] = $type; + } + if ($type == 'integer') { + $query= "SELECT trigger_body + FROM all_triggers + WHERE table_name=? + AND triggering_event='INSERT' + AND trigger_type='BEFORE EACH ROW'"; + // ^^ pretty reasonable mimic for "auto_increment" in oracle? + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $result = $stmt->execute(strtoupper($table)); + if (PEAR::isError($result)) { + return $result; + } + while ($triggerstr = $result->fetchOne()) { + if (preg_match('/.*SELECT\W+(.+)\.nextval +into +\:NEW\.'.$field_name.' +FROM +dual/im', $triggerstr, $matches)) { + $definition[0]['autoincrement'] = $matches[1]; + } + } + $stmt->free(); + $result->free(); + } + return $definition; + } + + // }}} + // {{{ getTableIndexDefinition() + + /** + * Get the structure of an index into an array + * + * @param string $table_name name of table that should be used in method + * @param string $index_name name of index that should be used in method + * @return mixed data array on success, a MDB2 error on failure + * @access public + */ + function getTableIndexDefinition($table_name, $index_name) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + list($owner, $table) = $this->splitTableSchema($table_name); + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT aic.column_name AS "column_name", + aic.column_position AS "column_position", + aic.descend AS "descend", + aic.table_owner AS "table_owner", + alc.constraint_type AS "constraint_type" + FROM all_ind_columns aic + LEFT JOIN all_constraints alc + ON aic.index_name = alc.constraint_name + AND aic.table_name = alc.table_name + AND aic.table_owner = alc.owner + WHERE (aic.table_name=? OR aic.table_name=?) + AND (aic.index_name=? OR aic.index_name=?) + AND (aic.table_owner=? OR aic.table_owner=?) + ORDER BY column_position'; + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + $indexnames = array_unique(array($db->getIndexName($index_name), $index_name)); + $i = 0; + $row = null; + while ((null === $row) && array_key_exists($i, $indexnames)) { + $args = array( + $table, + strtoupper($table), + $indexnames[$i], + strtoupper($indexnames[$i]), + $owner, + strtoupper($owner) + ); + $result = $stmt->execute($args); + if (PEAR::isError($result)) { + return $result; + } + $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC); + if (PEAR::isError($row)) { + return $row; + } + $i++; + } + if (null === $row) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + $index_name. ' is not an index on table '. $table_name, __FUNCTION__); + } + if ($row['constraint_type'] == 'U' || $row['constraint_type'] == 'P') { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + $index_name. ' is a constraint, not an index on table '. $table_name, __FUNCTION__); + } + + $definition = array(); + while (null !== $row) { + $row = array_change_key_case($row, CASE_LOWER); + $column_name = $row['column_name']; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $column_name = strtolower($column_name); + } else { + $column_name = strtoupper($column_name); + } + } + $definition['fields'][$column_name] = array( + 'position' => (int)$row['column_position'], + ); + if (!empty($row['descend'])) { + $definition['fields'][$column_name]['sorting'] = + ($row['descend'] == 'ASC' ? 'ascending' : 'descending'); + } + $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC); + } + $result->free(); + if (empty($definition['fields'])) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + $index_name. ' is not an index on table '. $table_name, __FUNCTION__); + } + return $definition; + } + + // }}} + // {{{ getTableConstraintDefinition() + + /** + * Get the structure of a constraint into an array + * + * @param string $table_name name of table that should be used in method + * @param string $constraint_name name of constraint that should be used in method + * @return mixed data array on success, a MDB2 error on failure + * @access public + */ + function getTableConstraintDefinition($table_name, $constraint_name) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + list($owner, $table) = $this->splitTableSchema($table_name); + if (empty($owner)) { + $owner = $db->dsn['username']; + } + + $query = 'SELECT alc.constraint_name, + CASE alc.constraint_type WHEN \'P\' THEN 1 ELSE 0 END "primary", + CASE alc.constraint_type WHEN \'R\' THEN 1 ELSE 0 END "foreign", + CASE alc.constraint_type WHEN \'U\' THEN 1 ELSE 0 END "unique", + CASE alc.constraint_type WHEN \'C\' THEN 1 ELSE 0 END "check", + alc.DELETE_RULE "ondelete", + \'NO ACTION\' "onupdate", + \'SIMPLE\' "match", + CASE alc.deferrable WHEN \'NOT DEFERRABLE\' THEN 0 ELSE 1 END "deferrable", + CASE alc.deferred WHEN \'IMMEDIATE\' THEN 0 ELSE 1 END "initiallydeferred", + alc.search_condition AS "search_condition", + alc.table_name, + cols.column_name AS "column_name", + cols.position, + r_alc.table_name "references_table", + r_cols.column_name "references_field", + r_cols.position "references_field_position" + FROM all_cons_columns cols + LEFT JOIN all_constraints alc + ON alc.constraint_name = cols.constraint_name + AND alc.owner = cols.owner + LEFT JOIN all_constraints r_alc + ON alc.r_constraint_name = r_alc.constraint_name + AND alc.r_owner = r_alc.owner + LEFT JOIN all_cons_columns r_cols + ON r_alc.constraint_name = r_cols.constraint_name + AND r_alc.owner = r_cols.owner + AND cols.position = r_cols.position + WHERE (alc.constraint_name=? OR alc.constraint_name=?) + AND alc.constraint_name = cols.constraint_name + AND (alc.owner=? OR alc.owner=?)'; + $tablenames = array(); + if (!empty($table)) { + $query.= ' AND (alc.table_name=? OR alc.table_name=?)'; + $tablenames = array($table, strtoupper($table)); + } + $stmt = $db->prepare($query); + if (PEAR::isError($stmt)) { + return $stmt; + } + + $constraintnames = array_unique(array($db->getIndexName($constraint_name), $constraint_name)); + $c = 0; + $row = null; + while ((null === $row) && array_key_exists($c, $constraintnames)) { + $args = array( + $constraintnames[$c], + strtoupper($constraintnames[$c]), + $owner, + strtoupper($owner) + ); + if (!empty($table)) { + $args = array_merge($args, $tablenames); + } + $result = $stmt->execute($args); + if (PEAR::isError($result)) { + return $result; + } + $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC); + if (PEAR::isError($row)) { + return $row; + } + $c++; + } + + $definition = array( + 'primary' => (boolean)$row['primary'], + 'unique' => (boolean)$row['unique'], + 'foreign' => (boolean)$row['foreign'], + 'check' => (boolean)$row['check'], + 'deferrable' => (boolean)$row['deferrable'], + 'initiallydeferred' => (boolean)$row['initiallydeferred'], + 'ondelete' => $row['ondelete'], + 'onupdate' => $row['onupdate'], + 'match' => $row['match'], + ); + + if ($definition['check']) { + // pattern match constraint for check constraint values into enum-style output: + $enumregex = '/'.$row['column_name'].' in \((.+?)\)/i'; + if (preg_match($enumregex, $row['search_condition'], $rangestr)) { + $definition['fields'][$column_name] = array(); + $allowed = explode(',', $rangestr[1]); + foreach ($allowed as $val) { + $val = trim($val); + $val = preg_replace('/^\'/', '', $val); + $val = preg_replace('/\'$/', '', $val); + array_push($definition['fields'][$column_name], $val); + } + } + } + + while (null !== $row) { + $row = array_change_key_case($row, CASE_LOWER); + $column_name = $row['column_name']; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $column_name = strtolower($column_name); + } else { + $column_name = strtoupper($column_name); + } + } + $definition['fields'][$column_name] = array( + 'position' => (int)$row['position'] + ); + if ($row['foreign']) { + $ref_column_name = $row['references_field']; + $ref_table_name = $row['references_table']; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $ref_column_name = strtolower($ref_column_name); + $ref_table_name = strtolower($ref_table_name); + } else { + $ref_column_name = strtoupper($ref_column_name); + $ref_table_name = strtoupper($ref_table_name); + } + } + $definition['references']['table'] = $ref_table_name; + $definition['references']['fields'][$ref_column_name] = array( + 'position' => (int)$row['references_field_position'] + ); + } + $lastrow = $row; + $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC); + } + $result->free(); + if (empty($definition['fields'])) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + $constraint_name . ' is not a constraint on table '. $table_name, __FUNCTION__); + } + + return $definition; + } + + // }}} + // {{{ getSequenceDefinition() + + /** + * Get the structure of a sequence into an array + * + * @param string $sequence name of sequence that should be used in method + * @return mixed data array on success, a MDB2 error on failure + * @access public + */ + function getSequenceDefinition($sequence) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $sequence_name = $db->getSequenceName($sequence); + $query = 'SELECT last_number FROM user_sequences'; + $query.= ' WHERE sequence_name='.$db->quote($sequence_name, 'text'); + $query.= ' OR sequence_name='.$db->quote(strtoupper($sequence_name), 'text'); + $start = $db->queryOne($query, 'integer'); + if (PEAR::isError($start)) { + return $start; + } + $definition = array(); + if ($start != 1) { + $definition = array('start' => $start); + } + return $definition; + } + + // }}} + // {{{ getTriggerDefinition() + + /** + * Get the structure of a trigger into an array + * + * EXPERIMENTAL + * + * WARNING: this function is experimental and may change the returned value + * at any time until labelled as non-experimental + * + * @param string $trigger name of trigger that should be used in method + * @return mixed data array on success, a MDB2 error on failure + * @access public + */ + function getTriggerDefinition($trigger) + { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = 'SELECT trigger_name AS "trigger_name", + table_name AS "table_name", + trigger_body AS "trigger_body", + trigger_type AS "trigger_type", + triggering_event AS "trigger_event", + description AS "trigger_comment", + 1 AS "trigger_enabled", + when_clause AS "when_clause" + FROM user_triggers + WHERE trigger_name = \''. strtoupper($trigger).'\''; + $types = array( + 'trigger_name' => 'text', + 'table_name' => 'text', + 'trigger_body' => 'text', + 'trigger_type' => 'text', + 'trigger_event' => 'text', + 'trigger_comment' => 'text', + 'trigger_enabled' => 'boolean', + 'when_clause' => 'text', + ); + $result = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC); + if (PEAR::isError($result)) { + return $result; + } + if (!empty($result['trigger_type'])) { + //$result['trigger_type'] = array_shift(explode(' ', $result['trigger_type'])); + $result['trigger_type'] = preg_replace('/(\S+).*/', '\\1', $result['trigger_type']); + } + return $result; + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table or a result set + * + * NOTE: only supports 'table' and 'flags' if $result + * is a table name. + * + * NOTE: flags won't contain index information. + * + * @param object|string $result MDB2_result object from a query or a + * string containing the name of a table. + * While this also accepts a query result + * resource identifier, this behavior is + * deprecated. + * @param int $mode a valid tableInfo mode + * + * @return array an associative array with the information requested. + * A MDB2_Error object on failure. + * + * @see MDB2_Driver_Common::tableInfo() + */ + function tableInfo($result, $mode = null) + { + if (is_string($result)) { + return parent::tableInfo($result, $mode); + } + + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $resource = MDB2::isResultCommon($result) ? $result->getResource() : $result; + if (!is_resource($resource)) { + return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'Could not generate result resource', __FUNCTION__); + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $case_func = 'strtolower'; + } else { + $case_func = 'strtoupper'; + } + } else { + $case_func = 'strval'; + } + + $count = @OCINumCols($resource); + $res = array(); + + if ($mode) { + $res['num_fields'] = $count; + } + + $db->loadModule('Datatype', null, true); + for ($i = 0; $i < $count; $i++) { + $column = array( + 'table' => '', + 'name' => $case_func(@OCIColumnName($resource, $i+1)), + 'type' => @OCIColumnType($resource, $i+1), + 'length' => @OCIColumnSize($resource, $i+1), + 'flags' => '', + ); + $res[$i] = $column; + $res[$i]['mdb2type'] = $db->datatype->mapNativeDatatype($res[$i]); + if ($mode & MDB2_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & MDB2_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + return $res; + } +} +?> \ No newline at end of file diff --git a/3rdparty/MDB2/Driver/mysql.php b/3rdparty/MDB2/Driver/mysql.php index 3008bd04f0..1d22e61f46 100644 --- a/3rdparty/MDB2/Driver/mysql.php +++ b/3rdparty/MDB2/Driver/mysql.php @@ -80,7 +80,7 @@ class MDB2_Driver_mysql extends MDB2_Driver_Common protected $start_transaction = false; - protected $varchar_max_length = 255; + public $varchar_max_length = 255; // }}} // {{{ constructor diff --git a/3rdparty/MDB2/Driver/oci8.php b/3rdparty/MDB2/Driver/oci8.php new file mode 100644 index 0000000000..a1eefc94d1 --- /dev/null +++ b/3rdparty/MDB2/Driver/oci8.php @@ -0,0 +1,1700 @@ + | +// +----------------------------------------------------------------------+ + +// $Id: oci8.php 295587 2010-02-28 17:16:38Z quipo $ + +/** + * MDB2 OCI8 driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_Driver_oci8 extends MDB2_Driver_Common +{ + // {{{ properties + var $string_quoting = array('start' => "'", 'end' => "'", 'escape' => "'", 'escape_pattern' => '@'); + + var $identifier_quoting = array('start' => '"', 'end' => '"', 'escape' => '"'); + + var $uncommitedqueries = 0; + // }}} + // {{{ constructor + + /** + * Constructor + */ + function __construct() + { + parent::__construct(); + + $this->phptype = 'oci8'; + $this->dbsyntax = 'oci8'; + + $this->supported['sequences'] = true; + $this->supported['indexes'] = true; + $this->supported['summary_functions'] = true; + $this->supported['order_by_text'] = true; + $this->supported['current_id'] = true; + $this->supported['affected_rows'] = true; + $this->supported['transactions'] = true; + $this->supported['savepoints'] = true; + $this->supported['limit_queries'] = true; + $this->supported['LOBs'] = true; + $this->supported['replace'] = 'emulated'; + $this->supported['sub_selects'] = true; + $this->supported['triggers'] = true; + $this->supported['auto_increment'] = false; // implementation is broken + $this->supported['primary_key'] = true; + $this->supported['result_introspection'] = true; + $this->supported['prepared_statements'] = true; + $this->supported['identifier_quoting'] = true; + $this->supported['pattern_escaping'] = true; + $this->supported['new_link'] = true; + + $this->options['DBA_username'] = false; + $this->options['DBA_password'] = false; + $this->options['database_name_prefix'] = false; + $this->options['emulate_database'] = true; + $this->options['default_tablespace'] = false; + $this->options['default_text_field_length'] = 2000; + $this->options['lob_allow_url_include'] = false; + $this->options['result_prefetching'] = false; + $this->options['max_identifiers_length'] = 30; + } + + // }}} + // {{{ errorInfo() + + /** + * This method is used to collect information about an error + * + * @param integer $error + * @return array + * @access public + */ + function errorInfo($error = null) + { + if (is_resource($error)) { + $error_data = @OCIError($error); + $error = null; + } elseif ($this->connection) { + $error_data = @OCIError($this->connection); + } else { + $error_data = @OCIError(); + } + $native_code = $error_data['code']; + $native_msg = $error_data['message']; + if (null === $error) { + static $ecode_map; + if (empty($ecode_map)) { + $ecode_map = array( + 1 => MDB2_ERROR_CONSTRAINT, + 900 => MDB2_ERROR_SYNTAX, + 904 => MDB2_ERROR_NOSUCHFIELD, + 911 => MDB2_ERROR_SYNTAX, //invalid character + 913 => MDB2_ERROR_VALUE_COUNT_ON_ROW, + 921 => MDB2_ERROR_SYNTAX, + 923 => MDB2_ERROR_SYNTAX, + 942 => MDB2_ERROR_NOSUCHTABLE, + 955 => MDB2_ERROR_ALREADY_EXISTS, + 1400 => MDB2_ERROR_CONSTRAINT_NOT_NULL, + 1401 => MDB2_ERROR_INVALID, + 1407 => MDB2_ERROR_CONSTRAINT_NOT_NULL, + 1418 => MDB2_ERROR_NOT_FOUND, + 1435 => MDB2_ERROR_NOT_FOUND, + 1476 => MDB2_ERROR_DIVZERO, + 1722 => MDB2_ERROR_INVALID_NUMBER, + 2289 => MDB2_ERROR_NOSUCHTABLE, + 2291 => MDB2_ERROR_CONSTRAINT, + 2292 => MDB2_ERROR_CONSTRAINT, + 2449 => MDB2_ERROR_CONSTRAINT, + 4081 => MDB2_ERROR_ALREADY_EXISTS, //trigger already exists + 24344 => MDB2_ERROR_SYNTAX, //success with compilation error + ); + } + if (isset($ecode_map[$native_code])) { + $error = $ecode_map[$native_code]; + } + } + return array($error, $native_code, $native_msg); + } + + // }}} + // {{{ beginTransaction() + + /** + * Start a transaction or set a savepoint. + * + * @param string name of a savepoint to set + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function beginTransaction($savepoint = null) + { + $this->debug('Starting transaction/savepoint', __FUNCTION__, array('is_manip' => true, 'savepoint' => $savepoint)); + if (null !== $savepoint) { + if (!$this->in_transaction) { + return $this->raiseError(MDB2_ERROR_INVALID, null, null, + 'savepoint cannot be released when changes are auto committed', __FUNCTION__); + } + $query = 'SAVEPOINT '.$savepoint; + return $this->_doQuery($query, true); + } + if ($this->in_transaction) { + return MDB2_OK; //nothing to do + } + if (!$this->destructor_registered && $this->opened_persistent) { + $this->destructor_registered = true; + register_shutdown_function('MDB2_closeOpenTransactions'); + } + $this->in_transaction = true; + ++$this->uncommitedqueries; + return MDB2_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit the database changes done during a transaction that is in + * progress or release a savepoint. This function may only be called when + * auto-committing is disabled, otherwise it will fail. Therefore, a new + * transaction is implicitly started after committing the pending changes. + * + * @param string name of a savepoint to release + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function commit($savepoint = null) + { + $this->debug('Committing transaction/savepoint', __FUNCTION__, array('is_manip' => true, 'savepoint' => $savepoint)); + if (!$this->in_transaction) { + return $this->raiseError(MDB2_ERROR_INVALID, null, null, + 'commit/release savepoint cannot be done changes are auto committed', __FUNCTION__); + } + if (null !== $savepoint) { + return MDB2_OK; + } + + if ($this->uncommitedqueries) { + $connection = $this->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + if (!@OCICommit($connection)) { + return $this->raiseError(null, null, null, + 'Unable to commit transaction', __FUNCTION__); + } + $this->uncommitedqueries = 0; + } + $this->in_transaction = false; + return MDB2_OK; + } + + // }}} + // {{{ rollback() + + /** + * Cancel any database changes done during a transaction or since a specific + * savepoint that is in progress. This function may only be called when + * auto-committing is disabled, otherwise it will fail. Therefore, a new + * transaction is implicitly started after canceling the pending changes. + * + * @param string name of a savepoint to rollback to + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function rollback($savepoint = null) + { + $this->debug('Rolling back transaction/savepoint', __FUNCTION__, array('is_manip' => true, 'savepoint' => $savepoint)); + if (!$this->in_transaction) { + return $this->raiseError(MDB2_ERROR_INVALID, null, null, + 'rollback cannot be done changes are auto committed', __FUNCTION__); + } + if (null !== $savepoint) { + $query = 'ROLLBACK TO SAVEPOINT '.$savepoint; + return $this->_doQuery($query, true); + } + + if ($this->uncommitedqueries) { + $connection = $this->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + if (!@OCIRollback($connection)) { + return $this->raiseError(null, null, null, + 'Unable to rollback transaction', __FUNCTION__); + } + $this->uncommitedqueries = 0; + } + $this->in_transaction = false; + return MDB2_OK; + } + + // }}} + // {{{ function setTransactionIsolation() + + /** + * Set the transacton isolation level. + * + * @param string standard isolation level + * READ UNCOMMITTED (allows dirty reads) + * READ COMMITTED (prevents dirty reads) + * REPEATABLE READ (prevents nonrepeatable reads) + * SERIALIZABLE (prevents phantom reads) + * @param array some transaction options: + * 'wait' => 'WAIT' | 'NO WAIT' + * 'rw' => 'READ WRITE' | 'READ ONLY' + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + * @since 2.1.1 + */ + function setTransactionIsolation($isolation, $options = array()) + { + $this->debug('Setting transaction isolation level', __FUNCTION__, array('is_manip' => true)); + switch ($isolation) { + case 'READ UNCOMMITTED': + $isolation = 'READ COMMITTED'; + case 'READ COMMITTED': + case 'REPEATABLE READ': + $isolation = 'SERIALIZABLE'; + case 'SERIALIZABLE': + break; + default: + return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'isolation level is not supported: '.$isolation, __FUNCTION__); + } + + $query = "ALTER SESSION ISOLATION LEVEL $isolation"; + return $this->_doQuery($query, true); + } + + // }}} + // {{{ _doConnect() + + /** + * do the grunt work of the connect + * + * @return connection on success or MDB2 Error Object on failure + * @access protected + */ + function _doConnect($username, $password, $persistent = false) + { + if (!PEAR::loadExtension($this->phptype)) { + return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'extension '.$this->phptype.' is not compiled into PHP', __FUNCTION__); + } + + $sid = ''; + + if (!empty($this->dsn['service']) && $this->dsn['hostspec']) { + //oci8://username:password@foo.example.com[:port]/?service=service + // service name is given, it is assumed that hostspec is really a + // hostname, we try to construct an oracle connection string from this + $port = $this->dsn['port'] ? $this->dsn['port'] : 1521; + $sid = sprintf("(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP) + (HOST=%s) (PORT=%s))) + (CONNECT_DATA=(SERVICE_NAME=%s)))", + $this->dsn['hostspec'], + $port, + $this->dsn['service'] + ); + } elseif ($this->dsn['hostspec']) { + // we are given something like 'oci8://username:password@foo/' + // we have hostspec but not a service name, now we assume that + // hostspec is a tnsname defined in tnsnames.ora + $sid = $this->dsn['hostspec']; + if (isset($this->dsn['port']) && $this->dsn['port']) { + $sid = $sid.':'.$this->dsn['port']; + } + } else { + // oci://username:password@ + // if everything fails, we have to rely on environment variables + // not before a check to 'emulate_database' + if (!$this->options['emulate_database'] && $this->database_name) { + $sid = $this->database_name; + } elseif (getenv('ORACLE_SID')) { + $sid = getenv('ORACLE_SID'); + } elseif ($sid = getenv('TWO_TASK')) { + $sid = getenv('TWO_TASK'); + } else { + return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'not a valid connection string or environment variable [ORACLE_SID|TWO_TASK] not set', + __FUNCTION__); + } + } + + if (function_exists('oci_connect')) { + if ($this->_isNewLinkSet()) { + $connect_function = 'oci_new_connect'; + } else { + $connect_function = $persistent ? 'oci_pconnect' : 'oci_connect'; + } + + $charset = empty($this->dsn['charset']) ? null : $this->dsn['charset']; + $session_mode = empty($this->dsn['session_mode']) ? null : $this->dsn['session_mode']; + $connection = @$connect_function($username, $password, $sid, $charset, $session_mode); + $error = @OCIError(); + if (isset($error['code']) && $error['code'] == 12541) { + // Couldn't find TNS listener. Try direct connection. + $connection = @$connect_function($username, $password, null, $charset); + } + } else { + $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; + $connection = @$connect_function($username, $password, $sid); + + if (!empty($this->dsn['charset'])) { + $result = $this->setCharset($this->dsn['charset'], $connection); + if (PEAR::isError($result)) { + return $result; + } + } + } + + if (!$connection) { + return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null, + 'unable to establish a connection', __FUNCTION__); + } + + if (empty($this->dsn['disable_iso_date'])) { + $query = "ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'"; + $err = $this->_doQuery($query, true, $connection); + if (PEAR::isError($err)) { + $this->disconnect(false); + return $err; + } + } + + $query = "ALTER SESSION SET NLS_NUMERIC_CHARACTERS='. '"; + $err = $this->_doQuery($query, true, $connection); + if (PEAR::isError($err)) { + $this->disconnect(false); + return $err; + } + + return $connection; + } + + // }}} + // {{{ connect() + + /** + * Connect to the database + * + * @return MDB2_OK on success, MDB2 Error Object on failure + * @access public + */ + function connect() + { + if (is_resource($this->connection)) { + //if (count(array_diff($this->connected_dsn, $this->dsn)) == 0 + if (MDB2::areEquals($this->connected_dsn, $this->dsn) + && $this->opened_persistent == $this->options['persistent'] + ) { + return MDB2_OK; + } + $this->disconnect(false); + } + + if ($this->database_name && $this->options['emulate_database']) { + $this->dsn['username'] = $this->options['database_name_prefix'].$this->database_name; + } + + $connection = $this->_doConnect($this->dsn['username'], + $this->dsn['password'], + $this->options['persistent']); + if (PEAR::isError($connection)) { + return $connection; + } + $this->connection = $connection; + $this->connected_dsn = $this->dsn; + $this->connected_database_name = ''; + $this->opened_persistent = $this->options['persistent']; + $this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype; + + if ($this->database_name) { + if ($this->database_name != $this->connected_database_name) { + $query = 'ALTER SESSION SET CURRENT_SCHEMA = "' .strtoupper($this->database_name) .'"'; + $result = $this->_doQuery($query); + if (PEAR::isError($result)) { + $err = $this->raiseError($result, null, null, + 'Could not select the database: '.$this->database_name, __FUNCTION__); + return $err; + } + $this->connected_database_name = $this->database_name; + } + } + + $this->as_keyword = ' '; + $server_info = $this->getServerVersion(); + if (is_array($server_info)) { + if ($server_info['major'] >= '10') { + $this->as_keyword = ' AS '; + } + } + return MDB2_OK; + } + + // }}} + // {{{ databaseExists() + + /** + * check if given database name is exists? + * + * @param string $name name of the database that should be checked + * + * @return mixed true/false on success, a MDB2 error on failure + * @access public + */ + function databaseExists($name) + { + $connection = $this->_doConnect($this->dsn['username'], + $this->dsn['password'], + $this->options['persistent']); + if (PEAR::isError($connection)) { + return $connection; + } + + $query = 'ALTER SESSION SET CURRENT_SCHEMA = "' .strtoupper($name) .'"'; + $result = $this->_doQuery($query, true, $connection, false); + if (PEAR::isError($result)) { + if (!MDB2::isError($result, MDB2_ERROR_NOT_FOUND)) { + return $result; + } + return false; + } + return true; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @param boolean $force if the disconnect should be forced even if the + * connection is opened persistently + * @return mixed true on success, false if not connected and error + * object on error + * @access public + */ + function disconnect($force = true) + { + if (is_resource($this->connection)) { + if ($this->in_transaction) { + $dsn = $this->dsn; + $database_name = $this->database_name; + $persistent = $this->options['persistent']; + $this->dsn = $this->connected_dsn; + $this->database_name = $this->connected_database_name; + $this->options['persistent'] = $this->opened_persistent; + $this->rollback(); + $this->dsn = $dsn; + $this->database_name = $database_name; + $this->options['persistent'] = $persistent; + } + + if (!$this->opened_persistent || $force) { + $ok = false; + if (function_exists('oci_close')) { + $ok = @oci_close($this->connection); + } else { + $ok = @OCILogOff($this->connection); + } + if (!$ok) { + return $this->raiseError(MDB2_ERROR_DISCONNECT_FAILED, + null, null, null, __FUNCTION__); + } + } + $this->uncommitedqueries = 0; + } else { + return false; + } + return parent::disconnect($force); + } + + // }}} + // {{{ standaloneQuery() + + /** + * execute a query as DBA + * + * @param string $query the SQL query + * @param mixed $types array containing the types of the columns in + * the result set + * @param boolean $is_manip if the query is a manipulation query + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function standaloneQuery($query, $types = null, $is_manip = false) + { + $user = $this->options['DBA_username']? $this->options['DBA_username'] : $this->dsn['username']; + $pass = $this->options['DBA_password']? $this->options['DBA_password'] : $this->dsn['password']; + $connection = $this->_doConnect($user, $pass, $this->options['persistent']); + if (PEAR::isError($connection)) { + return $connection; + } + + $offset = $this->offset; + $limit = $this->limit; + $this->offset = $this->limit = 0; + $query = $this->_modifyQuery($query, $is_manip, $limit, $offset); + + $result = $this->_doQuery($query, $is_manip, $connection, false); + if (!PEAR::isError($result)) { + if ($is_manip) { + $result = $this->_affectedRows($connection, $result); + } else { + $result = $this->_wrapResult($result, $types, true, false, $limit, $offset); + } + } + + @OCILogOff($connection); + return $result; + } + + // }}} + // {{{ _modifyQuery() + + /** + * Changes a query string for various DBMS specific reasons + * + * @param string $query query to modify + * @param boolean $is_manip if it is a DML query + * @param integer $limit limit the number of rows + * @param integer $offset start reading from given offset + * @return string modified query + * @access protected + */ + function _modifyQuery($query, $is_manip, $limit, $offset) + { + if (preg_match('/^\s*SELECT/i', $query)) { + if (!preg_match('/\sFROM\s/i', $query)) { + $query.= " FROM dual"; + } + if ($limit > 0) { + // taken from http://svn.ez.no/svn/ezcomponents/packages/Database + $max = $offset + $limit; + if ($offset > 0) { + $min = $offset + 1; + $query = "SELECT * FROM (SELECT a.*, ROWNUM mdb2rn FROM ($query) a WHERE ROWNUM <= $max) WHERE mdb2rn >= $min"; + } else { + $query = "SELECT a.* FROM ($query) a WHERE ROWNUM <= $max"; + } + } + } + return $query; + } + + /** + * Obtain DBMS specific SQL code portion needed to declare a generic type + * field to be used in statement like CREATE TABLE, without the field name + * and type values (ie. just the character set, default value, if the + * field is permitted to be NULL or not, and the collation options). + * + * @param array $field associative array with the name of the properties + * of the field being declared as array indexes. Currently, the types + * of supported field properties are as follows: + * + * default + * Text value to be used as default for this field. + * notnull + * Boolean flag that indicates whether this field is constrained + * to not be set to null. + * charset + * Text value with the default CHARACTER SET for this field. + * collation + * Text value with the default COLLATION for this field. + * @return string DBMS specific SQL code portion that should be used to + * declare the specified field's options. + * @access protected + */ + function _getDeclarationOptions($field) + { + $charset = empty($field['charset']) ? '' : + ' '.$this->_getCharsetFieldDeclaration($field['charset']); + + $notnull = empty($field['notnull']) ? ' NULL' : ' NOT NULL'; + $default = ''; + if (array_key_exists('default', $field)) { + if ($field['default'] === '') { + $db = $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + $valid_default_values = $this->getValidTypes(); + $field['default'] = $valid_default_values[$field['type']]; + if ($field['default'] === '' && ($db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL)) { + $field['default'] = ' '; + } + } + if (null !== $field['default']) { + $default = ' DEFAULT ' . $this->quote($field['default'], $field['type']); + } + } + + $collation = empty($field['collation']) ? '' : + ' '.$this->_getCollationFieldDeclaration($field['collation']); + + return $charset.$default.$notnull.$collation; + } + + // }}} + // {{{ _doQuery() + + /** + * Execute a query + * @param string $query query + * @param boolean $is_manip if the query is a manipulation query + * @param resource $connection + * @param string $database_name + * @return result or error object + * @access protected + */ + function _doQuery($query, $is_manip = false, $connection = null, $database_name = null) + { + $this->last_query = $query; + $result = $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'pre')); + if ($result) { + if (PEAR::isError($result)) { + return $result; + } + $query = $result; + } + if ($this->getOption('disable_query')) { + if ($is_manip) { + return 0; + } + return null; + } + + if (null === $connection) { + $connection = $this->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + } + + $query = str_replace("\r\n", "\n", $query); //for fixing end-of-line character in the PL/SQL in windows + $result = @OCIParse($connection, $query); + if (!$result) { + $err = $this->raiseError(null, null, null, + 'Could not create statement', __FUNCTION__); + return $err; + } + + $mode = $this->in_transaction ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS; + if (!@OCIExecute($result, $mode)) { + $err = $this->raiseError($result, null, null, + 'Could not execute statement', __FUNCTION__); + return $err; + } + + if (is_numeric($this->options['result_prefetching'])) { + @ocisetprefetch($result, $this->options['result_prefetching']); + } + + $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'post', 'result' => $result)); + return $result; + } + + // }}} + // {{{ _affectedRows() + + /** + * Returns the number of rows affected + * + * @param resource $result + * @param resource $connection + * @return mixed MDB2 Error Object or the number of rows affected + * @access private + */ + function _affectedRows($connection, $result = null) + { + if (null === $connection) { + $connection = $this->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + } + return @OCIRowCount($result); + } + + // }}} + // {{{ getServerVersion() + + /** + * return version information about the server + * + * @param bool $native determines if the raw version string should be returned + * @return mixed array/string with version information or MDB2 error object + * @access public + */ + function getServerVersion($native = false) + { + $connection = $this->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + if ($this->connected_server_info) { + $server_info = $this->connected_server_info; + } else { + $server_info = @ociserverversion($connection); + } + if (!$server_info) { + return $this->raiseError(null, null, null, + 'Could not get server information', __FUNCTION__); + } + // cache server_info + $this->connected_server_info = $server_info; + if (!$native) { + if (!preg_match('/ (\d+)\.(\d+)\.(\d+)\.([\d\.]+) /', $server_info, $tmp)) { + return $this->raiseError(MDB2_ERROR_INVALID, null, null, + 'Could not parse version information:'.$server_info, __FUNCTION__); + } + $server_info = array( + 'major' => $tmp[1], + 'minor' => $tmp[2], + 'patch' => $tmp[3], + 'extra' => $tmp[4], + 'native' => $server_info, + ); + } + return $server_info; + } + + // }}} + // {{{ prepare() + + /** + * Prepares a query for multiple execution with execute(). + * With some database backends, this is emulated. + * prepare() requires a generic query as string like + * 'INSERT INTO numbers VALUES(?,?)' or + * 'INSERT INTO numbers VALUES(:foo,:bar)'. + * The ? and :name and are placeholders which can be set using + * bindParam() and the query can be sent off using the execute() method. + * The allowed format for :name can be set with the 'bindname_format' option. + * + * @param string $query the query to prepare + * @param mixed $types array that contains the types of the placeholders + * @param mixed $result_types array that contains the types of the columns in + * the result set or MDB2_PREPARE_RESULT, if set to + * MDB2_PREPARE_MANIP the query is handled as a manipulation query + * @param mixed $lobs key (field) value (parameter) pair for all lob placeholders + * @return mixed resource handle for the prepared query on success, a MDB2 + * error on failure + * @access public + * @see bindParam, execute + */ + function prepare($query, $types = null, $result_types = null, $lobs = array()) + { + if ($this->options['emulate_prepared']) { + return parent::prepare($query, $types, $result_types, $lobs); + } + $is_manip = ($result_types === MDB2_PREPARE_MANIP); + $offset = $this->offset; + $limit = $this->limit; + $this->offset = $this->limit = 0; + $result = $this->debug($query, __FUNCTION__, array('is_manip' => $is_manip, 'when' => 'pre')); + if ($result) { + if (PEAR::isError($result)) { + return $result; + } + $query = $result; + } + $query = $this->_modifyQuery($query, $is_manip, $limit, $offset); + $placeholder_type_guess = $placeholder_type = null; + $question = '?'; + $colon = ':'; + $positions = array(); + $position = 0; + $parameter = -1; + while ($position < strlen($query)) { + $q_position = strpos($query, $question, $position); + $c_position = strpos($query, $colon, $position); + if ($q_position && $c_position) { + $p_position = min($q_position, $c_position); + } elseif ($q_position) { + $p_position = $q_position; + } elseif ($c_position) { + $p_position = $c_position; + } else { + break; + } + if (null === $placeholder_type) { + $placeholder_type_guess = $query[$p_position]; + } + + $new_pos = $this->_skipDelimitedStrings($query, $position, $p_position); + if (PEAR::isError($new_pos)) { + return $new_pos; + } + if ($new_pos != $position) { + $position = $new_pos; + continue; //evaluate again starting from the new position + } + + if ($query[$position] == $placeholder_type_guess) { + if (null === $placeholder_type) { + $placeholder_type = $query[$p_position]; + $question = $colon = $placeholder_type; + if (!empty($types) && is_array($types)) { + if ($placeholder_type == ':') { + if (is_int(key($types))) { + $types_tmp = $types; + $types = array(); + $count = -1; + } + } else { + $types = array_values($types); + } + } + } + if ($placeholder_type == ':') { + $regexp = '/^.{'.($position+1).'}('.$this->options['bindname_format'].').*$/s'; + $parameter = preg_replace($regexp, '\\1', $query); + if ($parameter === '') { + $err = $this->raiseError(MDB2_ERROR_SYNTAX, null, null, + 'named parameter name must match "bindname_format" option', __FUNCTION__); + return $err; + } + // use parameter name in type array + if (isset($count) && isset($types_tmp[++$count])) { + $types[$parameter] = $types_tmp[$count]; + } + $length = strlen($parameter) + 1; + } else { + ++$parameter; + //$length = strlen($parameter); + $length = 1; // strlen('?') + } + if (!in_array($parameter, $positions)) { + $positions[] = $parameter; + } + if (isset($types[$parameter]) + && ($types[$parameter] == 'clob' || $types[$parameter] == 'blob') + ) { + if (!isset($lobs[$parameter])) { + $lobs[$parameter] = $parameter; + } + $value = $this->quote(true, $types[$parameter]); + if (PEAR::isError($value)) { + return $value; + } + $query = substr_replace($query, $value, $p_position, $length); + $position = $p_position + strlen($value) - 1; + } elseif ($placeholder_type == '?') { + $query = substr_replace($query, ':'.$parameter, $p_position, 1); + $position = $p_position + $length; + } else { + $position = $p_position + 1; + } + } else { + $position = $p_position; + } + } + if (is_array($lobs)) { + $columns = $variables = ''; + foreach ($lobs as $parameter => $field) { + $columns.= ($columns ? ', ' : ' RETURNING ').$field; + $variables.= ($variables ? ', ' : ' INTO ').':'.$parameter; + } + $query.= $columns.$variables; + } + $connection = $this->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + $statement = @OCIParse($connection, $query); + if (!$statement) { + $err = $this->raiseError(null, null, null, + 'Could not create statement', __FUNCTION__); + return $err; + } + + $class_name = 'MDB2_Statement_'.$this->phptype; + $obj = new $class_name($this, $statement, $positions, $query, $types, $result_types, $is_manip, $limit, $offset); + $this->debug($query, __FUNCTION__, array('is_manip' => $is_manip, 'when' => 'post', 'result' => $obj)); + return $obj; + } + + // }}} + // {{{ nextID() + + /** + * Returns the next free id of a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true the sequence is + * automatic created, if it + * not exists + * @return mixed MDB2 Error Object or id + * @access public + */ + function nextID($seq_name, $ondemand = true) + { + $sequence_name = $this->quoteIdentifier($this->getSequenceName($seq_name), true); + $query = "SELECT $sequence_name.nextval FROM DUAL"; + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $this->expectError(MDB2_ERROR_NOSUCHTABLE); + $result = $this->queryOne($query, 'integer'); + $this->popExpect(); + $this->popErrorHandling(); + if (PEAR::isError($result)) { + if ($ondemand && $result->getCode() == MDB2_ERROR_NOSUCHTABLE) { + $this->loadModule('Manager', null, true); + $result = $this->manager->createSequence($seq_name); + if (PEAR::isError($result)) { + return $result; + } + return $this->nextId($seq_name, false); + } + } + return $result; + } + + // }}} + // {{{ lastInsertID() + + /** + * Returns the autoincrement ID if supported or $id or fetches the current + * ID in a sequence called: $table.(empty($field) ? '' : '_'.$field) + * + * @param string $table name of the table into which a new row was inserted + * @param string $field name of the field into which a new row was inserted + * @return mixed MDB2 Error Object or id + * @access public + */ + function lastInsertID($table = null, $field = null) + { + $old_seq = $table.(empty($field) ? '' : '_'.$field); + $sequence_name = $this->quoteIdentifier($this->getSequenceName($table), true); + $result = $this->queryOne("SELECT $sequence_name.currval", 'integer'); + if (PEAR::isError($result)) { + $sequence_name = $this->quoteIdentifier($this->getSequenceName($old_seq), true); + $result = $this->queryOne("SELECT $sequence_name.currval", 'integer'); + } + + return $result; + } + + // }}} + // {{{ currId() + + /** + * Returns the current id of a sequence + * + * @param string $seq_name name of the sequence + * @return mixed MDB2_Error or id + * @access public + */ + function currId($seq_name) + { + $sequence_name = $this->getSequenceName($seq_name); + $query = 'SELECT (last_number-1) FROM all_sequences'; + $query.= ' WHERE sequence_name='.$this->quote($sequence_name, 'text'); + $query.= ' OR sequence_name='.$this->quote(strtoupper($sequence_name), 'text'); + return $this->queryOne($query, 'integer'); + } +} + +/** + * MDB2 OCI8 result driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_Result_oci8 extends MDB2_Result_Common +{ + // }}} + // {{{ fetchRow() + + /** + * Fetch a row and insert the data into an existing array. + * + * @param int $fetchmode how the array data should be indexed + * @param int $rownum number of the row where the data can be found + * @return int data array on success, a MDB2 error on failure + * @access public + */ + function fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null) + { + if (null !== $rownum) { + $seek = $this->seek($rownum); + if (PEAR::isError($seek)) { + return $seek; + } + } + if ($fetchmode == MDB2_FETCHMODE_DEFAULT) { + $fetchmode = $this->db->fetchmode; + } + if ($fetchmode & MDB2_FETCHMODE_ASSOC) { + @OCIFetchInto($this->result, $row, OCI_ASSOC+OCI_RETURN_NULLS); + if (is_array($row) + && $this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE + ) { + $row = array_change_key_case($row, $this->db->options['field_case']); + } + } else { + @OCIFetchInto($this->result, $row, OCI_RETURN_NULLS); + } + if (!$row) { + if (false === $this->result) { + $err = $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'resultset has already been freed', __FUNCTION__); + return $err; + } + return null; + } + // remove additional column at the end + if ($this->offset > 0) { + array_pop($row); + } + $mode = 0; + $rtrim = false; + if ($this->db->options['portability'] & MDB2_PORTABILITY_RTRIM) { + if (empty($this->types)) { + $mode += MDB2_PORTABILITY_RTRIM; + } else { + $rtrim = true; + } + } + if ($mode) { + $this->db->_fixResultArrayValues($row, $mode); + } + if (!empty($this->types)) { + $row = $this->db->datatype->convertResultRow($this->types, $row, $rtrim); + } + if (!empty($this->values)) { + $this->_assignBindColumns($row); + } + if ($fetchmode === MDB2_FETCHMODE_OBJECT) { + $object_class = $this->db->options['fetch_class']; + if ($object_class == 'stdClass') { + $row = (object) $row; + } else { + $rowObj = new $object_class($row); + $row = $rowObj; + } + } + ++$this->rownum; + return $row; + } + + // }}} + // {{{ _getColumnNames() + + /** + * Retrieve the names of columns returned by the DBMS in a query result. + * + * @return mixed Array variable that holds the names of columns as keys + * or an MDB2 error on failure. + * Some DBMS may not return any columns when the result set + * does not contain any rows. + * @access private + */ + function _getColumnNames() + { + $columns = array(); + $numcols = $this->numCols(); + if (PEAR::isError($numcols)) { + return $numcols; + } + for ($column = 0; $column < $numcols; $column++) { + $column_name = @OCIColumnName($this->result, $column + 1); + $columns[$column_name] = $column; + } + if ($this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $columns = array_change_key_case($columns, $this->db->options['field_case']); + } + return $columns; + } + + // }}} + // {{{ numCols() + + /** + * Count the number of columns returned by the DBMS in a query result. + * + * @return mixed integer value with the number of columns, a MDB2 error + * on failure + * @access public + */ + function numCols() + { + $cols = @OCINumCols($this->result); + if (null === $cols) { + if (false === $this->result) { + return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'resultset has already been freed', __FUNCTION__); + } + if (null === $this->result) { + return count($this->types); + } + return $this->db->raiseError(null, null, null, + 'Could not get column count', __FUNCTION__); + } + if ($this->offset > 0) { + --$cols; + } + return $cols; + } + + // }}} + // {{{ free() + + /** + * Free the internal resources associated with $result. + * + * @return boolean true on success, false if $result is invalid + * @access public + */ + function free() + { + if (is_resource($this->result) && $this->db->connection) { + $free = @OCIFreeCursor($this->result); + if (false === $free) { + return $this->db->raiseError(null, null, null, + 'Could not free result', __FUNCTION__); + } + } + $this->result = false; + return MDB2_OK; + + } +} + +/** + * MDB2 OCI8 buffered result driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_BufferedResult_oci8 extends MDB2_Result_oci8 +{ + var $buffer; + var $buffer_rownum = - 1; + + // {{{ _fillBuffer() + + /** + * Fill the row buffer + * + * @param int $rownum row number upto which the buffer should be filled + if the row number is null all rows are ready into the buffer + * @return boolean true on success, false on failure + * @access protected + */ + function _fillBuffer($rownum = null) + { + if (isset($this->buffer) && is_array($this->buffer)) { + if (null === $rownum) { + if (!end($this->buffer)) { + return false; + } + } elseif (isset($this->buffer[$rownum])) { + return (bool)$this->buffer[$rownum]; + } + } + + $row = true; + while (((null === $rownum) || $this->buffer_rownum < $rownum) + && ($row = @OCIFetchInto($this->result, $buffer, OCI_RETURN_NULLS)) + ) { + ++$this->buffer_rownum; + // remove additional column at the end + if ($this->offset > 0) { + array_pop($buffer); + } + if (empty($this->types)) { + foreach (array_keys($buffer) as $key) { + if (is_a($buffer[$key], 'oci-lob')) { + $buffer[$key] = $buffer[$key]->load(); + } + } + } + $this->buffer[$this->buffer_rownum] = $buffer; + } + + if (!$row) { + ++$this->buffer_rownum; + $this->buffer[$this->buffer_rownum] = false; + return false; + } + return true; + } + + // }}} + // {{{ fetchRow() + + /** + * Fetch a row and insert the data into an existing array. + * + * @param int $fetchmode how the array data should be indexed + * @param int $rownum number of the row where the data can be found + * @return int data array on success, a MDB2 error on failure + * @access public + */ + function fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null) + { + if (false === $this->result) { + $err = $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'resultset has already been freed', __FUNCTION__); + return $err; + } + if (null === $this->result) { + return null; + } + if (null !== $rownum) { + $seek = $this->seek($rownum); + if (PEAR::isError($seek)) { + return $seek; + } + } + $target_rownum = $this->rownum + 1; + if ($fetchmode == MDB2_FETCHMODE_DEFAULT) { + $fetchmode = $this->db->fetchmode; + } + if (!$this->_fillBuffer($target_rownum)) { + return null; + } + $row = $this->buffer[$target_rownum]; + if ($fetchmode & MDB2_FETCHMODE_ASSOC) { + $column_names = $this->getColumnNames(); + foreach ($column_names as $name => $i) { + $column_names[$name] = $row[$i]; + } + $row = $column_names; + } + $mode = 0; + $rtrim = false; + if ($this->db->options['portability'] & MDB2_PORTABILITY_RTRIM) { + if (empty($this->types)) { + $mode += MDB2_PORTABILITY_RTRIM; + } else { + $rtrim = true; + } + } + if ($mode) { + $this->db->_fixResultArrayValues($row, $mode); + } + if (!empty($this->types)) { + $row = $this->db->datatype->convertResultRow($this->types, $row, $rtrim); + } + if (!empty($this->values)) { + $this->_assignBindColumns($row); + } + if ($fetchmode === MDB2_FETCHMODE_OBJECT) { + $object_class = $this->db->options['fetch_class']; + if ($object_class == 'stdClass') { + $row = (object) $row; + } else { + $rowObj = new $object_class($row); + $row = $rowObj; + } + } + ++$this->rownum; + return $row; + } + + // }}} + // {{{ seek() + + /** + * Seek to a specific row in a result set + * + * @param int $rownum number of the row where the data can be found + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function seek($rownum = 0) + { + if (false === $this->result) { + return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'resultset has already been freed', __FUNCTION__); + } + $this->rownum = $rownum - 1; + return MDB2_OK; + } + + // }}} + // {{{ valid() + + /** + * Check if the end of the result set has been reached + * + * @return mixed true or false on sucess, a MDB2 error on failure + * @access public + */ + function valid() + { + if (false === $this->result) { + return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'resultset has already been freed', __FUNCTION__); + } + if (null === $this->result) { + return true; + } + if ($this->_fillBuffer($this->rownum + 1)) { + return true; + } + return false; + } + + // }}} + // {{{ numRows() + + /** + * Returns the number of rows in a result object + * + * @return mixed MDB2 Error Object or the number of rows + * @access public + */ + function numRows() + { + if (false === $this->result) { + return $this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'resultset has already been freed', __FUNCTION__); + } + if (null === $this->result) { + return 0; + } + $this->_fillBuffer(); + return $this->buffer_rownum; + } + + // }}} + // {{{ free() + + /** + * Free the internal resources associated with $result. + * + * @return boolean true on success, false if $result is invalid + * @access public + */ + function free() + { + $this->buffer = null; + $this->buffer_rownum = null; + return parent::free(); + } +} + +/** + * MDB2 OCI8 statement driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith + */ +class MDB2_Statement_oci8 extends MDB2_Statement_Common +{ + // {{{ Variables (Properties) + + var $type_maxlengths = array(); + + // }}} + // {{{ bindParam() + + /** + * Bind a variable to a parameter of a prepared query. + * + * @param int $parameter the order number of the parameter in the query + * statement. The order number of the first parameter is 1. + * @param mixed &$value variable that is meant to be bound to specified + * parameter. The type of the value depends on the $type argument. + * @param string $type specifies the type of the field + * @param int $maxlength specifies the maximum length of the field; if set to -1, the + * current length of $value is used + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function bindParam($parameter, &$value, $type = null, $maxlength = -1) + { + if (!is_numeric($parameter)) { + $parameter = preg_replace('/^:(.*)$/', '\\1', $parameter); + } + if (MDB2_OK === ($ret = parent::bindParam($parameter, $value, $type))) { + $this->type_maxlengths[$parameter] = $maxlength; + } + + return $ret; + } + + // }}} + // {{{ _execute() + + /** + * Execute a prepared query statement helper method. + * + * @param mixed $result_class string which specifies which result class to use + * @param mixed $result_wrap_class string which specifies which class to wrap results in + * + * @return mixed MDB2_Result or integer (affected rows) on success, + * a MDB2 error on failure + * @access private + */ + function _execute($result_class = true, $result_wrap_class = false) + { + if (null === $this->statement) { + return parent::_execute($result_class, $result_wrap_class); + } + $this->db->last_query = $this->query; + $this->db->debug($this->query, 'execute', array('is_manip' => $this->is_manip, 'when' => 'pre', 'parameters' => $this->values)); + if ($this->db->getOption('disable_query')) { + $result = $this->is_manip ? 0 : null; + return $result; + } + + $connection = $this->db->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + + $result = MDB2_OK; + $lobs = $quoted_values = array(); + $i = 0; + foreach ($this->positions as $parameter) { + if (!array_key_exists($parameter, $this->values)) { + return $this->db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'Unable to bind to missing placeholder: '.$parameter, __FUNCTION__); + } + $type = array_key_exists($parameter, $this->types) ? $this->types[$parameter] : null; + if ($type == 'clob' || $type == 'blob') { + $lobs[$i]['file'] = false; + if (is_resource($this->values[$parameter])) { + $fp = $this->values[$parameter]; + $this->values[$parameter] = ''; + while (!feof($fp)) { + $this->values[$parameter] .= fread($fp, 8192); + } + } elseif (is_a($this->values[$parameter], 'OCI-Lob')) { + //do nothing + } elseif ($this->db->getOption('lob_allow_url_include') + && preg_match('/^(\w+:\/\/)(.*)$/', $this->values[$parameter], $match) + ) { + $lobs[$i]['file'] = true; + if ($match[1] == 'file://') { + $this->values[$parameter] = $match[2]; + } + } + $lobs[$i]['value'] = $this->values[$parameter]; + $lobs[$i]['descriptor'] =& $this->values[$parameter]; + // Test to see if descriptor has already been created for this + // variable (i.e. if it has been bound more than once): + if (!is_a($this->values[$parameter], 'OCI-Lob')) { + $this->values[$parameter] = @OCINewDescriptor($connection, OCI_D_LOB); + if (false === $this->values[$parameter]) { + $result = $this->db->raiseError(null, null, null, + 'Unable to create descriptor for LOB in parameter: '.$parameter, __FUNCTION__); + break; + } + } + $lob_type = ($type == 'blob' ? OCI_B_BLOB : OCI_B_CLOB); + if (!@OCIBindByName($this->statement, ':'.$parameter, $lobs[$i]['descriptor'], -1, $lob_type)) { + $result = $this->db->raiseError($this->statement, null, null, + 'could not bind LOB parameter', __FUNCTION__); + break; + } + } else if ($type == OCI_B_BFILE) { + // Test to see if descriptor has already been created for this + // variable (i.e. if it has been bound more than once): + if (!is_a($this->values[$parameter], "OCI-Lob")) { + $this->values[$parameter] = @OCINewDescriptor($connection, OCI_D_FILE); + if (false === $this->values[$parameter]) { + $result = $this->db->raiseError(null, null, null, + 'Unable to create descriptor for BFILE in parameter: '.$parameter, __FUNCTION__); + break; + } + } + if (!@OCIBindByName($this->statement, ':'.$parameter, $this->values[$parameter], -1, $type)) { + $result = $this->db->raiseError($this->statement, null, null, + 'Could not bind BFILE parameter', __FUNCTION__); + break; + } + } else if ($type == OCI_B_ROWID) { + // Test to see if descriptor has already been created for this + // variable (i.e. if it has been bound more than once): + if (!is_a($this->values[$parameter], "OCI-Lob")) { + $this->values[$parameter] = @OCINewDescriptor($connection, OCI_D_ROWID); + if (false === $this->values[$parameter]) { + $result = $this->db->raiseError(null, null, null, + 'Unable to create descriptor for ROWID in parameter: '.$parameter, __FUNCTION__); + break; + } + } + if (!@OCIBindByName($this->statement, ':'.$parameter, $this->values[$parameter], -1, $type)) { + $result = $this->db->raiseError($this->statement, null, null, + 'Could not bind ROWID parameter', __FUNCTION__); + break; + } + } else if ($type == OCI_B_CURSOR) { + // Test to see if cursor has already been allocated for this + // variable (i.e. if it has been bound more than once): + if (!is_resource($this->values[$parameter]) || !get_resource_type($this->values[$parameter]) == "oci8 statement") { + $this->values[$parameter] = @OCINewCursor($connection); + if (false === $this->values[$parameter]) { + $result = $this->db->raiseError(null, null, null, + 'Unable to allocate cursor for parameter: '.$parameter, __FUNCTION__); + break; + } + } + if (!@OCIBindByName($this->statement, ':'.$parameter, $this->values[$parameter], -1, $type)) { + $result = $this->db->raiseError($this->statement, null, null, + 'Could not bind CURSOR parameter', __FUNCTION__); + break; + } + } else { + $maxlength = array_key_exists($parameter, $this->type_maxlengths) ? $this->type_maxlengths[$parameter] : -1; + $this->values[$parameter] = $this->db->quote($this->values[$parameter], $type, false); + $quoted_values[$i] =& $this->values[$parameter]; + if (PEAR::isError($quoted_values[$i])) { + return $quoted_values[$i]; + } + if (!@OCIBindByName($this->statement, ':'.$parameter, $quoted_values[$i], $maxlength)) { + $result = $this->db->raiseError($this->statement, null, null, + 'could not bind non-abstract parameter', __FUNCTION__); + break; + } + } + ++$i; + } + + $lob_keys = array_keys($lobs); + if (!PEAR::isError($result)) { + $mode = (!empty($lobs) || $this->db->in_transaction) ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS; + if (!@OCIExecute($this->statement, $mode)) { + $err = $this->db->raiseError($this->statement, null, null, + 'could not execute statement', __FUNCTION__); + return $err; + } + + if (!empty($lobs)) { + foreach ($lob_keys as $i) { + if ((null !== $lobs[$i]['value']) && $lobs[$i]['value'] !== '') { + if (is_object($lobs[$i]['value'])) { + // Probably a NULL LOB + // @see http://bugs.php.net/bug.php?id=27485 + continue; + } + if ($lobs[$i]['file']) { + $result = $lobs[$i]['descriptor']->savefile($lobs[$i]['value']); + } else { + $result = $lobs[$i]['descriptor']->save($lobs[$i]['value']); + } + if (!$result) { + $result = $this->db->raiseError(null, null, null, + 'Unable to save descriptor contents', __FUNCTION__); + break; + } + } + } + + if (!PEAR::isError($result)) { + if (!$this->db->in_transaction) { + if (!@OCICommit($connection)) { + $result = $this->db->raiseError(null, null, null, + 'Unable to commit transaction', __FUNCTION__); + } + } else { + ++$this->db->uncommitedqueries; + } + } + } + } + + if (PEAR::isError($result)) { + return $result; + } + + if ($this->is_manip) { + $affected_rows = $this->db->_affectedRows($connection, $this->statement); + return $affected_rows; + } + + $result = $this->db->_wrapResult($this->statement, $this->result_types, + $result_class, $result_wrap_class, $this->limit, $this->offset); + $this->db->debug($this->query, 'execute', array('is_manip' => $this->is_manip, 'when' => 'post', 'result' => $result)); + return $result; + } + + // }}} + // {{{ free() + + /** + * Release resources allocated for the specified prepared query. + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function free() + { + if (null === $this->positions) { + return $this->db->raiseError(MDB2_ERROR, null, null, + 'Prepared statement has already been freed', __FUNCTION__); + } + $result = MDB2_OK; + + if ((null !== $this->statement) && !@OCIFreeStatement($this->statement)) { + $result = $this->db->raiseError(null, null, null, + 'Could not free statement', __FUNCTION__); + } + + parent::free(); + return $result; + } +} +?> \ No newline at end of file diff --git a/3rdparty/Sabre.includes.php b/3rdparty/Sabre.includes.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Backend/Abstract.php b/3rdparty/Sabre/CalDAV/Backend/Abstract.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Backend/PDO.php b/3rdparty/Sabre/CalDAV/Backend/PDO.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Calendar.php b/3rdparty/Sabre/CalDAV/Calendar.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/CalendarObject.php b/3rdparty/Sabre/CalDAV/CalendarObject.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryParser.php b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php old mode 100644 new mode 100755 index 1bb6b5d53f..8f674840e8 --- a/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php +++ b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php @@ -294,6 +294,7 @@ class Sabre_CalDAV_CalendarQueryValidator { // in the VALARM component code, so this is a hack, and an // expensive one too. if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) { + // Fire up the iterator! $it = new Sabre_VObject_RecurrenceIterator($component->parent->parent, (string)$component->parent->UID); while($it->valid()) { @@ -303,15 +304,37 @@ class Sabre_CalDAV_CalendarQueryValidator { // one is the first to trigger. Based on this, we can // determine if we can 'give up' expanding events. $firstAlarm = null; - foreach($expandedEvent->VALARM as $expandedAlarm) { - $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime(); - if (!$firstAlarm || $effectiveTrigger < $firstAlarm) { - $firstAlarm = $effectiveTrigger; - } - if ($expandedAlarm->isInTimeRange($start, $end)) { - return true; - } + if ($expandedEvent->VALARM !== null) { + foreach($expandedEvent->VALARM as $expandedAlarm) { + $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime(); + if ($expandedAlarm->isInTimeRange($start, $end)) { + return true; + } + + if ((string)$expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') { + // This is an alarm with a non-relative trigger + // time, likely created by a buggy client. The + // implication is that every alarm in this + // recurring event trigger at the exact same + // time. It doesn't make sense to traverse + // further. + } else { + // We store the first alarm as a means to + // figure out when we can stop traversing. + if (!$firstAlarm || $effectiveTrigger < $firstAlarm) { + $firstAlarm = $effectiveTrigger; + } + } + } + } + if (is_null($firstAlarm)) { + // No alarm was found. + // + // Or technically: No alarm that will change for + // every instance of the recurrence was found, + // which means we can assume there was no match. + return false; } if ($firstAlarm > $end) { return false; diff --git a/3rdparty/Sabre/CalDAV/CalendarRootNode.php b/3rdparty/Sabre/CalDAV/CalendarRootNode.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/ICalendar.php b/3rdparty/Sabre/CalDAV/ICalendar.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/ICalendarObject.php b/3rdparty/Sabre/CalDAV/ICalendarObject.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Plugin.php b/3rdparty/Sabre/CalDAV/Plugin.php old mode 100644 new mode 100755 index d7d1d97051..c56ab38484 --- a/3rdparty/Sabre/CalDAV/Plugin.php +++ b/3rdparty/Sabre/CalDAV/Plugin.php @@ -49,23 +49,23 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { /** * The email handler for invites and other scheduling messages. - * - * @var Sabre_CalDAV_Schedule_IMip + * + * @var Sabre_CalDAV_Schedule_IMip */ protected $imipHandler; /** * Sets the iMIP handler. * - * iMIP = The email transport of iCalendar scheduling messages. Setting - * this is optional, but if you want the server to allow invites to be sent + * iMIP = The email transport of iCalendar scheduling messages. Setting + * this is optional, but if you want the server to allow invites to be sent * out, you must set a handler. * - * Specifically iCal will plain assume that the server supports this. If - * the server doesn't, iCal will display errors when inviting people to + * Specifically iCal will plain assume that the server supports this. If + * the server doesn't, iCal will display errors when inviting people to * events. * - * @param Sabre_CalDAV_Schedule_IMip $imipHandler + * @param Sabre_CalDAV_Schedule_IMip $imipHandler * @return void */ public function setIMipHandler(Sabre_CalDAV_Schedule_IMip $imipHandler) { @@ -672,6 +672,42 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { } + if ($vobj->name !== 'VCALENDAR') { + throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support iCalendar objects.'); + } + + $foundType = null; + $foundUID = null; + foreach($vobj->getComponents() as $component) { + switch($component->name) { + case 'VTIMEZONE' : + continue 2; + case 'VEVENT' : + case 'VTODO' : + case 'VJOURNAL' : + if (is_null($foundType)) { + $foundType = $component->name; + if (!isset($component->UID)) { + throw new Sabre_DAV_Exception_BadRequest('Every ' . $component->name . ' component must have an UID'); + } + $foundUID = (string)$component->UID; + } else { + if ($foundType !== $component->name) { + throw new Sabre_DAV_Exception_BadRequest('A calendar object must only contain 1 component. We found a ' . $component->name . ' as well as a ' . $foundType); + } + if ($foundUID !== (string)$component->UID) { + throw new Sabre_DAV_Exception_BadRequest('Every ' . $component->name . ' in this object must have identical UIDs'); + } + } + break; + default : + throw new Sabre_DAV_Exception_BadRequest('You are not allowed to create components of type: ' . $component->name . ' here'); + + } + } + if (!$foundType) + throw new Sabre_DAV_Exception_BadRequest('iCalendar object must contain at least 1 of VEVENT, VTODO or VJOURNAL'); + } /** @@ -687,12 +723,12 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { if (!$originator) { throw new Sabre_DAV_Exception_BadRequest('The Originator: header must be specified when making POST requests'); - } + } if (!$recipients) { throw new Sabre_DAV_Exception_BadRequest('The Recipient: header must be specified when making POST requests'); - } + } - if (!preg_match('/^mailto:(.*)@(.*)$/', $originator)) { + if (!preg_match('/^mailto:(.*)@(.*)$/i', $originator)) { throw new Sabre_DAV_Exception_BadRequest('Originator must start with mailto: and must be valid email address'); } $originator = substr($originator,7); @@ -701,14 +737,14 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { foreach($recipients as $k=>$recipient) { $recipient = trim($recipient); - if (!preg_match('/^mailto:(.*)@(.*)$/', $recipient)) { + if (!preg_match('/^mailto:(.*)@(.*)$/i', $recipient)) { throw new Sabre_DAV_Exception_BadRequest('Recipients must start with mailto: and must be valid email address'); } $recipient = substr($recipient, 7); $recipients[$k] = $recipient; } - // We need to make sure that 'originator' matches one of the email + // We need to make sure that 'originator' matches one of the email // addresses of the selected principal. $principal = $outboxNode->getOwner(); $props = $this->server->getProperties($principal,array( @@ -724,7 +760,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { throw new Sabre_DAV_Exception_Forbidden('The addresses specified in the Originator header did not match any addresses in the owners calendar-user-address-set header'); } - try { + try { $vObject = Sabre_VObject_Reader::read($this->server->httpRequest->getBody(true)); } catch (Sabre_VObject_ParseException $e) { throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage()); @@ -749,9 +785,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { } if (in_array($method, array('REQUEST','REPLY','ADD','CANCEL')) && $componentType==='VEVENT') { - $this->iMIPMessage($originator, $recipients, $vObject); + $result = $this->iMIPMessage($originator, $recipients, $vObject); $this->server->httpResponse->sendStatus(200); - $this->server->httpResponse->sendBody('Messages sent'); + $this->server->httpResponse->setHeader('Content-Type','application/xml'); + $this->server->httpResponse->sendBody($this->generateScheduleResponse($result)); } else { throw new Sabre_DAV_Exception_NotImplemented('This iTIP method is currently not implemented'); } @@ -760,18 +797,83 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { /** * Sends an iMIP message by email. - * - * @param string $originator - * @param array $recipients - * @param Sabre_VObject_Component $vObject - * @return void + * + * This method must return an array with status codes per recipient. + * This should look something like: + * + * array( + * 'user1@example.org' => '2.0;Success' + * ) + * + * Formatting for this status code can be found at: + * https://tools.ietf.org/html/rfc5545#section-3.8.8.3 + * + * A list of valid status codes can be found at: + * https://tools.ietf.org/html/rfc5546#section-3.6 + * + * @param string $originator + * @param array $recipients + * @param Sabre_VObject_Component $vObject + * @return array */ protected function iMIPMessage($originator, array $recipients, Sabre_VObject_Component $vObject) { if (!$this->imipHandler) { - throw new Sabre_DAV_Exception_NotImplemented('No iMIP handler is setup on this server.'); + $resultStatus = '5.2;This server does not support this operation'; + } else { + $this->imipHandler->sendMessage($originator, $recipients, $vObject); + $resultStatus = '2.0;Success'; } - $this->imipHandler->sendMessage($originator, $recipients, $vObject); + + $result = array(); + foreach($recipients as $recipient) { + $result[$recipient] = $resultStatus; + } + + return $result; + + + } + + /** + * Generates a schedule-response XML body + * + * The recipients array is a key->value list, containing email addresses + * and iTip status codes. See the iMIPMessage method for a description of + * the value. + * + * @param array $recipients + * @return string + */ + public function generateScheduleResponse(array $recipients) { + + $dom = new DOMDocument('1.0','utf-8'); + $dom->formatOutput = true; + $xscheduleResponse = $dom->createElement('cal:schedule-response'); + $dom->appendChild($xscheduleResponse); + + foreach($this->server->xmlNamespaces as $namespace=>$prefix) { + + $xscheduleResponse->setAttribute('xmlns:' . $prefix, $namespace); + + } + + foreach($recipients as $recipient=>$status) { + $xresponse = $dom->createElement('cal:response'); + + $xrecipient = $dom->createElement('cal:recipient'); + $xrecipient->appendChild($dom->createTextNode($recipient)); + $xresponse->appendChild($xrecipient); + + $xrequestStatus = $dom->createElement('cal:request-status'); + $xrequestStatus->appendChild($dom->createTextNode($status)); + $xresponse->appendChild($xrequestStatus); + + $xscheduleResponse->appendChild($xresponse); + + } + + return $dom->saveXML(); } diff --git a/3rdparty/Sabre/CalDAV/Principal/Collection.php b/3rdparty/Sabre/CalDAV/Principal/Collection.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php b/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php b/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Principal/User.php b/3rdparty/Sabre/CalDAV/Principal/User.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Schedule/IMip.php b/3rdparty/Sabre/CalDAV/Schedule/IMip.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php b/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Schedule/Outbox.php b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Server.php b/3rdparty/Sabre/CalDAV/Server.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/UserCalendars.php b/3rdparty/Sabre/CalDAV/UserCalendars.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CalDAV/Version.php b/3rdparty/Sabre/CalDAV/Version.php old mode 100644 new mode 100755 index 939e903c89..ace9901c08 --- a/3rdparty/Sabre/CalDAV/Version.php +++ b/3rdparty/Sabre/CalDAV/Version.php @@ -14,7 +14,7 @@ class Sabre_CalDAV_Version { /** * Full version number */ - const VERSION = '1.6.2'; + const VERSION = '1.6.4'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/CalDAV/includes.php b/3rdparty/Sabre/CalDAV/includes.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/AddressBook.php b/3rdparty/Sabre/CardDAV/AddressBook.php old mode 100644 new mode 100755 index 3b381e1eea..12297175a8 --- a/3rdparty/Sabre/CardDAV/AddressBook.php +++ b/3rdparty/Sabre/CardDAV/AddressBook.php @@ -108,7 +108,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca */ public function createFile($name,$vcardData = null) { - $vcardData = stream_get_contents($vcardData); + if (is_resource($vcardData)) { + $vcardData = stream_get_contents($vcardData); + } // Converting to UTF-8, if needed $vcardData = Sabre_DAV_StringUtil::ensureUTF8($vcardData); diff --git a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php old mode 100644 new mode 100755 index 85a4963127..46bb8ff18d --- a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php +++ b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php @@ -9,7 +9,7 @@ * @package Sabre * @subpackage CardDAV * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ class Sabre_CardDAV_AddressBookQueryParser { @@ -88,12 +88,22 @@ class Sabre_CardDAV_AddressBookQueryParser { if (is_nan($limit)) $limit = null; $filter = $this->xpath->query('/card:addressbook-query/card:filter'); - if ($filter->length !== 1) { + + // According to the CardDAV spec there needs to be exactly 1 filter + // element. However, KDE 4.8.2 contains a bug that will encode 0 filter + // elements, so this is a workaround for that. + // + // See: https://bugs.kde.org/show_bug.cgi?id=300047 + if ($filter->length === 0) { + $test = null; + $filter = null; + } elseif ($filter->length === 1) { + $filter = $filter->item(0); + $test = $this->xpath->evaluate('string(@test)', $filter); + } else { throw new Sabre_DAV_Exception_BadRequest('Only one filter element is allowed'); } - $filter = $filter->item(0); - $test = $this->xpath->evaluate('string(@test)', $filter); if (!$test) $test = self::TEST_ANYOF; if ($test !== self::TEST_ANYOF && $test !== self::TEST_ALLOF) { throw new Sabre_DAV_Exception_BadRequest('The test attribute must either hold "anyof" or "allof"'); diff --git a/3rdparty/Sabre/CardDAV/AddressBookRoot.php b/3rdparty/Sabre/CardDAV/AddressBookRoot.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/Backend/Abstract.php b/3rdparty/Sabre/CardDAV/Backend/Abstract.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/Backend/PDO.php b/3rdparty/Sabre/CardDAV/Backend/PDO.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/Card.php b/3rdparty/Sabre/CardDAV/Card.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/IAddressBook.php b/3rdparty/Sabre/CardDAV/IAddressBook.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/ICard.php b/3rdparty/Sabre/CardDAV/ICard.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/IDirectory.php b/3rdparty/Sabre/CardDAV/IDirectory.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/Plugin.php b/3rdparty/Sabre/CardDAV/Plugin.php old mode 100644 new mode 100755 index 9ebec243eb..96def6dd96 --- a/3rdparty/Sabre/CardDAV/Plugin.php +++ b/3rdparty/Sabre/CardDAV/Plugin.php @@ -52,6 +52,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin { $server->subscribeEvent('report', array($this,'report')); $server->subscribeEvent('onHTMLActionsPanel', array($this,'htmlActionsPanel')); $server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction')); + $server->subscribeEvent('beforeWriteContent', array($this, 'beforeWriteContent')); + $server->subscribeEvent('beforeCreateFile', array($this, 'beforeCreateFile')); /* Namespaces */ $server->xmlNamespaces[self::NS_CARDDAV] = 'card'; @@ -152,7 +154,10 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin { $val = stream_get_contents($val); // Taking out \r to not screw up the xml output - $returnedProperties[200][$addressDataProp] = str_replace("\r","", $val); + //$returnedProperties[200][$addressDataProp] = str_replace("\r","", $val); + // The stripping of \r breaks the Mail App in OSX Mountain Lion + // this is fixed in master, but not backported. /Tanghus + $returnedProperties[200][$addressDataProp] = $val; } } @@ -283,6 +288,81 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin { } + /** + * This method is triggered before a file gets updated with new content. + * + * This plugin uses this method to ensure that Card nodes receive valid + * vcard data. + * + * @param string $path + * @param Sabre_DAV_IFile $node + * @param resource $data + * @return void + */ + public function beforeWriteContent($path, Sabre_DAV_IFile $node, &$data) { + + if (!$node instanceof Sabre_CardDAV_ICard) + return; + + $this->validateVCard($data); + + } + + /** + * This method is triggered before a new file is created. + * + * This plugin uses this method to ensure that Card nodes receive valid + * vcard data. + * + * @param string $path + * @param resource $data + * @param Sabre_DAV_ICollection $parentNode + * @return void + */ + public function beforeCreateFile($path, &$data, Sabre_DAV_ICollection $parentNode) { + + if (!$parentNode instanceof Sabre_CardDAV_IAddressBook) + return; + + $this->validateVCard($data); + + } + + /** + * Checks if the submitted iCalendar data is in fact, valid. + * + * An exception is thrown if it's not. + * + * @param resource|string $data + * @return void + */ + protected function validateVCard(&$data) { + + // If it's a stream, we convert it to a string first. + if (is_resource($data)) { + $data = stream_get_contents($data); + } + + // Converting the data to unicode, if needed. + $data = Sabre_DAV_StringUtil::ensureUTF8($data); + + try { + + $vobj = Sabre_VObject_Reader::read($data); + + } catch (Sabre_VObject_ParseException $e) { + + throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid vcard data. Parse error: ' . $e->getMessage()); + + } + + if ($vobj->name !== 'VCARD') { + throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support vcard objects.'); + } + + } + + /** * This function handles the addressbook-query REPORT * @@ -362,6 +442,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin { $vcard = Sabre_VObject_Reader::read($vcardData); + if (!$filters) return true; + foreach($filters as $filter) { $isDefined = isset($vcard->{$filter['name']}); diff --git a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/UserAddressBooks.php b/3rdparty/Sabre/CardDAV/UserAddressBooks.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/CardDAV/Version.php b/3rdparty/Sabre/CardDAV/Version.php old mode 100644 new mode 100755 index 811b929e39..d0623f0d3e --- a/3rdparty/Sabre/CardDAV/Version.php +++ b/3rdparty/Sabre/CardDAV/Version.php @@ -16,7 +16,7 @@ class Sabre_CardDAV_Version { /** * Full version number */ - const VERSION = '1.6.1'; + const VERSION = '1.6.3'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/CardDAV/includes.php b/3rdparty/Sabre/CardDAV/includes.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Auth/Backend/File.php b/3rdparty/Sabre/DAV/Auth/Backend/File.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Auth/IBackend.php b/3rdparty/Sabre/DAV/Auth/IBackend.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Auth/Plugin.php b/3rdparty/Sabre/DAV/Auth/Plugin.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/GuessContentType.php b/3rdparty/Sabre/DAV/Browser/GuessContentType.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/Plugin.php b/3rdparty/Sabre/DAV/Browser/Plugin.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/assets/favicon.ico b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/card.png b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/file.png b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Client.php b/3rdparty/Sabre/DAV/Client.php old mode 100644 new mode 100755 index 075e84caa1..9a428765e9 --- a/3rdparty/Sabre/DAV/Client.php +++ b/3rdparty/Sabre/DAV/Client.php @@ -11,7 +11,7 @@ * @package Sabre * @subpackage DAVClient * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ class Sabre_DAV_Client { @@ -23,6 +23,28 @@ class Sabre_DAV_Client { protected $password; protected $proxy; + /** + * Basic authentication + */ + const AUTH_BASIC = 1; + + /** + * Digest authentication + */ + const AUTH_DIGEST = 2; + + /** + * The authentication type we're using. + * + * This is a bitmask of AUTH_BASIC and AUTH_DIGEST. + * + * If DIGEST is used, the client makes 1 extra request per request, to get + * the authentication tokens. + * + * @var int + */ + protected $authType; + /** * Constructor * @@ -46,16 +68,21 @@ class Sabre_DAV_Client { 'baseUri', 'userName', 'password', - 'proxy' + 'proxy', ); - foreach($validSettings as $validSetting) { if (isset($settings[$validSetting])) { $this->$validSetting = $settings[$validSetting]; } } + if (isset($settings['authType'])) { + $this->authType = $settings['authType']; + } else { + $this->authType = self::AUTH_BASIC | self::AUTH_DIGEST; + } + $this->propertyMap['{DAV:}resourcetype'] = 'Sabre_DAV_Property_ResourceType'; } @@ -250,14 +277,9 @@ class Sabre_DAV_Client { // Automatically follow redirects CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 5, - CURLOPT_SSL_VERIFYPEER => true, - //CURLOPT_SSL_VERIFYPEER => false, ); switch ($method) { - case 'PUT': - $curlSettings[CURLOPT_PUT] = true; - break; case 'HEAD' : // do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD @@ -288,8 +310,15 @@ class Sabre_DAV_Client { $curlSettings[CURLOPT_PROXY] = $this->proxy; } - if ($this->userName) { - $curlSettings[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC | CURLAUTH_DIGEST; + if ($this->userName && $this->authType) { + $curlType = 0; + if ($this->authType & self::AUTH_BASIC) { + $curlType |= CURLAUTH_BASIC; + } + if ($this->authType & self::AUTH_DIGEST) { + $curlType |= CURLAUTH_DIGEST; + } + $curlSettings[CURLOPT_HTTPAUTH] = $curlType; $curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password; } diff --git a/3rdparty/Sabre/DAV/Collection.php b/3rdparty/Sabre/DAV/Collection.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Directory.php b/3rdparty/Sabre/DAV/Directory.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception.php b/3rdparty/Sabre/DAV/Exception.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/BadRequest.php b/3rdparty/Sabre/DAV/Exception/BadRequest.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/Conflict.php b/3rdparty/Sabre/DAV/Exception/Conflict.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/FileNotFound.php b/3rdparty/Sabre/DAV/Exception/FileNotFound.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/Forbidden.php b/3rdparty/Sabre/DAV/Exception/Forbidden.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/Locked.php b/3rdparty/Sabre/DAV/Exception/Locked.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/NotFound.php b/3rdparty/Sabre/DAV/Exception/NotFound.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/NotImplemented.php b/3rdparty/Sabre/DAV/Exception/NotImplemented.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/PaymentRequired.php b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php b/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/FS/Directory.php b/3rdparty/Sabre/DAV/FS/Directory.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/FS/File.php b/3rdparty/Sabre/DAV/FS/File.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/FS/Node.php b/3rdparty/Sabre/DAV/FS/Node.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/FSExt/Directory.php b/3rdparty/Sabre/DAV/FSExt/Directory.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/FSExt/File.php b/3rdparty/Sabre/DAV/FSExt/File.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/FSExt/Node.php b/3rdparty/Sabre/DAV/FSExt/Node.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/File.php b/3rdparty/Sabre/DAV/File.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/ICollection.php b/3rdparty/Sabre/DAV/ICollection.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/IExtendedCollection.php b/3rdparty/Sabre/DAV/IExtendedCollection.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/IFile.php b/3rdparty/Sabre/DAV/IFile.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/INode.php b/3rdparty/Sabre/DAV/INode.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/IProperties.php b/3rdparty/Sabre/DAV/IProperties.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/IQuota.php b/3rdparty/Sabre/DAV/IQuota.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Locks/Backend/FS.php b/3rdparty/Sabre/DAV/Locks/Backend/FS.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Locks/Backend/File.php b/3rdparty/Sabre/DAV/Locks/Backend/File.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Locks/LockInfo.php b/3rdparty/Sabre/DAV/Locks/LockInfo.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Locks/Plugin.php b/3rdparty/Sabre/DAV/Locks/Plugin.php old mode 100644 new mode 100755 index fd956950b8..035b3a6386 --- a/3rdparty/Sabre/DAV/Locks/Plugin.php +++ b/3rdparty/Sabre/DAV/Locks/Plugin.php @@ -292,7 +292,10 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin { $this->server->tree->getNodeForPath($uri); // We need to call the beforeWriteContent event for RFC3744 - $this->server->broadcastEvent('beforeWriteContent',array($uri)); + // Edit: looks like this is not used, and causing problems now. + // + // See Issue 222 + // $this->server->broadcastEvent('beforeWriteContent',array($uri)); } catch (Sabre_DAV_Exception_NotFound $e) { diff --git a/3rdparty/Sabre/DAV/Mount/Plugin.php b/3rdparty/Sabre/DAV/Mount/Plugin.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Node.php b/3rdparty/Sabre/DAV/Node.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/ObjectTree.php b/3rdparty/Sabre/DAV/ObjectTree.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property.php b/3rdparty/Sabre/DAV/Property.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/GetLastModified.php b/3rdparty/Sabre/DAV/Property/GetLastModified.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/Href.php b/3rdparty/Sabre/DAV/Property/Href.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/HrefList.php b/3rdparty/Sabre/DAV/Property/HrefList.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/IHref.php b/3rdparty/Sabre/DAV/Property/IHref.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/LockDiscovery.php b/3rdparty/Sabre/DAV/Property/LockDiscovery.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/ResourceType.php b/3rdparty/Sabre/DAV/Property/ResourceType.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/Response.php b/3rdparty/Sabre/DAV/Property/Response.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/ResponseList.php b/3rdparty/Sabre/DAV/Property/ResponseList.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/SupportedLock.php b/3rdparty/Sabre/DAV/Property/SupportedLock.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Server.php b/3rdparty/Sabre/DAV/Server.php old mode 100644 new mode 100755 index 50b190e8fa..0dfac8b0c7 --- a/3rdparty/Sabre/DAV/Server.php +++ b/3rdparty/Sabre/DAV/Server.php @@ -215,7 +215,7 @@ class Sabre_DAV_Server { $DOM->appendChild($error); $error->appendChild($DOM->createElement('s:exception',get_class($e))); - $error->appendChild($DOM->createElement('s:message',htmlentities($e->getMessage()))); + $error->appendChild($DOM->createElement('s:message',$e->getMessage())); if ($this->debugExceptions) { $error->appendChild($DOM->createElement('s:file',$e->getFile())); $error->appendChild($DOM->createElement('s:line',$e->getLine())); @@ -1784,7 +1784,14 @@ class Sabre_DAV_Server { $etag = $node->getETag(); if ($etag===$ifMatchItem) { $haveMatch = true; + } else { + // Evolution has a bug where it sometimes prepends the " + // with a \. This is our workaround. + if (str_replace('\\"','"', $ifMatchItem) === $etag) { + $haveMatch = true; + } } + } if (!$haveMatch) { throw new Sabre_DAV_Exception_PreconditionFailed('An If-Match header was specified, but none of the specified the ETags matched.','If-Match'); diff --git a/3rdparty/Sabre/DAV/ServerPlugin.php b/3rdparty/Sabre/DAV/ServerPlugin.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/SimpleCollection.php b/3rdparty/Sabre/DAV/SimpleCollection.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/SimpleDirectory.php b/3rdparty/Sabre/DAV/SimpleDirectory.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/SimpleFile.php b/3rdparty/Sabre/DAV/SimpleFile.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/StringUtil.php b/3rdparty/Sabre/DAV/StringUtil.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Tree.php b/3rdparty/Sabre/DAV/Tree.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Tree/Filesystem.php b/3rdparty/Sabre/DAV/Tree/Filesystem.php old mode 100644 new mode 100755 index 85a9ee317b..40580ae366 --- a/3rdparty/Sabre/DAV/Tree/Filesystem.php +++ b/3rdparty/Sabre/DAV/Tree/Filesystem.php @@ -42,9 +42,9 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree { $realPath = $this->getRealPath($path); if (!file_exists($realPath)) throw new Sabre_DAV_Exception_NotFound('File at location ' . $realPath . ' not found'); if (is_dir($realPath)) { - return new Sabre_DAV_FS_Directory($path); + return new Sabre_DAV_FS_Directory($realPath); } else { - return new Sabre_DAV_FS_File($path); + return new Sabre_DAV_FS_File($realPath); } } diff --git a/3rdparty/Sabre/DAV/URLUtil.php b/3rdparty/Sabre/DAV/URLUtil.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/UUIDUtil.php b/3rdparty/Sabre/DAV/UUIDUtil.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/Version.php b/3rdparty/Sabre/DAV/Version.php old mode 100644 new mode 100755 index 5e5d15e403..274646240a --- a/3rdparty/Sabre/DAV/Version.php +++ b/3rdparty/Sabre/DAV/Version.php @@ -14,7 +14,7 @@ class Sabre_DAV_Version { /** * Full version number */ - const VERSION = '1.6.2'; + const VERSION = '1.6.4'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/DAV/XMLUtil.php b/3rdparty/Sabre/DAV/XMLUtil.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAV/includes.php b/3rdparty/Sabre/DAV/includes.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php b/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Exception/AceConflict.php b/3rdparty/Sabre/DAVACL/Exception/AceConflict.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php b/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php b/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php b/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php b/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/IACL.php b/3rdparty/Sabre/DAVACL/IACL.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/IPrincipal.php b/3rdparty/Sabre/DAVACL/IPrincipal.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/IPrincipalBackend.php b/3rdparty/Sabre/DAVACL/IPrincipalBackend.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Plugin.php b/3rdparty/Sabre/DAVACL/Plugin.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Principal.php b/3rdparty/Sabre/DAVACL/Principal.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php b/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/PrincipalCollection.php b/3rdparty/Sabre/DAVACL/PrincipalCollection.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Property/Acl.php b/3rdparty/Sabre/DAVACL/Property/Acl.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php b/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Property/Principal.php b/3rdparty/Sabre/DAVACL/Property/Principal.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/Version.php b/3rdparty/Sabre/DAVACL/Version.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/DAVACL/includes.php b/3rdparty/Sabre/DAVACL/includes.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/HTTP/AWSAuth.php b/3rdparty/Sabre/HTTP/AWSAuth.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/HTTP/AbstractAuth.php b/3rdparty/Sabre/HTTP/AbstractAuth.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/HTTP/BasicAuth.php b/3rdparty/Sabre/HTTP/BasicAuth.php old mode 100644 new mode 100755 index a747cc6a31..f90ed24f5d --- a/3rdparty/Sabre/HTTP/BasicAuth.php +++ b/3rdparty/Sabre/HTTP/BasicAuth.php @@ -46,7 +46,7 @@ class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth { if (strpos(strtolower($auth),'basic')!==0) return false; - return explode(':', base64_decode(substr($auth, 6))); + return explode(':', base64_decode(substr($auth, 6)),2); } diff --git a/3rdparty/Sabre/HTTP/DigestAuth.php b/3rdparty/Sabre/HTTP/DigestAuth.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/HTTP/Request.php b/3rdparty/Sabre/HTTP/Request.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/HTTP/Response.php b/3rdparty/Sabre/HTTP/Response.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/HTTP/Util.php b/3rdparty/Sabre/HTTP/Util.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/HTTP/Version.php b/3rdparty/Sabre/HTTP/Version.php old mode 100644 new mode 100755 index 23dc7f8a7a..e6b4f7e535 --- a/3rdparty/Sabre/HTTP/Version.php +++ b/3rdparty/Sabre/HTTP/Version.php @@ -14,7 +14,7 @@ class Sabre_HTTP_Version { /** * Full version number */ - const VERSION = '1.6.2'; + const VERSION = '1.6.4'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/HTTP/includes.php b/3rdparty/Sabre/HTTP/includes.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Component.php b/3rdparty/Sabre/VObject/Component.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Component/VAlarm.php b/3rdparty/Sabre/VObject/Component/VAlarm.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Component/VCalendar.php b/3rdparty/Sabre/VObject/Component/VCalendar.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Component/VEvent.php b/3rdparty/Sabre/VObject/Component/VEvent.php old mode 100644 new mode 100755 index 4cc1e36d7d..d6b910874d --- a/3rdparty/Sabre/VObject/Component/VEvent.php +++ b/3rdparty/Sabre/VObject/Component/VEvent.php @@ -42,14 +42,15 @@ class Sabre_VObject_Component_VEvent extends Sabre_VObject_Component { $effectiveStart = $this->DTSTART->getDateTime(); if (isset($this->DTEND)) { + + // The DTEND property is considered non inclusive. So for a 3 day + // event in july, dtstart and dtend would have to be July 1st and + // July 4th respectively. + // + // See: + // http://tools.ietf.org/html/rfc5545#page-54 $effectiveEnd = $this->DTEND->getDateTime(); - // If this was an all-day event, we should just increase the - // end-date by 1. Otherwise the event will last until the second - // the date changed, by increasing this by 1 day the event lasts - // all of the last day as well. - if ($this->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE) { - $effectiveEnd->modify('+1 day'); - } + } elseif (isset($this->DURATION)) { $effectiveEnd = clone $effectiveStart; $effectiveEnd->add( Sabre_VObject_DateTimeParser::parseDuration($this->DURATION) ); diff --git a/3rdparty/Sabre/VObject/Component/VJournal.php b/3rdparty/Sabre/VObject/Component/VJournal.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Component/VTodo.php b/3rdparty/Sabre/VObject/Component/VTodo.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/DateTimeParser.php b/3rdparty/Sabre/VObject/DateTimeParser.php old mode 100644 new mode 100755 index 1e2d54ef3a..23a4bb6991 --- a/3rdparty/Sabre/VObject/DateTimeParser.php +++ b/3rdparty/Sabre/VObject/DateTimeParser.php @@ -125,6 +125,9 @@ class Sabre_VObject_DateTimeParser { } + if ($duration==='P') { + $duration = 'PT0S'; + } $iv = new DateInterval($duration); if ($invert) $iv->invert = true; @@ -150,6 +153,7 @@ class Sabre_VObject_DateTimeParser { } $newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur); + if ($newDur === '+') { $newDur = '+0 seconds'; }; return $newDur; } diff --git a/3rdparty/Sabre/VObject/Element.php b/3rdparty/Sabre/VObject/Element.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Element/DateTime.php b/3rdparty/Sabre/VObject/Element/DateTime.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Element/MultiDateTime.php b/3rdparty/Sabre/VObject/Element/MultiDateTime.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/ElementList.php b/3rdparty/Sabre/VObject/ElementList.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/FreeBusyGenerator.php b/3rdparty/Sabre/VObject/FreeBusyGenerator.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Node.php b/3rdparty/Sabre/VObject/Node.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Parameter.php b/3rdparty/Sabre/VObject/Parameter.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/ParseException.php b/3rdparty/Sabre/VObject/ParseException.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Property.php b/3rdparty/Sabre/VObject/Property.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Property/DateTime.php b/3rdparty/Sabre/VObject/Property/DateTime.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Property/MultiDateTime.php b/3rdparty/Sabre/VObject/Property/MultiDateTime.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/Reader.php b/3rdparty/Sabre/VObject/Reader.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/RecurrenceIterator.php b/3rdparty/Sabre/VObject/RecurrenceIterator.php old mode 100644 new mode 100755 index 833aa091ab..740270dd8f --- a/3rdparty/Sabre/VObject/RecurrenceIterator.php +++ b/3rdparty/Sabre/VObject/RecurrenceIterator.php @@ -337,6 +337,8 @@ class Sabre_VObject_RecurrenceIterator implements Iterator { $this->endDate = clone $this->startDate; if (isset($this->baseEvent->DURATION)) { $this->endDate->add(Sabre_VObject_DateTimeParser::parse($this->baseEvent->DURATION->value)); + } elseif ($this->baseEvent->DTSTART->getDateType()===Sabre_VObject_Property_DateTime::DATE) { + $this->endDate->modify('+1 day'); } } $this->currentDate = clone $this->startDate; @@ -561,7 +563,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator { */ public function fastForward(DateTime $dt) { - while($this->valid() && $this->getDTEnd() < $dt) { + while($this->valid() && $this->getDTEnd() <= $dt) { $this->next(); } @@ -823,9 +825,40 @@ class Sabre_VObject_RecurrenceIterator implements Iterator { */ protected function nextYearly() { + $currentMonth = $this->currentDate->format('n'); + $currentYear = $this->currentDate->format('Y'); + $currentDayOfMonth = $this->currentDate->format('j'); + + // No sub-rules, so we just advance by year if (!$this->byMonth) { + + // Unless it was a leap day! + if ($currentMonth==2 && $currentDayOfMonth==29) { + + $counter = 0; + do { + $counter++; + // Here we increase the year count by the interval, until + // we hit a date that's also in a leap year. + // + // We could just find the next interval that's dividable by + // 4, but that would ignore the rule that there's no leap + // year every year that's dividable by a 100, but not by + // 400. (1800, 1900, 2100). So we just rely on the datetime + // functions instead. + $nextDate = clone $this->currentDate; + $nextDate->modify('+ ' . ($this->interval*$counter) . ' years'); + } while ($nextDate->format('n')!=2); + $this->currentDate = $nextDate; + + return; + + } + + // The easiest form $this->currentDate->modify('+' . $this->interval . ' years'); return; + } $currentMonth = $this->currentDate->format('n'); @@ -877,8 +910,8 @@ class Sabre_VObject_RecurrenceIterator implements Iterator { } else { - // no byDay or byMonthDay, so we can just loop through the - // months. + // These are the 'byMonth' rules, if there are no byDay or + // byMonthDay sub-rules. do { $currentMonth++; @@ -888,6 +921,7 @@ class Sabre_VObject_RecurrenceIterator implements Iterator { } } while (!in_array($currentMonth, $this->byMonth)); $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth); + return; } diff --git a/3rdparty/Sabre/VObject/Version.php b/3rdparty/Sabre/VObject/Version.php old mode 100644 new mode 100755 index 00110febc0..9ee03d8711 --- a/3rdparty/Sabre/VObject/Version.php +++ b/3rdparty/Sabre/VObject/Version.php @@ -14,7 +14,7 @@ class Sabre_VObject_Version { /** * Full version number */ - const VERSION = '1.3.2'; + const VERSION = '1.3.4'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/VObject/WindowsTimezoneMap.php b/3rdparty/Sabre/VObject/WindowsTimezoneMap.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/VObject/includes.php b/3rdparty/Sabre/VObject/includes.php old mode 100644 new mode 100755 diff --git a/3rdparty/Sabre/autoload.php b/3rdparty/Sabre/autoload.php old mode 100644 new mode 100755 diff --git a/3rdparty/class.phpmailer.php b/3rdparty/class.phpmailer.php index 4589cd791e..af089d5978 100644 --- a/3rdparty/class.phpmailer.php +++ b/3rdparty/class.phpmailer.php @@ -2,7 +2,7 @@ /*~ class.phpmailer.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | -| Version: 5.2 | +| Version: 5.2.1 | | Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ | | ------------------------------------------------------------------------- | | Admin: Jim Jagielski (project admininistrator) | @@ -10,7 +10,7 @@ | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net | | : Jim Jagielski (jimjag) jimjag@gmail.com | | Founder: Brent R. Matzelle (original founder) | -| Copyright (c) 2010-2011, Jim Jagielski. All Rights Reserved. | +| Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved. | | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. | | Copyright (c) 2001-2003, Brent R. Matzelle | | ------------------------------------------------------------------------- | @@ -29,7 +29,7 @@ * @author Andy Prevost * @author Marcus Bointon * @author Jim Jagielski - * @copyright 2010 - 2011 Jim Jagielski + * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost * @version $Id: class.phpmailer.php 450 2010-06-23 16:46:33Z coolbru $ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License @@ -129,6 +129,13 @@ class PHPMailer { */ protected $MIMEHeader = ''; + /** + * Stores the complete sent MIME message (Body and Headers) + * @var string + * @access protected + */ + protected $SentMIMEMessage = ''; + /** * Sets word wrapping on the body of the message to a given number of * characters. @@ -317,7 +324,7 @@ class PHPMailer { * Sets the PHPMailer Version number * @var string */ - public $Version = '5.2'; + public $Version = '5.2.1'; /** * What to use in the X-Mailer header @@ -460,7 +467,7 @@ class PHPMailer { * @return boolean */ public function AddReplyTo($address, $name = '') { - return $this->AddAnAddress('ReplyTo', $address, $name); + return $this->AddAnAddress('Reply-To', $address, $name); } /** @@ -473,12 +480,14 @@ class PHPMailer { * @access protected */ protected function AddAnAddress($kind, $address, $name = '') { - if (!preg_match('/^(to|cc|bcc|ReplyTo)$/', $kind)) { + if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) { $this->SetError($this->Lang('Invalid recipient array').': '.$kind); if ($this->exceptions) { throw new phpmailerException('Invalid recipient array: ' . $kind); } - echo $this->Lang('Invalid recipient array').': '.$kind; + if ($this->SMTPDebug) { + echo $this->Lang('Invalid recipient array').': '.$kind; + } return false; } $address = trim($address); @@ -488,10 +497,12 @@ class PHPMailer { if ($this->exceptions) { throw new phpmailerException($this->Lang('invalid_address').': '.$address); } - echo $this->Lang('invalid_address').': '.$address; + if ($this->SMTPDebug) { + echo $this->Lang('invalid_address').': '.$address; + } return false; } - if ($kind != 'ReplyTo') { + if ($kind != 'Reply-To') { if (!isset($this->all_recipients[strtolower($address)])) { array_push($this->$kind, array($address, $name)); $this->all_recipients[strtolower($address)] = true; @@ -520,14 +531,16 @@ class PHPMailer { if ($this->exceptions) { throw new phpmailerException($this->Lang('invalid_address').': '.$address); } - echo $this->Lang('invalid_address').': '.$address; + if ($this->SMTPDebug) { + echo $this->Lang('invalid_address').': '.$address; + } return false; } $this->From = $address; $this->FromName = $name; if ($auto) { if (empty($this->ReplyTo)) { - $this->AddAnAddress('ReplyTo', $address, $name); + $this->AddAnAddress('Reply-To', $address, $name); } if (empty($this->Sender)) { $this->Sender = $address; @@ -574,6 +587,7 @@ class PHPMailer { if(!$this->PreSend()) return false; return $this->PostSend(); } catch (phpmailerException $e) { + $this->SentMIMEMessage = ''; $this->SetError($e->getMessage()); if ($this->exceptions) { throw $e; @@ -584,6 +598,7 @@ class PHPMailer { protected function PreSend() { try { + $mailHeader = ""; if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL); } @@ -603,6 +618,19 @@ class PHPMailer { $this->MIMEHeader = $this->CreateHeader(); $this->MIMEBody = $this->CreateBody(); + // To capture the complete message when using mail(), create + // an extra header list which CreateHeader() doesn't fold in + if ($this->Mailer == 'mail') { + if (count($this->to) > 0) { + $mailHeader .= $this->AddrAppend("To", $this->to); + } else { + $mailHeader .= $this->HeaderLine("To", "undisclosed-recipients:;"); + } + $mailHeader .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader(trim($this->Subject)))); + // if(count($this->cc) > 0) { + // $mailHeader .= $this->AddrAppend("Cc", $this->cc); + // } + } // digitally sign with DKIM if enabled if ($this->DKIM_domain && $this->DKIM_private) { @@ -610,7 +638,9 @@ class PHPMailer { $this->MIMEHeader = str_replace("\r\n", "\n", $header_dkim) . $this->MIMEHeader; } + $this->SentMIMEMessage = sprintf("%s%s\r\n\r\n%s",$this->MIMEHeader,$mailHeader,$this->MIMEBody); return true; + } catch (phpmailerException $e) { $this->SetError($e->getMessage()); if ($this->exceptions) { @@ -628,6 +658,8 @@ class PHPMailer { return $this->SendmailSend($this->MIMEHeader, $this->MIMEBody); case 'smtp': return $this->SmtpSend($this->MIMEHeader, $this->MIMEBody); + case 'mail': + return $this->MailSend($this->MIMEHeader, $this->MIMEBody); default: return $this->MailSend($this->MIMEHeader, $this->MIMEBody); } @@ -637,7 +669,9 @@ class PHPMailer { if ($this->exceptions) { throw $e; } - echo $e->getMessage()."\n"; + if ($this->SMTPDebug) { + echo $e->getMessage()."\n"; + } return false; } } @@ -703,7 +737,7 @@ class PHPMailer { $to = implode(', ', $toArr); if (empty($this->Sender)) { - $params = "-oi -f %s"; + $params = "-oi "; } else { $params = sprintf("-oi -f %s", $this->Sender); } @@ -732,7 +766,7 @@ class PHPMailer { $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body); } } else { - $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); + $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); // implement call back function if it exists $isSent = ($rt == 1) ? 1 : 0; $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body); @@ -880,7 +914,9 @@ class PHPMailer { } } catch (phpmailerException $e) { $this->smtp->Reset(); - throw $e; + if ($this->exceptions) { + throw $e; + } } return true; } @@ -1159,7 +1195,7 @@ class PHPMailer { $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); } } - } + } $from = array(); $from[0][0] = trim($this->From); @@ -1177,7 +1213,7 @@ class PHPMailer { } if(count($this->ReplyTo) > 0) { - $result .= $this->AddrAppend('Reply-to', $this->ReplyTo); + $result .= $this->AddrAppend('Reply-To', $this->ReplyTo); } // mail() sets the subject itself @@ -1250,6 +1286,16 @@ class PHPMailer { return $result; } + /** + * Returns the MIME message (headers and body). Only really valid post PreSend(). + * @access public + * @return string + */ + public function GetSentMIMEMessage() { + return $this->SentMIMEMessage; + } + + /** * Assembles the message body. Returns an empty string on failure. * @access public @@ -1363,8 +1409,8 @@ class PHPMailer { $signed = tempnam("", "signed"); if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) { @unlink($file); - @unlink($signed); $body = file_get_contents($signed); + @unlink($signed); } else { @unlink($file); @unlink($signed); @@ -1487,7 +1533,9 @@ class PHPMailer { if ($this->exceptions) { throw $e; } - echo $e->getMessage()."\n"; + if ($this->SMTPDebug) { + echo $e->getMessage()."\n"; + } if ( $e->getCode() == self::STOP_CRITICAL ) { return false; } @@ -1590,15 +1638,23 @@ class PHPMailer { return false; } } - if (version_compare(PHP_VERSION, '5.3.0', '<')) { - $magic_quotes = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - } + $magic_quotes = get_magic_quotes_runtime(); + if ($magic_quotes) { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + set_magic_quotes_runtime(0); + } else { + ini_set('magic_quotes_runtime', 0); + } + } $file_buffer = file_get_contents($path); $file_buffer = $this->EncodeString($file_buffer, $encoding); - if (version_compare(PHP_VERSION, '5.3.0', '<')) { - set_magic_quotes_runtime($magic_quotes); - } + if ($magic_quotes) { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + set_magic_quotes_runtime($magic_quotes); + } else { + ini_set('magic_quotes_runtime', $magic_quotes); + } + } return $file_buffer; } catch (Exception $e) { $this->SetError($e->getMessage()); @@ -2154,7 +2210,7 @@ class PHPMailer { * @return $message */ public function MsgHTML($message, $basedir = '') { - preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images); + preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images); if(isset($images[2])) { foreach($images[2] as $i => $url) { // do not change urls for absolute images (thanks to corvuscorax) @@ -2168,20 +2224,23 @@ class PHPMailer { if ( strlen($basedir) > 1 && substr($basedir, -1) != '/') { $basedir .= '/'; } if ( strlen($directory) > 1 && substr($directory, -1) != '/') { $directory .= '/'; } if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType) ) { - $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message); + $message = preg_replace("/".$images[1][$i]."=[\"']".preg_quote($url, '/')."[\"']/Ui", $images[1][$i]."=\"".$cid."\"", $message); } } } } $this->IsHTML(true); $this->Body = $message; - $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message))); - if (!empty($textMsg) && empty($this->AltBody)) { - $this->AltBody = html_entity_decode($textMsg); - } + if (empty($this->AltBody)) { + $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message))); + if (!empty($textMsg)) { + $this->AltBody = html_entity_decode($textMsg, ENT_QUOTES, $this->CharSet); + } + } if (empty($this->AltBody)) { $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n"; } + return $message; } /** diff --git a/3rdparty/class.smtp.php b/3rdparty/class.smtp.php index 07c275936c..6977bffad1 100644 --- a/3rdparty/class.smtp.php +++ b/3rdparty/class.smtp.php @@ -2,7 +2,7 @@ /*~ class.smtp.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | -| Version: 5.2 | +| Version: 5.2.1 | | Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ | | ------------------------------------------------------------------------- | | Admin: Jim Jagielski (project admininistrator) | @@ -10,7 +10,7 @@ | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net | | : Jim Jagielski (jimjag) jimjag@gmail.com | | Founder: Brent R. Matzelle (original founder) | -| Copyright (c) 2010-2011, Jim Jagielski. All Rights Reserved. | +| Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved. | | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. | | Copyright (c) 2001-2003, Brent R. Matzelle | | ------------------------------------------------------------------------- | @@ -30,7 +30,7 @@ * @author Marcus Bointon * @copyright 2004 - 2008 Andy Prevost * @author Jim Jagielski - * @copyright 2010 - 2011 Jim Jagielski + * @copyright 2010 - 2012 Jim Jagielski * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL) * @version $Id: class.smtp.php 450 2010-06-23 16:46:33Z coolbru $ */ @@ -72,7 +72,7 @@ class SMTP { * Sets the SMTP PHPMailer Version number * @var string */ - public $Version = '5.2'; + public $Version = '5.2.1'; ///////////////////////////////////////////////// // PROPERTIES, PRIVATE AND PROTECTED @@ -797,7 +797,8 @@ class SMTP { */ private function get_lines() { $data = ""; - while($str = @fgets($this->smtp_conn,515)) { + while(!feof($this->smtp_conn)) { + $str = @fgets($this->smtp_conn,515); if($this->do_debug >= 4) { echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '
'; echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '
'; diff --git a/3rdparty/css/chosen-sprite.png b/3rdparty/css/chosen-sprite.png old mode 100644 new mode 100755 index f20db4439ea5c1038126bf326c8fd048b03a8226..113dc9885a6b864ac154b266f024b4597f5c6ae7 GIT binary patch delta 547 zcmV+;0^I%P1+N5<7k?-S1^@s6qPv;@0005@Nkl7_w z9?!Y=&fGw`Tn=~{*Ton1uJA6{0|TOO2&BQ5HsK)1f-8_=X@8PE=DxJX2wOssuBTi- ztctp_Icy10;>bvGb;1!tn9@9~RX8G2I%CwsHHDkCy0>$esIh1ra2i{pFWqk8J}}=x zVJbVkHT4^FdLL~5COic$#XOK)fH9ZCJz$&fPqt9leWXN5)R3h=VcKPcDb+TN-TaAg_f?;|FjQBh2T5*pKI{yFvKXc~Hw6wJT z{{AOVo_zoQeZqtZ&!0cvw{PF?-@ki%d;k6WS6EoMdiClhOP1WeeS7cTz4PYH`}FD4 zt5>h?-n~0()~rX59=&++V%xTD`T6-@zI<7}eEIzO^LOst`S@T)vFse zZ0PFhnmc#y*RNl9?AVc)msea|{PX9}Ns}gR+O%o+?%jtD9eVii;l+y=r%jvo;K760 zvu76+6kNZ4ed^SyPoF-WIC0|Z*ROy4_>r5N`~Lm=&!0c{_4O@WxbWAnUpYBBmoHy_ z_Uzfgg9n!`T{?O4j}$9Asc%4D@ty45_&F_R{g9Lk0qD52mW_e8hCD#Hn3?L-tbj`>OxT zJ7v;md~}?7W?s>W`VVqX@=db;D+pYCKd;4N)z`osoP6iyoB9teW8`B#?2;Ii#BfGM zL+6u_bqvF)z6Qwy7F^e#>{}{m61e02bdHnN$L$~3eq~pF@_OO1hcV%@q4${;^UfV+ znXY)w;%ghbu4vj9l}FCEd^hZyc+KPP6}AS4MsdBpQGw+X69gF?tV83O8O(MiJx^-A zboXW1bFqq*pAC;_YOi~??#RV$D!*(*_VfK;FjaJ|%YuJ~uPm<26>Fce&`YSSyXC`g zaTdR+Ec5IClowvmjG1!3;Krqz>yXh1n|0 tag. @@ -9,7 +9,7 @@ * Dual licensed under the MIT and GPL licenses, located in * MIT-LICENSE.txt and GPL-LICENSE.txt respectively. * - * Date: Mon Feb 6 22:40:40 2012 -0800 + * Date: Tue Sep 4 23:38:33 2012 -0700 * */ diff --git a/3rdparty/fullcalendar/js/fullcalendar.js b/3rdparty/fullcalendar/js/fullcalendar.js index 314f8c8a1a..d59de77c84 100644 --- a/3rdparty/fullcalendar/js/fullcalendar.js +++ b/3rdparty/fullcalendar/js/fullcalendar.js @@ -1,6 +1,6 @@ /** * @preserve - * FullCalendar v1.5.3 + * FullCalendar v1.5.4 * http://arshaw.com/fullcalendar/ * * Use fullcalendar.css for basic styling. @@ -11,7 +11,7 @@ * Dual licensed under the MIT and GPL licenses, located in * MIT-LICENSE.txt and GPL-LICENSE.txt respectively. * - * Date: Mon Feb 6 22:40:40 2012 -0800 + * Date: Tue Sep 4 23:38:33 2012 -0700 * */ @@ -111,7 +111,7 @@ var rtlDefaults = { -var fc = $.fullCalendar = { version: "1.5.3" }; +var fc = $.fullCalendar = { version: "1.5.4" }; var fcViews = fc.views = {}; @@ -1658,7 +1658,7 @@ function sliceSegs(events, visEventEnds, start, end) { msLength: segEnd - segStart }); } - } + } return segs.sort(segCmp); } @@ -1742,29 +1742,26 @@ function setOuterHeight(element, height, includeMargins) { } -// TODO: curCSS has been deprecated (jQuery 1.4.3 - 10/16/2010) - - function hsides(element, includeMargins) { return hpadding(element) + hborders(element) + (includeMargins ? hmargins(element) : 0); } function hpadding(element) { - return (parseFloat($.curCSS(element[0], 'paddingLeft', true)) || 0) + - (parseFloat($.curCSS(element[0], 'paddingRight', true)) || 0); + return (parseFloat($.css(element[0], 'paddingLeft', true)) || 0) + + (parseFloat($.css(element[0], 'paddingRight', true)) || 0); } function hmargins(element) { - return (parseFloat($.curCSS(element[0], 'marginLeft', true)) || 0) + - (parseFloat($.curCSS(element[0], 'marginRight', true)) || 0); + return (parseFloat($.css(element[0], 'marginLeft', true)) || 0) + + (parseFloat($.css(element[0], 'marginRight', true)) || 0); } function hborders(element) { - return (parseFloat($.curCSS(element[0], 'borderLeftWidth', true)) || 0) + - (parseFloat($.curCSS(element[0], 'borderRightWidth', true)) || 0); + return (parseFloat($.css(element[0], 'borderLeftWidth', true)) || 0) + + (parseFloat($.css(element[0], 'borderRightWidth', true)) || 0); } @@ -1774,20 +1771,20 @@ function vsides(element, includeMargins) { function vpadding(element) { - return (parseFloat($.curCSS(element[0], 'paddingTop', true)) || 0) + - (parseFloat($.curCSS(element[0], 'paddingBottom', true)) || 0); + return (parseFloat($.css(element[0], 'paddingTop', true)) || 0) + + (parseFloat($.css(element[0], 'paddingBottom', true)) || 0); } function vmargins(element) { - return (parseFloat($.curCSS(element[0], 'marginTop', true)) || 0) + - (parseFloat($.curCSS(element[0], 'marginBottom', true)) || 0); + return (parseFloat($.css(element[0], 'marginTop', true)) || 0) + + (parseFloat($.css(element[0], 'marginBottom', true)) || 0); } function vborders(element) { - return (parseFloat($.curCSS(element[0], 'borderTopWidth', true)) || 0) + - (parseFloat($.curCSS(element[0], 'borderBottomWidth', true)) || 0); + return (parseFloat($.css(element[0], 'borderTopWidth', true)) || 0) + + (parseFloat($.css(element[0], 'borderBottomWidth', true)) || 0); } @@ -1956,7 +1953,6 @@ function firstDefined() { } - fcViews.month = MonthView; function MonthView(element, calendar) { @@ -4662,7 +4658,7 @@ function DayEventRenderer() { ""; } html += - "" + event.title + "" + + "" + htmlEscape(event.title) + "" + ""; if (seg.isEnd && isEventResizable(event)) { html += diff --git a/3rdparty/fullcalendar/js/fullcalendar.min.js b/3rdparty/fullcalendar/js/fullcalendar.min.js index df37bdfd80..da6c7c09fd 100644 --- a/3rdparty/fullcalendar/js/fullcalendar.min.js +++ b/3rdparty/fullcalendar/js/fullcalendar.min.js @@ -1,6 +1,6 @@ /* - FullCalendar v1.5.3 + FullCalendar v1.5.4 http://arshaw.com/fullcalendar/ Use fullcalendar.css for basic styling. @@ -11,7 +11,7 @@ Dual licensed under the MIT and GPL licenses, located in MIT-LICENSE.txt and GPL-LICENSE.txt respectively. - Date: Mon Feb 6 22:40:40 2012 -0800 + Date: Tue Sep 4 23:38:33 2012 -0700 */ (function(m,ma){function wb(a){m.extend(true,Ya,a)}function Yb(a,b,e){function d(k){if(E){u();q();na();S(k)}else f()}function f(){B=b.theme?"ui":"fc";a.addClass("fc");b.isRTL&&a.addClass("fc-rtl");b.theme&&a.addClass("ui-widget");E=m("

").prependTo(a);C=new Zb(X,b);(P=C.render())&&a.prepend(P);y(b.defaultView);m(window).resize(oa);t()||g()}function g(){setTimeout(function(){!n.start&&t()&&S()},0)}function l(){m(window).unbind("resize",oa);C.destroy(); @@ -39,10 +39,10 @@ a[12])*1E3);lb(e,b)}else{e.setUTCFullYear(a[1],a[3]?a[3]-1:0,a[5]||1);e.setUTCHo 10):0)}}function Oa(a,b,e){return ib(a,null,b,e)}function ib(a,b,e,d){d=d||Ya;var f=a,g=b,l,j=e.length,t,y,S,Q="";for(l=0;ll;y--)if(S=dc[e.substring(l,y)]){if(f)Q+=S(f,d);l=y-1;break}if(y==l)if(f)Q+=t}}return Q}function Ua(a){return a.end?ec(a.end,a.allDay):ba(N(a.start),1)}function ec(a,b){a=N(a);return b||a.getHours()||a.getMinutes()?ba(a,1):Ka(a)}function fc(a,b){return(b.msLength-a.msLength)*100+(a.event.start-b.event.start)}function Cb(a,b){return a.end>b.start&&a.starte&&td){y=N(d);Q=false}else{y=y;Q=true}f.push({event:j,start:t,end:y,isStart:S,isEnd:Q,msLength:y-t})}}return f.sort(fc)}function ob(a){var b=[],e,d=a.length,f,g,l,j;for(e=0;e=0;e--){d=a[b[e].toLowerCase()];if(d!== -ma)return d}return a[""]}function Qa(a){return a.replace(/&/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""").replace(/\n/g,"
")}function Ib(a){return a.id+"/"+a.className+"/"+a.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig,"")}function qb(a){a.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})}function ab(a){a.children().removeClass("fc-first fc-last").filter(":first-child").addClass("fc-first").end().filter(":last-child").addClass("fc-last")} +g._fci)!==ma){g._fci=ma;g=b[f];e(g.event,g.element,g);m(d.target).trigger(d)}d.stopPropagation()})}function Va(a,b,e){for(var d=0,f;d=0;e--){d=a[b[e].toLowerCase()];if(d!==ma)return d}return a[""]}function Qa(a){return a.replace(/&/g, +"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""").replace(/\n/g,"
")}function Ib(a){return a.id+"/"+a.className+"/"+a.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig,"")}function qb(a){a.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})}function ab(a){a.children().removeClass("fc-first fc-last").filter(":first-child").addClass("fc-first").end().filter(":last-child").addClass("fc-last")} function rb(a,b){a.each(function(e,d){d.className=d.className.replace(/^fc-\w*/,"fc-"+lc[b.getDay()])})}function Jb(a,b){var e=a.source||{},d=a.color,f=e.color,g=b("eventColor"),l=a.backgroundColor||d||e.backgroundColor||f||b("eventBackgroundColor")||g;d=a.borderColor||d||e.borderColor||f||b("eventBorderColor")||g;a=a.textColor||e.textColor||b("eventTextColor");b=[];l&&b.push("background-color:"+l);d&&b.push("border-color:"+d);a&&b.push("color:"+a);return b.join(";")}function $a(a,b,e){if(m.isFunction(a))a= [a];if(a){var d,f;for(d=0;d=e[t][0]&&g' + option.html + ''; + } else { + return ""; + } + }; + + AbstractChosen.prototype.results_update_field = function() { + this.result_clear_highlight(); + this.result_single_selected = null; + return this.results_build(); + }; + + AbstractChosen.prototype.results_toggle = function() { + if (this.results_showing) { + return this.results_hide(); + } else { + return this.results_show(); + } + }; + + AbstractChosen.prototype.results_search = function(evt) { + if (this.results_showing) { + return this.winnow_results(); + } else { + return this.results_show(); + } + }; + + AbstractChosen.prototype.keyup_checker = function(evt) { + var stroke, _ref; + stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; + this.search_field_scale(); + switch (stroke) { + case 8: + if (this.is_multiple && this.backstroke_length < 1 && this.choices > 0) { + return this.keydown_backstroke(); + } else if (!this.pending_backstroke) { + this.result_clear_highlight(); + return this.results_search(); + } + break; + case 13: + evt.preventDefault(); + if (this.results_showing) return this.result_select(evt); + break; + case 27: + if (this.results_showing) this.results_hide(); + return true; + case 9: + case 38: + case 40: + case 16: + case 91: + case 17: + break; + default: + return this.results_search(); + } + }; + + AbstractChosen.prototype.generate_field_id = function() { + var new_id; + new_id = this.generate_random_id(); + this.form_field.id = new_id; + return new_id; + }; + + AbstractChosen.prototype.generate_random_char = function() { + var chars, newchar, rand; + chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ"; + rand = Math.floor(Math.random() * chars.length); + return newchar = chars.substring(rand, rand + 1); + }; + + return AbstractChosen; + + })(); + + root.AbstractChosen = AbstractChosen; + +}).call(this); + +/* +Chosen source: generate output using 'cake build' +Copyright (c) 2011 by Harvest +*/ + +(function() { + var $, Chosen, get_side_border_padding, root, + __hasProp = Object.prototype.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; + + root = this; + + $ = jQuery; + + $.fn.extend({ + chosen: function(options) { + if ($.browser.msie && ($.browser.version === "6.0" || $.browser.version === "7.0")) { + return this; + } + return $(this).each(function(input_field) { + if (!($(this)).hasClass("chzn-done")) return new Chosen(this, options); + }); + } + }); + + Chosen = (function(_super) { + + __extends(Chosen, _super); + + function Chosen() { + Chosen.__super__.constructor.apply(this, arguments); + } + + Chosen.prototype.setup = function() { + this.form_field_jq = $(this.form_field); + return this.is_rtl = this.form_field_jq.hasClass("chzn-rtl"); + }; + + Chosen.prototype.finish_setup = function() { + return this.form_field_jq.addClass("chzn-done"); + }; + Chosen.prototype.set_up_html = function() { var container_div, dd_top, dd_width, sf_width; this.container_id = this.form_field.id.length ? this.form_field.id.replace(/(:|\.)/g, '_') : this.generate_field_id(); @@ -71,14 +308,11 @@ if (this.is_multiple) { container_div.html('
    '); } else { - container_div.html('' + this.default_text + '
      '); + container_div.html('' + this.default_text + '
        '); } this.form_field_jq.hide().after(container_div); this.container = $('#' + this.container_id); this.container.addClass("chzn-container-" + (this.is_multiple ? "multi" : "single")); - if (!this.is_multiple && this.form_field.options.length <= this.disable_search_threshold) { - this.container.addClass("chzn-container-single-nosearch"); - } this.dropdown = this.container.find('div.chzn-drop').first(); dd_top = this.container.height(); dd_width = this.f_width - get_side_border_padding(this.dropdown); @@ -102,83 +336,92 @@ }); } this.results_build(); - return this.set_tab_index(); + this.set_tab_index(); + return this.form_field_jq.trigger("liszt:ready", { + chosen: this + }); }; + Chosen.prototype.register_observers = function() { - this.container.mousedown(__bind(function(evt) { - return this.container_mousedown(evt); - }, this)); - this.container.mouseup(__bind(function(evt) { - return this.container_mouseup(evt); - }, this)); - this.container.mouseenter(__bind(function(evt) { - return this.mouse_enter(evt); - }, this)); - this.container.mouseleave(__bind(function(evt) { - return this.mouse_leave(evt); - }, this)); - this.search_results.mouseup(__bind(function(evt) { - return this.search_results_mouseup(evt); - }, this)); - this.search_results.mouseover(__bind(function(evt) { - return this.search_results_mouseover(evt); - }, this)); - this.search_results.mouseout(__bind(function(evt) { - return this.search_results_mouseout(evt); - }, this)); - this.form_field_jq.bind("liszt:updated", __bind(function(evt) { - return this.results_update_field(evt); - }, this)); - this.search_field.blur(__bind(function(evt) { - return this.input_blur(evt); - }, this)); - this.search_field.keyup(__bind(function(evt) { - return this.keyup_checker(evt); - }, this)); - this.search_field.keydown(__bind(function(evt) { - return this.keydown_checker(evt); - }, this)); + var _this = this; + this.container.mousedown(function(evt) { + return _this.container_mousedown(evt); + }); + this.container.mouseup(function(evt) { + return _this.container_mouseup(evt); + }); + this.container.mouseenter(function(evt) { + return _this.mouse_enter(evt); + }); + this.container.mouseleave(function(evt) { + return _this.mouse_leave(evt); + }); + this.search_results.mouseup(function(evt) { + return _this.search_results_mouseup(evt); + }); + this.search_results.mouseover(function(evt) { + return _this.search_results_mouseover(evt); + }); + this.search_results.mouseout(function(evt) { + return _this.search_results_mouseout(evt); + }); + this.form_field_jq.bind("liszt:updated", function(evt) { + return _this.results_update_field(evt); + }); + this.search_field.blur(function(evt) { + return _this.input_blur(evt); + }); + this.search_field.keyup(function(evt) { + return _this.keyup_checker(evt); + }); + this.search_field.keydown(function(evt) { + return _this.keydown_checker(evt); + }); if (this.is_multiple) { - this.search_choices.click(__bind(function(evt) { - return this.choices_click(evt); - }, this)); - return this.search_field.focus(__bind(function(evt) { - return this.input_focus(evt); - }, this)); + this.search_choices.click(function(evt) { + return _this.choices_click(evt); + }); + return this.search_field.focus(function(evt) { + return _this.input_focus(evt); + }); + } else { + return this.container.click(function(evt) { + return evt.preventDefault(); + }); } }; + Chosen.prototype.search_field_disabled = function() { - this.is_disabled = this.form_field_jq.attr('disabled'); + this.is_disabled = this.form_field_jq[0].disabled; if (this.is_disabled) { this.container.addClass('chzn-disabled'); - this.search_field.attr('disabled', true); + this.search_field[0].disabled = true; if (!this.is_multiple) { this.selected_item.unbind("focus", this.activate_action); } return this.close_field(); } else { this.container.removeClass('chzn-disabled'); - this.search_field.attr('disabled', false); + this.search_field[0].disabled = false; if (!this.is_multiple) { return this.selected_item.bind("focus", this.activate_action); } } }; + Chosen.prototype.container_mousedown = function(evt) { var target_closelink; if (!this.is_disabled) { target_closelink = evt != null ? ($(evt.target)).hasClass("search-choice-close") : false; - if (evt && evt.type === "mousedown") { + if (evt && evt.type === "mousedown" && !this.results_showing) { evt.stopPropagation(); } if (!this.pending_destroy_click && !target_closelink) { if (!this.active_field) { - if (this.is_multiple) { - this.search_field.val(""); - } + if (this.is_multiple) this.search_field.val(""); $(document).click(this.click_test_action); this.results_show(); - } else if (!this.is_multiple && evt && ($(evt.target) === this.selected_item || $(evt.target).parents("a.chzn-single").length)) { + } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chzn-single").length)) { evt.preventDefault(); this.results_toggle(); } @@ -188,37 +431,17 @@ } } }; + Chosen.prototype.container_mouseup = function(evt) { - if (evt.target.nodeName === "ABBR") { - return this.results_reset(evt); - } - }; - Chosen.prototype.mouse_enter = function() { - return this.mouse_on_container = true; - }; - Chosen.prototype.mouse_leave = function() { - return this.mouse_on_container = false; - }; - Chosen.prototype.input_focus = function(evt) { - if (!this.active_field) { - return setTimeout((__bind(function() { - return this.container_mousedown(); - }, this)), 50); - } - }; - Chosen.prototype.input_blur = function(evt) { - if (!this.mouse_on_container) { - this.active_field = false; - return setTimeout((__bind(function() { - return this.blur_test(); - }, this)), 100); - } + if (evt.target.nodeName === "ABBR") return this.results_reset(evt); }; + Chosen.prototype.blur_test = function(evt) { if (!this.active_field && this.container.hasClass("chzn-container-active")) { return this.close_field(); } }; + Chosen.prototype.close_field = function() { $(document).unbind("click", this.click_test_action); if (!this.is_multiple) { @@ -233,6 +456,7 @@ this.show_search_field_default(); return this.search_field_scale(); }; + Chosen.prototype.activate_field = function() { if (!this.is_multiple && !this.active_field) { this.search_field.attr("tabindex", this.selected_item.attr("tabindex")); @@ -243,6 +467,7 @@ this.search_field.val(this.search_field.val()); return this.search_field.focus(); }; + Chosen.prototype.test_active_click = function(evt) { if ($(evt.target).parents('#' + this.container_id).length) { return this.active_field = true; @@ -250,9 +475,9 @@ return this.close_field(); } }; + Chosen.prototype.results_build = function() { - var content, data, startTime, _i, _len, _ref; - startTime = new Date(); + var content, data, _i, _len, _ref; this.parsing = true; this.results_data = root.SelectParser.select_to_array(this.form_field); if (this.is_multiple && this.choices > 0) { @@ -260,6 +485,11 @@ this.choices = 0; } else if (!this.is_multiple) { this.selected_item.find("span").text(this.default_text); + if (this.form_field.options.length <= this.disable_search_threshold) { + this.container.addClass("chzn-container-single-nosearch"); + } else { + this.container.removeClass("chzn-container-single-nosearch"); + } } content = ''; _ref = this.results_data; @@ -272,10 +502,8 @@ if (data.selected && this.is_multiple) { this.choice_build(data); } else if (data.selected && !this.is_multiple) { - this.selected_item.find("span").text(data.text); - if (this.allow_single_deselect) { - this.selected_item.find("span").first().after(""); - } + this.selected_item.removeClass("chzn-default").find("span").text(data.text); + if (this.allow_single_deselect) this.single_deselect_control_build(); } } } @@ -285,6 +513,7 @@ this.search_results.html(content); return this.parsing = false; }; + Chosen.prototype.result_add_group = function(group) { if (!group.disabled) { group.dom_id = this.container_id + "_g_" + group.array_index; @@ -293,31 +522,7 @@ return ""; } }; - Chosen.prototype.result_add_option = function(option) { - var classes, style; - if (!option.disabled) { - option.dom_id = this.container_id + "_o_" + option.array_index; - classes = option.selected && this.is_multiple ? [] : ["active-result"]; - if (option.selected) { - classes.push("result-selected"); - } - if (option.group_array_index != null) { - classes.push("group-option"); - } - if (option.classes !== "") { - classes.push(option.classes); - } - style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : ""; - return '
      • ' + option.html + '
      • '; - } else { - return ""; - } - }; - Chosen.prototype.results_update_field = function() { - this.result_clear_highlight(); - this.result_single_selected = null; - return this.results_build(); - }; + Chosen.prototype.result_do_highlight = function(el) { var high_bottom, high_top, maxHeight, visible_bottom, visible_top; if (el.length) { @@ -336,19 +541,12 @@ } } }; + Chosen.prototype.result_clear_highlight = function() { - if (this.result_highlight) { - this.result_highlight.removeClass("highlighted"); - } + if (this.result_highlight) this.result_highlight.removeClass("highlighted"); return this.result_highlight = null; }; - Chosen.prototype.results_toggle = function() { - if (this.results_showing) { - return this.results_hide(); - } else { - return this.results_show(); - } - }; + Chosen.prototype.results_show = function() { var dd_top; if (!this.is_multiple) { @@ -367,6 +565,7 @@ this.search_field.val(this.search_field.val()); return this.winnow_results(); }; + Chosen.prototype.results_hide = function() { if (!this.is_multiple) { this.selected_item.removeClass("chzn-single-with-drop"); @@ -377,6 +576,7 @@ }); return this.results_showing = false; }; + Chosen.prototype.set_tab_index = function(el) { var ti; if (this.form_field_jq.attr("tabindex")) { @@ -390,6 +590,7 @@ } } }; + Chosen.prototype.show_search_field_default = function() { if (this.is_multiple && this.choices < 1 && !this.active_field) { this.search_field.val(this.default_text); @@ -399,6 +600,7 @@ return this.search_field.removeClass("default"); } }; + Chosen.prototype.search_results_mouseup = function(evt) { var target; target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); @@ -407,34 +609,38 @@ return this.result_select(evt); } }; + Chosen.prototype.search_results_mouseover = function(evt) { var target; target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); - if (target) { - return this.result_do_highlight(target); - } + if (target) return this.result_do_highlight(target); }; + Chosen.prototype.search_results_mouseout = function(evt) { if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) { return this.result_clear_highlight(); } }; + Chosen.prototype.choices_click = function(evt) { evt.preventDefault(); if (this.active_field && !($(evt.target).hasClass("search-choice" || $(evt.target).parents('.search-choice').first)) && !this.results_showing) { return this.results_show(); } }; + Chosen.prototype.choice_build = function(item) { - var choice_id, link; + var choice_id, link, + _this = this; choice_id = this.container_id + "_c_" + item.array_index; this.choices += 1; this.search_container.before('
      • ' + item.html + '
      • '); link = $('#' + choice_id).find("a").first(); - return link.click(__bind(function(evt) { - return this.choice_destroy_link_click(evt); - }, this)); + return link.click(function(evt) { + return _this.choice_destroy_link_click(evt); + }); }; + Chosen.prototype.choice_destroy_link_click = function(evt) { evt.preventDefault(); if (!this.is_disabled) { @@ -444,6 +650,7 @@ return evt.stopPropagation; } }; + Chosen.prototype.choice_destroy = function(link) { this.choices -= 1; this.show_search_field_default(); @@ -453,16 +660,17 @@ this.result_deselect(link.attr("rel")); return link.parents('li').first().remove(); }; + Chosen.prototype.results_reset = function(evt) { this.form_field.options[0].selected = true; this.selected_item.find("span").text(this.default_text); + if (!this.is_multiple) this.selected_item.addClass("chzn-default"); this.show_search_field_default(); $(evt.target).remove(); this.form_field_jq.trigger("change"); - if (this.active_field) { - return this.results_hide(); - } + if (this.active_field) return this.results_hide(); }; + Chosen.prototype.result_select = function(evt) { var high, high_id, item, position; if (this.result_highlight) { @@ -474,6 +682,7 @@ } else { this.search_results.find(".result-selected").removeClass("result-selected"); this.result_single_selected = high; + this.selected_item.removeClass("chzn-default"); } high.addClass("result-selected"); position = high_id.substr(high_id.lastIndexOf("_") + 1); @@ -484,24 +693,23 @@ this.choice_build(item); } else { this.selected_item.find("span").first().text(item.text); - if (this.allow_single_deselect) { - this.selected_item.find("span").first().after(""); - } - } - if (!(evt.metaKey && this.is_multiple)) { - this.results_hide(); + if (this.allow_single_deselect) this.single_deselect_control_build(); } + if (!(evt.metaKey && this.is_multiple)) this.results_hide(); this.search_field.val(""); this.form_field_jq.trigger("change"); return this.search_field_scale(); } }; + Chosen.prototype.result_activate = function(el) { return el.addClass("active-result"); }; + Chosen.prototype.result_deactivate = function(el) { return el.removeClass("active-result"); }; + Chosen.prototype.result_deselect = function(pos) { var result, result_data; result_data = this.results_data[pos]; @@ -514,30 +722,31 @@ this.form_field_jq.trigger("change"); return this.search_field_scale(); }; - Chosen.prototype.results_search = function(evt) { - if (this.results_showing) { - return this.winnow_results(); - } else { - return this.results_show(); + + Chosen.prototype.single_deselect_control_build = function() { + if (this.allow_single_deselect && this.selected_item.find("abbr").length < 1) { + return this.selected_item.find("span").first().after(""); } }; + Chosen.prototype.winnow_results = function() { - var found, option, part, parts, regex, result_id, results, searchText, startTime, startpos, text, zregex, _i, _j, _len, _len2, _ref; - startTime = new Date(); + var found, option, part, parts, regex, regexAnchor, result, result_id, results, searchText, startpos, text, zregex, _i, _j, _len, _len2, _ref; this.no_results_clear(); results = 0; searchText = this.search_field.val() === this.default_text ? "" : $('
        ').text($.trim(this.search_field.val())).html(); - regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); + regexAnchor = this.search_contains ? "" : "^"; + regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); _ref = this.results_data; for (_i = 0, _len = _ref.length; _i < _len; _i++) { option = _ref[_i]; if (!option.disabled && !option.empty) { if (option.group) { - $('#' + option.dom_id).hide(); + $('#' + option.dom_id).css('display', 'none'); } else if (!(this.is_multiple && option.selected)) { found = false; result_id = option.dom_id; + result = $("#" + result_id); if (regex.test(option.html)) { found = true; results += 1; @@ -561,18 +770,16 @@ } else { text = option.html; } - if ($("#" + result_id).html !== text) { - $("#" + result_id).html(text); - } - this.result_activate($("#" + result_id)); + result.html(text); + this.result_activate(result); if (option.group_array_index != null) { - $("#" + this.results_data[option.group_array_index].dom_id).show(); + $("#" + this.results_data[option.group_array_index].dom_id).css('display', 'list-item'); } } else { if (this.result_highlight && result_id === this.result_highlight.attr('id')) { this.result_clear_highlight(); } - this.result_deactivate($("#" + result_id)); + this.result_deactivate(result); } } } @@ -583,6 +790,7 @@ return this.winnow_results_set_highlight(); } }; + Chosen.prototype.winnow_results_clear = function() { var li, lis, _i, _len, _results; this.search_field.val(""); @@ -591,46 +799,49 @@ for (_i = 0, _len = lis.length; _i < _len; _i++) { li = lis[_i]; li = $(li); - _results.push(li.hasClass("group-result") ? li.show() : !this.is_multiple || !li.hasClass("result-selected") ? this.result_activate(li) : void 0); + if (li.hasClass("group-result")) { + _results.push(li.css('display', 'auto')); + } else if (!this.is_multiple || !li.hasClass("result-selected")) { + _results.push(this.result_activate(li)); + } else { + _results.push(void 0); + } } return _results; }; + Chosen.prototype.winnow_results_set_highlight = function() { var do_high, selected_results; if (!this.result_highlight) { selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : []; do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first(); - if (do_high != null) { - return this.result_do_highlight(do_high); - } + if (do_high != null) return this.result_do_highlight(do_high); } }; + Chosen.prototype.no_results = function(terms) { var no_results_html; no_results_html = $('
      • ' + this.results_none_found + ' ""
      • '); no_results_html.find("span").first().html(terms); return this.search_results.append(no_results_html); }; + Chosen.prototype.no_results_clear = function() { return this.search_results.find(".no-results").remove(); }; + Chosen.prototype.keydown_arrow = function() { var first_active, next_sib; if (!this.result_highlight) { first_active = this.search_results.find("li.active-result").first(); - if (first_active) { - this.result_do_highlight($(first_active)); - } + if (first_active) this.result_do_highlight($(first_active)); } else if (this.results_showing) { next_sib = this.result_highlight.nextAll("li.active-result").first(); - if (next_sib) { - this.result_do_highlight(next_sib); - } - } - if (!this.results_showing) { - return this.results_show(); + if (next_sib) this.result_do_highlight(next_sib); } + if (!this.results_showing) return this.results_show(); }; + Chosen.prototype.keyup_arrow = function() { var prev_sibs; if (!this.results_showing && !this.is_multiple) { @@ -640,13 +851,12 @@ if (prev_sibs.length) { return this.result_do_highlight(prev_sibs.first()); } else { - if (this.choices > 0) { - this.results_hide(); - } + if (this.choices > 0) this.results_hide(); return this.result_clear_highlight(); } } }; + Chosen.prototype.keydown_backstroke = function() { if (this.pending_backstroke) { this.choice_destroy(this.pending_backstroke.find("a").first()); @@ -656,59 +866,25 @@ return this.pending_backstroke.addClass("search-choice-focus"); } }; + Chosen.prototype.clear_backstroke = function() { if (this.pending_backstroke) { this.pending_backstroke.removeClass("search-choice-focus"); } return this.pending_backstroke = null; }; - Chosen.prototype.keyup_checker = function(evt) { - var stroke, _ref; - stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; - this.search_field_scale(); - switch (stroke) { - case 8: - if (this.is_multiple && this.backstroke_length < 1 && this.choices > 0) { - return this.keydown_backstroke(); - } else if (!this.pending_backstroke) { - this.result_clear_highlight(); - return this.results_search(); - } - break; - case 13: - evt.preventDefault(); - if (this.results_showing) { - return this.result_select(evt); - } - break; - case 27: - if (this.results_showing) { - return this.results_hide(); - } - break; - case 9: - case 38: - case 40: - case 16: - case 91: - case 17: - break; - default: - return this.results_search(); - } - }; + Chosen.prototype.keydown_checker = function(evt) { var stroke, _ref; stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; this.search_field_scale(); - if (stroke !== 8 && this.pending_backstroke) { - this.clear_backstroke(); - } + if (stroke !== 8 && this.pending_backstroke) this.clear_backstroke(); switch (stroke) { case 8: this.backstroke_length = this.search_field.val().length; break; case 9: + if (this.results_showing && !this.is_multiple) this.result_select(evt); this.mouse_on_container = false; break; case 13: @@ -723,6 +899,7 @@ break; } }; + Chosen.prototype.search_field_scale = function() { var dd_top, div, h, style, style_block, styles, w, _i, _len; if (this.is_multiple) { @@ -741,9 +918,7 @@ $('body').append(div); w = div.width() + 25; div.remove(); - if (w > this.f_width - 10) { - w = this.f_width - 10; - } + if (w > this.f_width - 10) w = this.f_width - 10; this.search_field.css({ 'width': w + 'px' }); @@ -753,12 +928,7 @@ }); } }; - Chosen.prototype.generate_field_id = function() { - var new_id; - new_id = this.generate_random_id(); - this.form_field.id = new_id; - return new_id; - }; + Chosen.prototype.generate_random_id = function() { var string; string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char(); @@ -767,91 +937,16 @@ } return string; }; - Chosen.prototype.generate_random_char = function() { - var chars, newchar, rand; - chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ"; - rand = Math.floor(Math.random() * chars.length); - return newchar = chars.substring(rand, rand + 1); - }; + return Chosen; - })(); + + })(AbstractChosen); + get_side_border_padding = function(elmt) { var side_border_padding; return side_border_padding = elmt.outerWidth() - elmt.width(); }; + root.get_side_border_padding = get_side_border_padding; -}).call(this); -(function() { - var SelectParser; - SelectParser = (function() { - function SelectParser() { - this.options_index = 0; - this.parsed = []; - } - SelectParser.prototype.add_node = function(child) { - if (child.nodeName === "OPTGROUP") { - return this.add_group(child); - } else { - return this.add_option(child); - } - }; - SelectParser.prototype.add_group = function(group) { - var group_position, option, _i, _len, _ref, _results; - group_position = this.parsed.length; - this.parsed.push({ - array_index: group_position, - group: true, - label: group.label, - children: 0, - disabled: group.disabled - }); - _ref = group.childNodes; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - option = _ref[_i]; - _results.push(this.add_option(option, group_position, group.disabled)); - } - return _results; - }; - SelectParser.prototype.add_option = function(option, group_position, group_disabled) { - if (option.nodeName === "OPTION") { - if (option.text !== "") { - if (group_position != null) { - this.parsed[group_position].children += 1; - } - this.parsed.push({ - array_index: this.parsed.length, - options_index: this.options_index, - value: option.value, - text: option.text, - html: option.innerHTML, - selected: option.selected, - disabled: group_disabled === true ? group_disabled : option.disabled, - group_array_index: group_position, - classes: option.className, - style: option.style.cssText - }); - } else { - this.parsed.push({ - array_index: this.parsed.length, - options_index: this.options_index, - empty: true - }); - } - return this.options_index += 1; - } - }; - return SelectParser; - })(); - SelectParser.select_to_array = function(select) { - var child, parser, _i, _len, _ref; - parser = new SelectParser(); - _ref = select.childNodes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - parser.add_node(child); - } - return parser.parsed; - }; - this.SelectParser = SelectParser; + }).call(this); diff --git a/3rdparty/js/chosen/chosen.jquery.min.js b/3rdparty/js/chosen/chosen.jquery.min.js old mode 100644 new mode 100755 index 371ee53e7a..9ba164cc47 --- a/3rdparty/js/chosen/chosen.jquery.min.js +++ b/3rdparty/js/chosen/chosen.jquery.min.js @@ -1,10 +1,10 @@ // Chosen, a Select Box Enhancer for jQuery and Protoype // by Patrick Filler for Harvest, http://getharvest.com // -// Version 0.9.5 +// Version 0.9.8 // Full source at https://github.com/harvesthq/chosen // Copyright (c) 2011 Harvest http://getharvest.com // MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md // This file is generated by `cake build`, do not edit it by hand. -(function(){var a,b,c,d,e=function(a,b){return function(){return a.apply(b,arguments)}};d=this,a=jQuery,a.fn.extend({chosen:function(c){return a.browser!=="msie"||a.browser.version!=="6.0"&&a.browser.version!=="7.0"?a(this).each(function(d){if(!a(this).hasClass("chzn-done"))return new b(this,c)}):this}}),b=function(){function b(b,c){this.form_field=b,this.options=c!=null?c:{},this.set_default_values(),this.form_field_jq=a(this.form_field),this.is_multiple=this.form_field.multiple,this.is_rtl=this.form_field_jq.hasClass("chzn-rtl"),this.default_text_default=this.form_field.multiple?"Select Some Options":"Select an Option",this.set_up_html(),this.register_observers(),this.form_field_jq.addClass("chzn-done")}b.prototype.set_default_values=function(){this.click_test_action=e(function(a){return this.test_active_click(a)},this),this.activate_action=e(function(a){return this.activate_field(a)},this),this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=this.options.allow_single_deselect!=null&&this.form_field.options[0].text===""?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.choices=0;return this.results_none_found=this.options.no_results_text||"No results match"},b.prototype.set_up_html=function(){var b,d,e,f;this.container_id=this.form_field.id.length?this.form_field.id.replace(/(:|\.)/g,"_"):this.generate_field_id(),this.container_id+="_chzn",this.f_width=this.form_field_jq.outerWidth(),this.default_text=this.form_field_jq.data("placeholder")?this.form_field_jq.data("placeholder"):this.default_text_default,b=a("
        ",{id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+this.f_width+"px;"}),this.is_multiple?b.html('
          '):b.html(''+this.default_text+'
            '),this.form_field_jq.hide().after(b),this.container=a("#"+this.container_id),this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single")),!this.is_multiple&&this.form_field.options.length<=this.disable_search_threshold&&this.container.addClass("chzn-container-single-nosearch"),this.dropdown=this.container.find("div.chzn-drop").first(),d=this.container.height(),e=this.f_width-c(this.dropdown),this.dropdown.css({width:e+"px",top:d+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),f=e-c(this.search_container)-c(this.search_field),this.search_field.css({width:f+"px"})),this.results_build();return this.set_tab_index()},b.prototype.register_observers=function(){this.container.mousedown(e(function(a){return this.container_mousedown(a)},this)),this.container.mouseup(e(function(a){return this.container_mouseup(a)},this)),this.container.mouseenter(e(function(a){return this.mouse_enter(a)},this)),this.container.mouseleave(e(function(a){return this.mouse_leave(a)},this)),this.search_results.mouseup(e(function(a){return this.search_results_mouseup(a)},this)),this.search_results.mouseover(e(function(a){return this.search_results_mouseover(a)},this)),this.search_results.mouseout(e(function(a){return this.search_results_mouseout(a)},this)),this.form_field_jq.bind("liszt:updated",e(function(a){return this.results_update_field(a)},this)),this.search_field.blur(e(function(a){return this.input_blur(a)},this)),this.search_field.keyup(e(function(a){return this.keyup_checker(a)},this)),this.search_field.keydown(e(function(a){return this.keydown_checker(a)},this));if(this.is_multiple){this.search_choices.click(e(function(a){return this.choices_click(a)},this));return this.search_field.focus(e(function(a){return this.input_focus(a)},this))}},b.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq.attr("disabled");if(this.is_disabled){this.container.addClass("chzn-disabled"),this.search_field.attr("disabled",!0),this.is_multiple||this.selected_item.unbind("focus",this.activate_action);return this.close_field()}this.container.removeClass("chzn-disabled"),this.search_field.attr("disabled",!1);if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},b.prototype.container_mousedown=function(b){var c;if(!this.is_disabled){c=b!=null?a(b.target).hasClass("search-choice-close"):!1,b&&b.type==="mousedown"&&b.stopPropagation();if(!this.pending_destroy_click&&!c){this.active_field?!this.is_multiple&&b&&(a(b.target)===this.selected_item||a(b.target).parents("a.chzn-single").length)&&(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).click(this.click_test_action),this.results_show());return this.activate_field()}return this.pending_destroy_click=!1}},b.prototype.container_mouseup=function(a){if(a.target.nodeName==="ABBR")return this.results_reset(a)},b.prototype.mouse_enter=function(){return this.mouse_on_container=!0},b.prototype.mouse_leave=function(){return this.mouse_on_container=!1},b.prototype.input_focus=function(a){if(!this.active_field)return setTimeout(e(function(){return this.container_mousedown()},this),50)},b.prototype.input_blur=function(a){if(!this.mouse_on_container){this.active_field=!1;return setTimeout(e(function(){return this.blur_test()},this),100)}},b.prototype.blur_test=function(a){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},b.prototype.close_field=function(){a(document).unbind("click",this.click_test_action),this.is_multiple||(this.selected_item.attr("tabindex",this.search_field.attr("tabindex")),this.search_field.attr("tabindex",-1)),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default();return this.search_field_scale()},b.prototype.activate_field=function(){!this.is_multiple&&!this.active_field&&(this.search_field.attr("tabindex",this.selected_item.attr("tabindex")),this.selected_item.attr("tabindex",-1)),this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val());return this.search_field.focus()},b.prototype.test_active_click=function(b){return a(b.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},b.prototype.results_build=function(){var a,b,c,e,f,g;c=new Date,this.parsing=!0,this.results_data=d.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||this.selected_item.find("span").text(this.default_text),a="",g=this.results_data;for(e=0,f=g.length;e')));this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.search_results.html(a);return this.parsing=!1},b.prototype.result_add_group=function(b){if(!b.disabled){b.dom_id=this.container_id+"_g_"+b.array_index;return'
          • '+a("
            ").text(b.label).html()+"
          • "}return""},b.prototype.result_add_option=function(a){var b,c;if(!a.disabled){a.dom_id=this.container_id+"_o_"+a.array_index,b=a.selected&&this.is_multiple?[]:["active-result"],a.selected&&b.push("result-selected"),a.group_array_index!=null&&b.push("group-option"),a.classes!==""&&b.push(a.classes),c=a.style.cssText!==""?' style="'+a.style+'"':"";return'
          • "+a.html+"
          • "}return""},b.prototype.results_update_field=function(){this.result_clear_highlight(),this.result_single_selected=null;return this.results_build()},b.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight();if(b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(c'+b.html+''),d=a("#"+c).find("a").first();return d.click(e(function(a){return this.choice_destroy_link_click(a)},this))},b.prototype.choice_destroy_link_click=function(b){b.preventDefault();if(!this.is_disabled){this.pending_destroy_click=!0;return this.choice_destroy(a(b.target))}return b.stopPropagation},b.prototype.choice_destroy=function(a){this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),this.result_deselect(a.attr("rel"));return a.parents("li").first().remove()},b.prototype.results_reset=function(b){this.form_field.options[0].selected=!0,this.selected_item.find("span").text(this.default_text),this.show_search_field_default(),a(b.target).remove(),this.form_field_jq.trigger("change");if(this.active_field)return this.results_hide()},b.prototype.result_select=function(a){var b,c,d,e;if(this.result_highlight){b=this.result_highlight,c=b.attr("id"),this.result_clear_highlight(),this.is_multiple?this.result_deactivate(b):(this.search_results.find(".result-selected").removeClass("result-selected"),this.result_single_selected=b),b.addClass("result-selected"),e=c.substr(c.lastIndexOf("_")+1),d=this.results_data[e],d.selected=!0,this.form_field.options[d.options_index].selected=!0,this.is_multiple?this.choice_build(d):(this.selected_item.find("span").first().text(d.text),this.allow_single_deselect&&this.selected_item.find("span").first().after('')),(!a.metaKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),this.form_field_jq.trigger("change");return this.search_field_scale()}},b.prototype.result_activate=function(a){return a.addClass("active-result")},b.prototype.result_deactivate=function(a){return a.removeClass("active-result")},b.prototype.result_deselect=function(b){var c,d;d=this.results_data[b],d.selected=!1,this.form_field.options[d.options_index].selected=!1,c=a("#"+this.container_id+"_o_"+b),c.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change");return this.search_field_scale()},b.prototype.results_search=function(a){return this.results_showing?this.winnow_results():this.results_show()},b.prototype.winnow_results=function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;j=new Date,this.no_results_clear(),h=0,i=this.search_field.val()===this.default_text?"":a("
            ").text(a.trim(this.search_field.val())).html(),f=new RegExp("^"+i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),m=new RegExp(i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),r=this.results_data;for(n=0,p=r.length;n=0||c.html.indexOf("[")===0){e=c.html.replace(/\[|\]/g,"").split(" ");if(e.length)for(o=0,q=e.length;o"+c.html.substr(k+i.length),l=l.substr(0,k)+""+l.substr(k)):l=c.html,a("#"+g).html!==l&&a("#"+g).html(l),this.result_activate(a("#"+g)),c.group_array_index!=null&&a("#"+this.results_data[c.group_array_index].dom_id).show()):(this.result_highlight&&g===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(a("#"+g)))}}return h<1&&i.length?this.no_results(i):this.winnow_results_set_highlight()},b.prototype.winnow_results_clear=function(){var b,c,d,e,f;this.search_field.val(""),c=this.search_results.find("li"),f=[];for(d=0,e=c.length;d'+this.results_none_found+' ""'),c.find("span").first().html(b);return this.search_results.append(c)},b.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},b.prototype.keydown_arrow=function(){var b,c;this.result_highlight?this.results_showing&&(c=this.result_highlight.nextAll("li.active-result").first(),c&&this.result_do_highlight(c)):(b=this.search_results.find("li.active-result").first(),b&&this.result_do_highlight(a(b)));if(!this.results_showing)return this.results_show()},b.prototype.keyup_arrow=function(){var a;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight){a=this.result_highlight.prevAll("li.active-result");if(a.length)return this.result_do_highlight(a.first());this.choices>0&&this.results_hide();return this.result_clear_highlight()}},b.prototype.keydown_backstroke=function(){if(this.pending_backstroke){this.choice_destroy(this.pending_backstroke.find("a").first());return this.clear_backstroke()}this.pending_backstroke=this.search_container.siblings("li.search-choice").last();return this.pending_backstroke.addClass("search-choice-focus")},b.prototype.clear_backstroke=function(){this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus");return this.pending_backstroke=null},b.prototype.keyup_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale();switch(b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke){this.result_clear_highlight();return this.results_search()}break;case 13:a.preventDefault();if(this.results_showing)return this.result_select(a);break;case 27:if(this.results_showing)return this.results_hide();break;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},b.prototype.keydown_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale(),b!==8&&this.pending_backstroke&&this.clear_backstroke();switch(b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},b.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(i=0,j=g.length;i",{style:f}),c.text(this.search_field.val()),a("body").append(c),h=c.width()+25,c.remove(),h>this.f_width-10&&(h=this.f_width-10),this.search_field.css({width:h+"px"}),b=this.container.height();return this.dropdown.css({top:b+"px"})}},b.prototype.generate_field_id=function(){var a;a=this.generate_random_id(),this.form_field.id=a;return a},b.prototype.generate_random_id=function(){var b;b="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(a("#"+b).length>0)b+=this.generate_random_char();return b},b.prototype.generate_random_char=function(){var a,b,c;a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",c=Math.floor(Math.random()*a.length);return b=a.substring(c,c+1)};return b}(),c=function(a){var b;return b=a.outerWidth()-a.width()},d.get_side_border_padding=c}).call(this),function(){var a;a=function(){function a(){this.options_index=0,this.parsed=[]}a.prototype.add_node=function(a){return a.nodeName==="OPTGROUP"?this.add_group(a):this.add_option(a)},a.prototype.add_group=function(a){var b,c,d,e,f,g;b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:a.label,children:0,disabled:a.disabled}),f=a.childNodes,g=[];for(d=0,e=f.length;d"+a.html+"")},a.prototype.results_update_field=function(){return this.result_clear_highlight(),this.result_single_selected=null,this.results_build()},a.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},a.prototype.results_search=function(a){return this.results_showing?this.winnow_results():this.results_show()},a.prototype.keyup_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale();switch(b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:a.preventDefault();if(this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},a.prototype.generate_field_id=function(){var a;return a=this.generate_random_id(),this.form_field.id=a,a},a.prototype.generate_random_char=function(){var a,b,c;return a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",c=Math.floor(Math.random()*a.length),b=a.substring(c,c+1)},a}(),b.AbstractChosen=a}.call(this),function(){var a,b,c,d,e=Object.prototype.hasOwnProperty,f=function(a,b){function d(){this.constructor=a}for(var c in b)e.call(b,c)&&(a[c]=b[c]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};d=this,a=jQuery,a.fn.extend({chosen:function(c){return!a.browser.msie||a.browser.version!=="6.0"&&a.browser.version!=="7.0"?a(this).each(function(d){if(!a(this).hasClass("chzn-done"))return new b(this,c)}):this}}),b=function(b){function e(){e.__super__.constructor.apply(this,arguments)}return f(e,b),e.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.is_rtl=this.form_field_jq.hasClass("chzn-rtl")},e.prototype.finish_setup=function(){return this.form_field_jq.addClass("chzn-done")},e.prototype.set_up_html=function(){var b,d,e,f;return this.container_id=this.form_field.id.length?this.form_field.id.replace(/(:|\.)/g,"_"):this.generate_field_id(),this.container_id+="_chzn",this.f_width=this.form_field_jq.outerWidth(),this.default_text=this.form_field_jq.data("placeholder")?this.form_field_jq.data("placeholder"):this.default_text_default,b=a("
            ",{id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+this.f_width+"px;"}),this.is_multiple?b.html('
              '):b.html(''+this.default_text+'
                '),this.form_field_jq.hide().after(b),this.container=a("#"+this.container_id),this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single")),this.dropdown=this.container.find("div.chzn-drop").first(),d=this.container.height(),e=this.f_width-c(this.dropdown),this.dropdown.css({width:e+"px",top:d+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),f=e-c(this.search_container)-c(this.search_field),this.search_field.css({width:f+"px"})),this.results_build(),this.set_tab_index(),this.form_field_jq.trigger("liszt:ready",{chosen:this})},e.prototype.register_observers=function(){var a=this;return this.container.mousedown(function(b){return a.container_mousedown(b)}),this.container.mouseup(function(b){return a.container_mouseup(b)}),this.container.mouseenter(function(b){return a.mouse_enter(b)}),this.container.mouseleave(function(b){return a.mouse_leave(b)}),this.search_results.mouseup(function(b){return a.search_results_mouseup(b)}),this.search_results.mouseover(function(b){return a.search_results_mouseover(b)}),this.search_results.mouseout(function(b){return a.search_results_mouseout(b)}),this.form_field_jq.bind("liszt:updated",function(b){return a.results_update_field(b)}),this.search_field.blur(function(b){return a.input_blur(b)}),this.search_field.keyup(function(b){return a.keyup_checker(b)}),this.search_field.keydown(function(b){return a.keydown_checker(b)}),this.is_multiple?(this.search_choices.click(function(b){return a.choices_click(b)}),this.search_field.focus(function(b){return a.input_focus(b)})):this.container.click(function(a){return a.preventDefault()})},e.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq[0].disabled;if(this.is_disabled)return this.container.addClass("chzn-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus",this.activate_action),this.close_field();this.container.removeClass("chzn-disabled"),this.search_field[0].disabled=!1;if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},e.prototype.container_mousedown=function(b){var c;if(!this.is_disabled)return c=b!=null?a(b.target).hasClass("search-choice-close"):!1,b&&b.type==="mousedown"&&!this.results_showing&&b.stopPropagation(),!this.pending_destroy_click&&!c?(this.active_field?!this.is_multiple&&b&&(a(b.target)[0]===this.selected_item[0]||a(b.target).parents("a.chzn-single").length)&&(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).click(this.click_test_action),this.results_show()),this.activate_field()):this.pending_destroy_click=!1},e.prototype.container_mouseup=function(a){if(a.target.nodeName==="ABBR")return this.results_reset(a)},e.prototype.blur_test=function(a){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},e.prototype.close_field=function(){return a(document).unbind("click",this.click_test_action),this.is_multiple||(this.selected_item.attr("tabindex",this.search_field.attr("tabindex")),this.search_field.attr("tabindex",-1)),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},e.prototype.activate_field=function(){return!this.is_multiple&&!this.active_field&&(this.search_field.attr("tabindex",this.selected_item.attr("tabindex")),this.selected_item.attr("tabindex",-1)),this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},e.prototype.test_active_click=function(b){return a(b.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},e.prototype.results_build=function(){var a,b,c,e,f;this.parsing=!0,this.results_data=d.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||(this.selected_item.find("span").text(this.default_text),this.form_field.options.length<=this.disable_search_threshold?this.container.addClass("chzn-container-single-nosearch"):this.container.removeClass("chzn-container-single-nosearch")),a="",f=this.results_data;for(c=0,e=f.length;c'+a("
                ").text(b.label).html()+"")},e.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight();if(b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(c'+b.html+''),d=a("#"+c).find("a").first(),d.click(function(a){return e.choice_destroy_link_click(a)})},e.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),this.is_disabled?b.stopPropagation:(this.pending_destroy_click=!0,this.choice_destroy(a(b.target)))},e.prototype.choice_destroy=function(a){return this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),this.result_deselect(a.attr("rel")),a.parents("li").first().remove()},e.prototype.results_reset=function(b){this.form_field.options[0].selected=!0,this.selected_item.find("span").text(this.default_text),this.is_multiple||this.selected_item.addClass("chzn-default"),this.show_search_field_default(),a(b.target).remove(),this.form_field_jq.trigger("change");if(this.active_field)return this.results_hide()},e.prototype.result_select=function(a){var b,c,d,e;if(this.result_highlight)return b=this.result_highlight,c=b.attr("id"),this.result_clear_highlight(),this.is_multiple?this.result_deactivate(b):(this.search_results.find(".result-selected").removeClass("result-selected"),this.result_single_selected=b,this.selected_item.removeClass("chzn-default")),b.addClass("result-selected"),e=c.substr(c.lastIndexOf("_")+1),d=this.results_data[e],d.selected=!0,this.form_field.options[d.options_index].selected=!0,this.is_multiple?this.choice_build(d):(this.selected_item.find("span").first().text(d.text),this.allow_single_deselect&&this.single_deselect_control_build()),(!a.metaKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),this.form_field_jq.trigger("change"),this.search_field_scale()},e.prototype.result_activate=function(a){return a.addClass("active-result")},e.prototype.result_deactivate=function(a){return a.removeClass("active-result")},e.prototype.result_deselect=function(b){var c,d;return d=this.results_data[b],d.selected=!1,this.form_field.options[d.options_index].selected=!1,c=a("#"+this.container_id+"_o_"+b),c.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change"),this.search_field_scale()},e.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect&&this.selected_item.find("abbr").length<1)return this.selected_item.find("span").first().after('')},e.prototype.winnow_results=function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;this.no_results_clear(),j=0,k=this.search_field.val()===this.default_text?"":a("
                ").text(a.trim(this.search_field.val())).html(),g=this.search_contains?"":"^",f=new RegExp(g+k.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),n=new RegExp(k.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),s=this.results_data;for(o=0,q=s.length;o=0||c.html.indexOf("[")===0){e=c.html.replace(/\[|\]/g,"").split(" ");if(e.length)for(p=0,r=e.length;p"+c.html.substr(l+k.length),m=m.substr(0,l)+""+m.substr(l)):m=c.html,h.html(m),this.result_activate(h),c.group_array_index!=null&&a("#"+this.results_data[c.group_array_index].dom_id).css("display","list-item")):(this.result_highlight&&i===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(h))}}return j<1&&k.length?this.no_results(k):this.winnow_results_set_highlight()},e.prototype.winnow_results_clear=function(){var b,c,d,e,f;this.search_field.val(""),c=this.search_results.find("li"),f=[];for(d=0,e=c.length;d'+this.results_none_found+' ""'),c.find("span").first().html(b),this.search_results.append(c)},e.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},e.prototype.keydown_arrow=function(){var b,c;this.result_highlight?this.results_showing&&(c=this.result_highlight.nextAll("li.active-result").first(),c&&this.result_do_highlight(c)):(b=this.search_results.find("li.active-result").first(),b&&this.result_do_highlight(a(b)));if(!this.results_showing)return this.results_show()},e.prototype.keyup_arrow=function(){var a;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight)return a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices>0&&this.results_hide(),this.result_clear_highlight())},e.prototype.keydown_backstroke=function(){return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(this.pending_backstroke=this.search_container.siblings("li.search-choice").last(),this.pending_backstroke.addClass("search-choice-focus"))},e.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},e.prototype.keydown_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale(),b!==8&&this.pending_backstroke&&this.clear_backstroke();switch(b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},e.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(i=0,j=g.length;i",{style:f}),c.text(this.search_field.val()),a("body").append(c),h=c.width()+25,c.remove(),h>this.f_width-10&&(h=this.f_width-10),this.search_field.css({width:h+"px"}),b=this.container.height(),this.dropdown.css({top:b+"px"})}},e.prototype.generate_random_id=function(){var b;b="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(a("#"+b).length>0)b+=this.generate_random_char();return b},e}(AbstractChosen),c=function(a){var b;return b=a.outerWidth()-a.width()},d.get_side_border_padding=c}.call(this) \ No newline at end of file diff --git a/3rdparty/miniColors/GPL-LICENSE.txt b/3rdparty/miniColors/GPL-LICENSE.txt new file mode 100644 index 0000000000..11dddd00ef --- /dev/null +++ b/3rdparty/miniColors/GPL-LICENSE.txt @@ -0,0 +1,278 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. diff --git a/3rdparty/miniColors/MIT-LICENSE.txt b/3rdparty/miniColors/MIT-LICENSE.txt new file mode 100644 index 0000000000..ec6f758157 --- /dev/null +++ b/3rdparty/miniColors/MIT-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) Cory LaViska + +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/3rdparty/miniColors/css/images/colors.png b/3rdparty/miniColors/css/images/colors.png new file mode 100755 index 0000000000000000000000000000000000000000..deb50a9ae102938cadf7aa93824d1527536b77b8 GIT binary patch literal 12973 zcmV;eGE&WnP)&PG2V2$-#)jds#v0Btk^1`P=irlfjhmQ?AS@CY-%wBv^~TD-E+ z=v&CT5&nv}?uWF)LmI98-~ax(zA38|x%{ZAw4btV-FCcgI=xgWrO0+zDQ5fW{d-yD z-~Q+SdL!oNCqMa#eJj8D&2MCK|NlAt`oZbn_w}1>|JM4?d%f1vZ#j;gr<2F+`%d>Y zbzJs(3+6efO$BsZeQ&^Zre^j=g-=H-oJmp{^KA2&~Lu^ zX8q|;f4aW>H~H>#=qmi@biNk8tr)~tGugKP+v}dY{G7h?4^O{7d;Re6X1`AYY4pH6 zppJm_K70L{?`R+Hwbuv?FuaBVDc)myz34oRjK3Xs`u*MBk`^pI$r6RkS zfBOCR-)}&d4d~x}_no|b`&PdG`fK^iU;d)M|NZaJ&h7YD~}Uont8 zy+3*Aa-)au-k<)6@7v2efJ#RX>=sa62{`wk@p3mEbLF+*aqBA)s84+ZpYtAHtGx#M zU5`Kit{`vQ_hTxsmkRc_O*fEl|2C+c{^<$u^7p_0efy^y=)d~vEBV{s{w9C=)1S`3 zKY9HP_@AG?-YV2lqgUU6j)3ouEh2aJ_?CKIas2t_*KHkXE2TXAbIrYAuRBmUKlZrH zXCFS-0?^sFRKvvMGy!fg*Rt2#kAv;SfP4Xfs{wv#KsTO!2l@7T`@L;%zfXYQ{w__GuMxH`w)ANZSPPXG@e zyv_jI0oM?~@Y!NO(-|2tjt)qt<96W4A-bZUg&>v@@bNf%J-g4m7PfCY@AP$-?fIO3 zul4sCq#p3WtM8t^{@V?qKJyOb&C6GyYxVGJ{k<7L**tyyw^WLw8^!tZ%P-}xfBozB z@BDr{=LGzJ=`m6mW(xX&%bTJwG|1C|ZysC-^rVM&jVCbzguo;~XLKTKSgt2`fF1!~ z&FcjQA;r<40^0%@0lr`3)rohsrGa~Gz;D;IbY?qld-e$S?U;?uG-`ADtqt%ePrq&y zX9NEB{@ZWA-GRT+ozrVQZ98A{&-wThXD|0ub$$VoKZX?U?@h$Kzr{8{`JiVSM&bm>Z)BCdV`Sx!c0k-2Vz%QSHr4)~1fWCKs2K_vnBG7)@wbVHp0J2O%+D#AFq zCiuD-kG^`q2Y_3evf^3-R)+1$v`9&HGyq->6RI^rdcFh>FuZ{`PzG z@-5JnZQJ&GJ7@dc7g;{5stp3T5V)v`Ulj)L{lG^8UmdS`6%8U_)WJv*Q5yZ3;Q|pw?9CVn=|*QX2q!GlcVT4fvba zublo2c4Gvkf!+eY0ewqYowhAC4rsvF6UYDL)w6eeeGslHWu_ZvU+$^nfAPf^Q{J9Q zmx1)BBSptE9=Hx2931Uiy-^7RU#qMT(5iI+fjXlD3e)6FJjP0oowklf(XQDNO2F$o zs?%i2Mt7`a*?4`WG*T%}M{l-$)zhCjeC7Kc)v>QPsa@B(e6~$3s2-Q2UO&Ja|V)6X02K}rNh z&@!aR>6cmpAjVJ%1hGq#BG=1LHxihAR-)_zSfkOm#MJKDxAPjksoehT#ZUjXW0sb* zYJqOuw{iZhT;UA)0d20iFh$1l^JXv(wGmTNV3SW)n_q1JTMfYi z-6}bY(du`qQxjDS0si)T-S%z3H!6=-LupEoHsiafI-PQZSy?^uea|4uV?91976Y{; z93?EpFo4^)*JM(6ssZuA$S{!Z#BeS#DvL9~(;r5V2L6PXj}#d%sl;AmpxSYD3w8ta zMq5_&_|?l>Zr_03yu97FSl~CnSI@sxFW!LO48SI`b_3bCzZtPkz+XPTc>Gb~yy1Lt zGPWD&PhaT7*_V6j_&@s5k21+DH`om_v^)3+ol^E$O^##qC^7_MbO(jTg53tX%n*>* zGiefoSIfPL{HO+?U3QkKH8%5V^m(bk!g7OVIBMQ6*28b0Zu>UMQmZLmT-;7uHboYf&onoX%o4H*)wWb-1)#IDD2MKerWe6LWult&k zvvd5qt)nef)mfUyuLf}T{6_cJN~5I40mV?Ak1N$#K(Zv-M{(4i{jq%z;4^O@d0G#^ z8AI?qvamoG04*%B#nc+&$;D6{nvso)!w}poj#^XE3c;NP^iw5UgAbTSOGXnK!5Kt6#DjyleQS{>Wdjas-v6iRXpjFX$ zOi4j^Tm{rYvNYU&ZME_?Q;XWYskpTCXQwS2;J0l}&TNHgn8~gC_6klMeKvnuJ-*@i z3uI-xG9IYnT&&7-DK)=$J^mm6_{Uk0mqEIJWC$T>t@b_P$ys7bonTZud%dA2YBk7{Cs6>;0Q#X^f$%Fx$y3z_k^b#nj-pcwn)K zuFCbh1X+_%w|j8%_@7*yba4V&Z`iDdHDgyL&f6XM5eaNoc zcJ-l3lfu-HV)RXX-#}dJ&zVu6qM{z(2MSY2w)T*{HO8ZZfOfwh0DPSAp+v1w$i{Z{ z^M*EbQfKq#?Yt%*LV`*whi_W_`v!IC&>f^U zjGwC$#O~QqLW3B!X*Dv+ygzy0C6y4w1Ih9b{91|9Nkn1t$xw1wNW$BYwO3E}zHD*_){6LOBD{BTuAcH_x z1~f$-dc-oP3Z53J2+PhMWJf#}&J!X%9(cTyr7hs?8-=5pTPtT;PHzkXIlk?Vpmu`E z2FUIE+RSP@wgsUr18YEDs#LivNKL1=k|+l9P>^@w_-py-MBSI3(~qEAm?50Lba|Y| zAL;A?SfdgG^z?^P0gna|MP~OVgu*DR@nM-+Q#7`s_m666X7*XWZa>d(cR?PHUY*qH zG=Q#nobmRnDOqTSvQr(PKHa{Sz%u*P?rYbqBSrJ_TItYY4D%vqzB~Q@ja4MAGcU)| z{7z7WDYxr|v)@(6|K0C?m-6^oZx7(rAnWQGKw;N#IK6ufmaxKW*pYx0sYOP?=uNAU zx0RZ0VmHtrOKn!*^{bf--tB|etI_ILm^-`E8FSp8xwW*%mN1yC?_RP{M-VlWTDs#b z#WADx3HYb`wOpD78h2{q*TFoe78-1Jv;qIq2W4&}e(zLX(&LOuau`{fY1@CVQ&(s8@-EmNerpD{r?5x7{ z!p60Cx?*29DY6Bt=A2fzhLYtTgH(#ssFXU%yH`2$?P=qitsmy;KgH?;<$-KBN2MOK zR`5TV>ga@r_qcsA)*td`+$ujmg67fNCNf}NRn*wwkCmG#P3?*(G(3btP-d5^Y_?=UA#=N$+8k7MT7796f+`KBP#I&`p>-*J1*VdTSRMaY-bAqK_;>BA^Xp&#`X;bLuC|cp25o%9M%+qu&f^=D>3G_V9xIk@T<{2vpY-@yunQ?S@VqthZ5s3vLn>Gc6965J z3u(_aqk%Yqs@3?}r5b0ql&HFj;YQoCkEG-bB>r z0NQ9DyjBKwRE?VFYxfO;Sv$ex5U`qizQ+YE__WusdOV>%Vmm2-inB1PV^tjh@UG*d z`h!N$_O(`Ye(hmD@Dq{1Ugy~9uP^%Zy^efIA9m2NDaZKqyjUd zJ(yHdQlY8dk~(agk@1vqe23TDDTiwX+{(a>9N*U911&kw8B2RwVOpb4bu_RO($&`g zTd5SiKhPXZV(A6=I#|d@gTxioIp_o0i%f8QCR4I@9i!U$NZ!xk3$}+OxxoxSz!E?j=j@O$>=r(iPGO~*Ux{lWynbW>6Si57dH@JRhFv#aI*o9IB zyQ1TX>Y!FXB;CUi;AtFxP`Syb7V3m_DFnC?g(^w#vx-bXT^{KS7T7rx&rzaelt>&o zQ-SAO`LY{r4BbF^vkPz?8f33w4FzRN}ncW;i7VFV$J>)<#nAe6Wp4l6gu$&`vlg4 zD}2?@r%@fJ^DtqbOl=CX^^xFk`m% zK#7o+5O3aee|*0yFb3Qf;GN+x3S>2X3wU{5v|7mG*2~M+LCrmuEMWPj6AnC->Ws<{ zMw3uH1AtyTZDL9k%-Zv;w($i2sA7fyegC?;BgAqS2L-kpcHDU6KwA?y_OC| za;DjaS=&83+Y~0Nyx8n6yjPezs}Q&B60u|KVihfiy`QK~t*lg7*bv_n+#jUO^7x4; zZh7+PcOp(GWQA?b1h-*60WZu(tO;tidJHukv#7_+NP*JxW|T$*UswugCX* zKT2phB?%#i4}xGyXB=>gr^7oLS#c(wNI-$2GKB-*hvPa56Y%)R!|$}mWMFY(3d)yV z=GIahn{~D7jMey&^ONHjG!Xk(o3XqCzb$Dil5p!silfJsgP!8?6V;mD{MN`Q*u)WU z@icMD6An@%%AJho6aHVE&+3ZJY?;DHvTWWm8V$Ud!FX9QAi~lFRDo>rssp>>?J@#4 zu8i0KzP`Hm#Q?tJv~46PWiPNX9-ovRQ?4)2J-pB)?z1?)=dnkl!NC9~WlC0sNk;;9 z9Y&d8NM_mDVluEolp%%5;YuhR%9LJEtO#^+oIqQ?L+Jx#cLlnwsW)Ol##o#f#~S+^ zJ91%G+U59Pp3wXLbkA%DL0hU&$ov)7NzioWc^b!0i~_E41O;VL&-$pApQ$wxQ6DlI z;C3$~D~$HA_h?)wTV|*Zslc@794H4#Fkxbfd4E)c3Kp-~)+Z>V;^K2w#UZLrd3m?} z0p-$VVV5e~3Z7n%*z!8v5cl0%$N$40{%{NMv-_|N8MSrKKxX$HJiTWSY#-2+$gA6- ze}(g0j&Hd;2CghS3sk0)M4>UPpvDh1Jcrl-Mkowo=|1B1J@79t^5Q3Cl~gDw(tk5d zJX_98Dmk<+A9ehwTQZwFI~olplpQt^#S36j!t?@RaVC^23w!}c#Zht&8D0RkUpnJY{#$L?#D7JZ1|7Bi~R`9D-iV+^(i;^Frv3LQ$G}^oC_}&%j?l zYE_kmCa}EMtcG9p@j8CXl15(LlPz0jHlQhmjT#oft<|8J_#lpsFP`#3+WH;h1jt%O zdcF&MqynU~f-tF*_0fTS0sueM&s)jTTzety1{GR|;0ox)f)@-@%^U&L@$Kssi23rO zpByKb*tIzhREIT}I>*I(cKD$jKU2Hol_s!W`$2tq837jI+X~FvE82qip>t0XS*NqLbCgZYRwbXkz?Qc z5+tzPy8OK{&!ebLR46tKZkbmPjE2sFis%f9Ar6!VM-(<~Fc>MkHi0g!A@XJl^r-$c zYU0S5p0v3DHCfH*VM`W-$eT)(r;hqG<6xYBE17B&+qc&yd)pFO%LVwOi74JSrRP1B z<7cNK2A#{YhM+6}b!1QRT8cQa!6AX=)DYbYd>Y(ljlcw^tEDp*n2om+)yD?3iv#ci zE2^w;?811v;qNPq!j_I&L2~Imej;+ERHx_cch&KK``h1M4g84&7we=f1gtu^c2sQU zt$5-UtBKb`hm8_IXBhw2Q37j_ofR^1MWDS0HAq7>>E8j{Sq~s;9YCj8qm&XT(u?gi#&H!eW4`Fqx!Nby_`sy%+oIHW9^)3KjUD%AK12J)GlTlcg;q zo*mWtB)c;(gBb#P0`#7@XB`%7@0{XrM(+6gn;Sgx?^_=ke~+eH1RWNy7uWIe7|C8J_AW*}bAd`B`Zqy{|9`bMJyS@;1v zBp+5iArsh@wfsi;lBs1-;^0Y_^muE8Kw%D4XY`uMszmWpP?Wj}L70k5K)#)u#4LLjHkzIMA=)M zKUel_aXli1yfR7Ra_1-}|vK0NZDPUoOovJ-M`h9}b%Efwen!LBgc#6|>ft}nYDlPAf1 z-4rc~y#C<$;l%T6MkB-54>Q?_1WnIp&)wlGCUfgfwMrtia{PPi_`mwqucm;GK@Cz4 zAsy5*pk|3F=N#9=Tgg-6u4uDTXUPLg4zEDrc1lAUwPNc&yf#a84XKK))P#;{ zyJTsdfE*{3Q{LZm{3VgC9hEfbQ+50hn1du$<{BQ=$<*{jL9P-HFTvc}jE2t=JquHr zyug-}A}}y7PIAmn1MIYQ1T0P_A)`ydvIWN3Tb+&(HVYI^366C=+3AVG6r*5HuCih^n>i*E*wy>K z!36kGSqF7Ukg1KR5XhNJ;nb!iir3nC&sTNABDDy#?8XK4^uhv8!q>a&+sV#B0!pF> zol$bK+cKPAURO#~Q|4ehE=SzodSn*dBK0Yxl-N$2#Hvg;n=AbqSFIGeIKeHHEEI?8 zXtGvk{UCjHLJzNXaR&n04AoI_n!7SEv&u`4!g${Sy<`CTk!LJWSs8)9WQy0stPbvQ zbyuAs-HTnL2zWoXUG$_(fkK=>$6pc!YEc#ES~>pL&*k`SQpkv+;Bn@CfzcGL<_hWj$4TMR_0v#C!#)j8hk;*z+{VK;* znhEeflCC#M3h+wFxXAnGbNrzFi06eflTyUd{6}#Djtt^an~1whzlw^h@hfjL?v4oF z#1agUN5ybK23j(8|4vqxbwIP9vp|3=&cyO1QFl7SQrF;o&hR&|SxWb59-r7r*#Lq^;kzlwknOQ5S~8K0;kw1Bt+WOUd%Y_J#DP z!TGKlP#Z;QGeLDwV;2^{GH^>jdEBeh34s4{a?@}0`U=fX&fNa!H+QExnKpo)rycO~ z185zpBaz3??u#gq9+&p?vXvS%ppB+9x>O|Cr))wy(npMyh=Fu5inot=`NKKvxdiPF znbDp9y@VBvM)E)Z_YV9N$0zco z4jM;|t{-ZDFtOkiH9bL<4{#Nk`=g4L}K3m**kPYtWf};$TgsKze7+h5+8#9o9 zQ>u<}An5Vk5x7N?q+qXmUR&#>pim7wKJ)=}2zNg!99Dc@AEN49QF=U8XCH9n4Am+3 z@c3l1Oc`kYWia`AbPd`@FxodT1oZ4>M0IeEGIDi7Z}!9&$<%hqv493OkN@^^99#CV zkiwkSL%gtI;Q7FJGOKPzHk-K>f2I~KD$4}3UPUHJP!%@n1^ss1;xniD6ngj+)iK%N z5tnD(De$=BWn>whVP)A&)xl|_ga%dMD+z8(XHQ4{QXLwk_g8fWz%PX29JYH(4JjLD z$tMjIo)QJLa_pRzDsMnqa!sH+pezNGWI;gd#Q`M|&=%9{hK&q`M90N)d@~YRN+j$Y zrv!Q6@vWm)mdO$sPs&|Soc({?RmcDN&wrk38s(`mkcf&5K?f66!ffn7syrA{K%ZD= z2(LO*2Yg?h%&@RnfK+(0b$w}O)r8m}R0se+3Ve~rEAn~+#RQEp%E?RC3JgHVW7k;P!>H z)`!&N&+7QeAl2=%F#A5}&_)el1f<||+^LC^0Wb|rNsxM=D1@?j`&;pwGF8ZP8mRgh zfxxOZ`}>-Axoo`ff3JW|df=afTb8^ky|>4V?tYo_n#g+4%H}~CL3SSvbjg18Mhya{ zLzgucj6wZ4?S9Nkd?RpYK%P~60?E@IeVFvCUfMsgrbXbm#A9=$;|hpckmPe##aQ61{x z18*G#z7n+qWJUu;T{PLmzR!e#3>TsB6j8~i&Wiefl+NOf4rhC^9Anv?x$ROjm>$h|%~-nv))i15J@SV49c z`Eo>q)B*G%%j&2x5m>tl%%F^b0h1QB&Ab+Wt=>@8VX6#L4l)_V%@D)AP&R6Kqm607 z=uJE+fs|W@d?-B@ySQ!Xv$%VPx2ij**ALY3X*mL`w)DKMLxWt}12@v^l;*C8 zLe68#5%atSW*U{5q*|isExo>TOmS41=(b{uv00gyS%n}FAo7eQXLsj zI60KuI<(|)P0*t$RU%xP$*LnRe=ro`E0-(#>|oNoTjP()ie~1w* z(F`|`D48c;@b4OU|K$Sw^0#xTL5Ov_t(b+KI|={Mz)y_=83Q4sf#+$JU5|iF2Xd-- z0V*3Al9S@I^d{ro3ua8CxPWDAGcm%T1YDWHGl|mK@73yy0scmH{(8x{E=o!ln2xDO z12BTly>>JU5O%kTEq4_=f;L>G3mt z)Fn%M0&3!^JZV4>1tn5=G(neG@LUG*MQUHhh*{>=yEYjqsDea1JM-M)WMP@)XIQ!h{l z&YuLnM{hJqb37 z{|YMp5bVw|W^IWN3jEPS8&R8#w@#`q5eN5zR`CMX37}7bJ4toCwY*Zl+3}7dLzNt> zbb87Siwi>F{})sxwQrHxC2n!fIj8y`8u-`l$HKN5P@~!sd39Q;D11IaWDF^=U&H$| zxdL*(+(0$)d&O+6{Y`+q!ss&uysgWUXzI%oZ{)L802cb$pE%@O9;x<+_XK`s z{-^h#nZ!8A9J=5T(u*_eF&&PdqEY}#+p{NaxHzFc%C?#c&S_(h5_B1(W|QMPhCQH9 z$)5|=`ONY7g_YxkE1O?lKDw{Y2zZIn!R7qU2r~5Mvo$s_4U#^{1h>u{n{J&hq`_7& zm9mh0fR654l)NL9hAKXe7neZ-OAa1?TiASAc&9-7yR!zn9pk2t>! z=!qnFeOBLhCzinLLxL-F{zQAl=$=G%L^Jt}4E0IH2Ej-X8bS#Ce-SeQtM!ml0Jpe- zY)6Uo0S%=vcx{1Isb6d~zt(0W>o7i~9!{23yv(bW83*UdATj1@_(7uXs+AwFEq54X z$lU~2lpk>jHD-!ekUB@+-P?DWdiY5JmQ&ms9A6xguF2X{S2oY+_9N{&;{UVW(n+u| z<17Q(mW?4~*6Vs6G`fEogPYA643cZOZ?Uyt+3S-P1;tT+mf=lL&G=hN02-vf9#mNW>o+i4{X z+lsCy&R*`V<3|rA3F7Es&K#TNo~ZO>Ks#d$X{9G&1jGAv<$2RUzrkTd6bkoWfd6rG z(M`(i&hG1SXlJ!{{Ca7T|NVoh&YiseDCo_2N>82 z-lxCI%x7H@40q4tiu*h@qT10SVU(H-aE-?=mvXhDy|RPJt3$@tCavnZ8`b&h&b2z% z06!{82sC?2p{{vgNrRD$fn5XU$=8R47n~)MM)%{Yd*$`XA8>rHUWcv=MS*_~ZZ|M5 zfohXTYHc6$UgaTubtZ;9_n~+b%~3fCRFp$Tka5W5h~hnb*6;JCQRANH1coD-zcsoC z#JkgL5pa)20mtLl1lB^1YQ10!)ZTlF=lkNz{SV~$RHq*um%N@^?wlPJvWAfjA`?KG z0^G!?buAqeXY}%d&s#bCVI@RY&U{mX>4aWuaAFA0kTWy9I0N=;hip$60Z_$Rz+%Rrqdqz6WRRvPPe66#Mcx7Mon)0e zh*(2-e}9hec>E#g&|D(`-wLMWke$BP2sGDtd{l9g^6$*3=skzK7@qf@tZY6)Z0)4> zPP(Qz5)CSz(qlaSGdRBEm&?p+D^y`ehqs+3s* zF7HX1-Cwr19eIk!Pf(c97|f)UwyH_HMq%&SIim+@k4FiVyhr(xzP|-&!3TElpMYAZ>8@Ukxq8Y&hq}+CLE~_%Y%87%?a=y;gSg|i;r+=tiV1Gtw!L!vyFv8Z4J3c)#J|s z+5_4QC?jBzyE6sC!NZm8Lr)a!U45@+@5!tYLQW$)I$nLRI*+g4ngX@CwXTj=eGJFf zD?NPZ(Pxci#t1-(kvlxFS%6P(zr}%&Kv!o*r`eGw;r%rjK?061!Q(AH_kV<(nc$+G z>QbQg0_8gPpkd!3I~(ouTn1)n$@gs%quU;@es1xSGQ?xr&!?Q1Y68)QmTKc4JLw3f z@7=BU<_P?6#jn%x1~0ED_pv&D<^iVm-|!%B1^etnotguind8c`xUB}()~)wS-0IA?4voqD*+6-oMRl%tpfjHB z)^lb6F=IftoKuK2n>Os^c{4^kg%eL!z0yI{%Ido)7m%`gaeichh~i zW<)Q4M-D&}YBX#6*<0iAzij_DN5c z{^L#_|K&s8>?Z)D$baykCm7M}&p*Aq`<^Te;ZU8uZ>FRCY`rr-y7M`PUF0 zCcl`;^yGNt`Jq;;Ip~8x&r}r7=kp|CpDsY^p!)cU*E-5pAqvM240Q^H0!aYx1|ZX} zLz<{f1^9S88VWd*$zaaqxxWDz{48n}FnZqU+3N}e7HQiy=Kjgl;cyf1_KQ4L^I~D( z`4P36htpA50>4N&Pl7*7U$YB6AghboOA5yh98maGLht0rBJ^Rp!bt-MEdkI!a=D5c zLEyVQd+mIfC7vR{+S;E1##3sRI2;bX!j@%G1X!!r>wTHcW)EkRyjCfUo~b-^64>|b za=E0zU_i}glZwTn|Bx*fiwC~J=?7N>SOGoKe(0DEi@;bamB?`%->-mkT{m>|lju5( zpHC@lnx+8KVO4NdX+EEeH5S*Yn$c)PtJO-}Ory~d^GRC53|fN2vLLLk9@NEks)q0I zXuV#GQEj5oGq_U3W{KTyXR6H)lp79*-vD-N&#P*nY_(byqnbm{#5}y&Y)s|hR;v~H z%>({bt3thA_m456=cWB@SX}e$JK*hhYvCu(X0!kG)`1$is=S*=Po9Y=Y;e#fx5DQ* on{t(Z@Avy3T!81ef!_oe0Bc?e9f;|#Q2+n{07*qoM6N<$g3r89FaQ7m literal 0 HcmV?d00001 diff --git a/3rdparty/miniColors/css/jquery.miniColors.css b/3rdparty/miniColors/css/jquery.miniColors.css new file mode 100755 index 0000000000..592f44894d --- /dev/null +++ b/3rdparty/miniColors/css/jquery.miniColors.css @@ -0,0 +1,125 @@ +INPUT.miniColors { + margin-right: 4px; +} + +.miniColors-selector { + position: absolute; + width: 175px; + height: 150px; + background: white; + border: solid 1px #bababa; + -moz-box-shadow: 0 0 6px rgba(0, 0, 0, .25); + -webkit-box-shadow: 0 0 6px rgba(0, 0, 0, .25); + box-shadow: 0 0 6px rgba(0, 0, 0, .25); + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + padding: 5px; + z-index: 999999; +} + +.miniColors.opacity.miniColors-selector { + width: 200px; +} + +.miniColors-selector.black { + background: black; + border-color: black; +} + +.miniColors-colors { + position: absolute; + top: 5px; + left: 5px; + width: 150px; + height: 150px; + background: url(images/colors.png) -40px 0 no-repeat; + cursor: crosshair; +} + +.miniColors.opacity .miniColors-colors { + left: 30px; +} + +.miniColors-hues { + position: absolute; + top: 5px; + left: 160px; + width: 20px; + height: 150px; + background: url(images/colors.png) 0 0 no-repeat; + cursor: crosshair; +} + +.miniColors.opacity .miniColors-hues { + left: 185px; +} + +.miniColors-opacity { + position: absolute; + top: 5px; + left: 5px; + width: 20px; + height: 150px; + background: url(images/colors.png) -20px 0 no-repeat; + cursor: crosshair; +} + +.miniColors-colorPicker { + position: absolute; + width: 11px; + height: 11px; + border: 1px solid black; + -moz-border-radius: 11px; + -webkit-border-radius: 11px; + border-radius: 11px; +} +.miniColors-colorPicker-inner { + position: absolute; + top: 0; + left: 0; + width: 7px; + height: 7px; + border: 2px solid white; + -moz-border-radius: 9px; + -webkit-border-radius: 9px; + border-radius: 9px; +} + +.miniColors-huePicker, +.miniColors-opacityPicker { + position: absolute; + left: -2px; + width: 22px; + height: 2px; + border: 1px solid black; + background: white; + margin-top: -1px; + border-radius: 2px; +} + +.miniColors-trigger, +.miniColors-triggerWrap { + width: 22px; + height: 22px; + display: inline-block; +} + +.miniColors-triggerWrap { + background: url(images/trigger.png) -22px 0 no-repeat; +} + +.miniColors-triggerWrap.disabled { + filter: alpha(opacity=50); + opacity: .5; +} + +.miniColors-trigger { + vertical-align: middle; + outline: none; + background: url(images/trigger.png) 0 0 no-repeat; +} + +.miniColors-triggerWrap.disabled .miniColors-trigger { + cursor: default; +} \ No newline at end of file diff --git a/3rdparty/miniColors/js/jquery.miniColors.js b/3rdparty/miniColors/js/jquery.miniColors.js new file mode 100755 index 0000000000..a0f439c2c4 --- /dev/null +++ b/3rdparty/miniColors/js/jquery.miniColors.js @@ -0,0 +1,710 @@ +/* + * jQuery miniColors: A small color selector + * + * Copyright 2012 Cory LaViska for A Beautiful Site, LLC. (http://www.abeautifulsite.net/) + * + * Dual licensed under the MIT or GPL Version 2 licenses + * +*/ +if(jQuery) (function($) { + + $.extend($.fn, { + + miniColors: function(o, data) { + + var create = function(input, o, data) { + // + // Creates a new instance of the miniColors selector + // + + // Determine initial color (defaults to white) + var color = expandHex(input.val()) || 'ffffff', + hsb = hex2hsb(color), + rgb = hsb2rgb(hsb), + alpha = parseFloat(input.attr('data-opacity')).toFixed(2); + + if( alpha > 1 ) alpha = 1; + if( alpha < 0 ) alpha = 0; + + // Create trigger + var trigger = $(''); + trigger.insertAfter(input); + trigger.wrap(''); + if( o.opacity ) { + trigger.css('backgroundColor', 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + alpha + ')'); + } + + // Set input data and update attributes + input + .addClass('miniColors') + .data('original-maxlength', input.attr('maxlength') || null) + .data('original-autocomplete', input.attr('autocomplete') || null) + .data('letterCase', o.letterCase === 'uppercase' ? 'uppercase' : 'lowercase') + .data('opacity', o.opacity ? true : false) + .data('alpha', alpha) + .data('trigger', trigger) + .data('hsb', hsb) + .data('change', o.change ? o.change : null) + .data('close', o.close ? o.close : null) + .data('open', o.open ? o.open : null) + .attr('maxlength', 7) + .attr('autocomplete', 'off') + .val('#' + convertCase(color, o.letterCase)); + + // Handle options + if( o.readonly || input.prop('readonly') ) input.prop('readonly', true); + if( o.disabled || input.prop('disabled') ) disable(input); + + // Show selector when trigger is clicked + trigger.on('click.miniColors', function(event) { + event.preventDefault(); + if( input.val() === '' ) input.val('#'); + show(input); + + }); + + // Show selector when input receives focus + input.on('focus.miniColors', function(event) { + if( input.val() === '' ) input.val('#'); + show(input); + }); + + // Hide on blur + input.on('blur.miniColors', function(event) { + var hex = expandHex( hsb2hex(input.data('hsb')) ); + input.val( hex ? '#' + convertCase(hex, input.data('letterCase')) : '' ); + }); + + // Hide when tabbing out of the input + input.on('keydown.miniColors', function(event) { + if( event.keyCode === 9 ) hide(input); + }); + + // Update when color is typed in + input.on('keyup.miniColors', function(event) { + setColorFromInput(input); + }); + + // Handle pasting + input.on('paste.miniColors', function(event) { + // Short pause to wait for paste to complete + setTimeout( function() { + setColorFromInput(input); + }, 5); + }); + + }; + + var destroy = function(input) { + // + // Destroys an active instance of the miniColors selector + // + hide(); + input = $(input); + + // Restore to original state + input.data('trigger').parent().remove(); + input + .attr('autocomplete', input.data('original-autocomplete')) + .attr('maxlength', input.data('original-maxlength')) + .removeData() + .removeClass('miniColors') + .off('.miniColors'); + $(document).off('.miniColors'); + }; + + var enable = function(input) { + // + // Enables the input control and the selector + // + input + .prop('disabled', false) + .data('trigger').parent().removeClass('disabled'); + }; + + var disable = function(input) { + // + // Disables the input control and the selector + // + hide(input); + input + .prop('disabled', true) + .data('trigger').parent().addClass('disabled'); + }; + + var show = function(input) { + // + // Shows the miniColors selector + // + if( input.prop('disabled') ) return false; + + // Hide all other instances + hide(); + + // Generate the selector + var selector = $('
                '); + selector + .append('
                ') + .append('
                ') + .css('display', 'none') + .addClass( input.attr('class') ); + + // Opacity + if( input.data('opacity') ) { + selector + .addClass('opacity') + .prepend('
                '); + } + + // Set background for colors + var hsb = input.data('hsb'); + selector + .find('.miniColors-colors').css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 })).end() + .find('.miniColors-opacity').css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: hsb.s, b: hsb.b })).end(); + + // Set colorPicker position + var colorPosition = input.data('colorPosition'); + if( !colorPosition ) colorPosition = getColorPositionFromHSB(hsb); + selector.find('.miniColors-colorPicker') + .css('top', colorPosition.y + 'px') + .css('left', colorPosition.x + 'px'); + + // Set huePicker position + var huePosition = input.data('huePosition'); + if( !huePosition ) huePosition = getHuePositionFromHSB(hsb); + selector.find('.miniColors-huePicker').css('top', huePosition + 'px'); + + // Set opacity position + var opacityPosition = input.data('opacityPosition'); + if( !opacityPosition ) opacityPosition = getOpacityPositionFromAlpha(input.attr('data-opacity')); + selector.find('.miniColors-opacityPicker').css('top', opacityPosition + 'px'); + + // Set input data + input + .data('selector', selector) + .data('huePicker', selector.find('.miniColors-huePicker')) + .data('opacityPicker', selector.find('.miniColors-opacityPicker')) + .data('colorPicker', selector.find('.miniColors-colorPicker')) + .data('mousebutton', 0); + + $('BODY').append(selector); + + // Position the selector + var trigger = input.data('trigger'), + hidden = !input.is(':visible'), + top = hidden ? trigger.offset().top + trigger.outerHeight() : input.offset().top + input.outerHeight(), + left = hidden ? trigger.offset().left : input.offset().left, + selectorWidth = selector.outerWidth(), + selectorHeight = selector.outerHeight(), + triggerWidth = trigger.outerWidth(), + triggerHeight = trigger.outerHeight(), + windowHeight = $(window).height(), + windowWidth = $(window).width(), + scrollTop = $(window).scrollTop(), + scrollLeft = $(window).scrollLeft(); + + // Adjust based on viewport + if( (top + selectorHeight) > windowHeight + scrollTop ) top = top - selectorHeight - triggerHeight; + if( (left + selectorWidth) > windowWidth + scrollLeft ) left = left - selectorWidth + triggerWidth; + + // Set position and show + selector.css({ + top: top, + left: left + }).fadeIn(100); + + // Prevent text selection in IE + selector.on('selectstart', function() { return false; }); + + // Hide on resize (IE7/8 trigger this when any element is resized...) + if( !$.browser.msie || ($.browser.msie && $.browser.version >= 9) ) { + $(window).on('resize.miniColors', function(event) { + hide(input); + }); + } + + $(document) + .on('mousedown.miniColors touchstart.miniColors', function(event) { + + input.data('mousebutton', 1); + var testSubject = $(event.target).parents().andSelf(); + + if( testSubject.hasClass('miniColors-colors') ) { + event.preventDefault(); + input.data('moving', 'colors'); + moveColor(input, event); + } + + if( testSubject.hasClass('miniColors-hues') ) { + event.preventDefault(); + input.data('moving', 'hues'); + moveHue(input, event); + } + + if( testSubject.hasClass('miniColors-opacity') ) { + event.preventDefault(); + input.data('moving', 'opacity'); + moveOpacity(input, event); + } + + if( testSubject.hasClass('miniColors-selector') ) { + event.preventDefault(); + return; + } + + if( testSubject.hasClass('miniColors') ) return; + + hide(input); + }) + .on('mouseup.miniColors touchend.miniColors', function(event) { + event.preventDefault(); + input.data('mousebutton', 0).removeData('moving'); + }) + .on('mousemove.miniColors touchmove.miniColors', function(event) { + event.preventDefault(); + if( input.data('mousebutton') === 1 ) { + if( input.data('moving') === 'colors' ) moveColor(input, event); + if( input.data('moving') === 'hues' ) moveHue(input, event); + if( input.data('moving') === 'opacity' ) moveOpacity(input, event); + } + }); + + // Fire open callback + if( input.data('open') ) { + input.data('open').call(input.get(0), '#' + hsb2hex(hsb), $.extend(hsb2rgb(hsb), { a: parseFloat(input.attr('data-opacity')) })); + } + + }; + + var hide = function(input) { + + // + // Hides one or more miniColors selectors + // + + // Hide all other instances if input isn't specified + if( !input ) input = $('.miniColors'); + + input.each( function() { + var selector = $(this).data('selector'); + $(this).removeData('selector'); + $(selector).fadeOut(100, function() { + // Fire close callback + if( input.data('close') ) { + var hsb = input.data('hsb'), hex = hsb2hex(hsb); + input.data('close').call(input.get(0), '#' + hex, $.extend(hsb2rgb(hsb), { a: parseFloat(input.attr('data-opacity')) })); + } + $(this).remove(); + }); + }); + + $(document).off('.miniColors'); + + }; + + var moveColor = function(input, event) { + + var colorPicker = input.data('colorPicker'); + + colorPicker.hide(); + + var position = { + x: event.pageX, + y: event.pageY + }; + + // Touch support + if( event.originalEvent.changedTouches ) { + position.x = event.originalEvent.changedTouches[0].pageX; + position.y = event.originalEvent.changedTouches[0].pageY; + } + position.x = position.x - input.data('selector').find('.miniColors-colors').offset().left - 6; + position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 6; + if( position.x <= -5 ) position.x = -5; + if( position.x >= 144 ) position.x = 144; + if( position.y <= -5 ) position.y = -5; + if( position.y >= 144 ) position.y = 144; + + input.data('colorPosition', position); + colorPicker.css('left', position.x).css('top', position.y).show(); + + // Calculate saturation + var s = Math.round((position.x + 5) * 0.67); + if( s < 0 ) s = 0; + if( s > 100 ) s = 100; + + // Calculate brightness + var b = 100 - Math.round((position.y + 5) * 0.67); + if( b < 0 ) b = 0; + if( b > 100 ) b = 100; + + // Update HSB values + var hsb = input.data('hsb'); + hsb.s = s; + hsb.b = b; + + // Set color + setColor(input, hsb, true); + }; + + var moveHue = function(input, event) { + + var huePicker = input.data('huePicker'); + + huePicker.hide(); + + var position = event.pageY; + + // Touch support + if( event.originalEvent.changedTouches ) { + position = event.originalEvent.changedTouches[0].pageY; + } + + position = position - input.data('selector').find('.miniColors-colors').offset().top - 1; + if( position <= -1 ) position = -1; + if( position >= 149 ) position = 149; + input.data('huePosition', position); + huePicker.css('top', position).show(); + + // Calculate hue + var h = Math.round((150 - position - 1) * 2.4); + if( h < 0 ) h = 0; + if( h > 360 ) h = 360; + + // Update HSB values + var hsb = input.data('hsb'); + hsb.h = h; + + // Set color + setColor(input, hsb, true); + + }; + + var moveOpacity = function(input, event) { + + var opacityPicker = input.data('opacityPicker'); + + opacityPicker.hide(); + + var position = event.pageY; + + // Touch support + if( event.originalEvent.changedTouches ) { + position = event.originalEvent.changedTouches[0].pageY; + } + + position = position - input.data('selector').find('.miniColors-colors').offset().top - 1; + if( position <= -1 ) position = -1; + if( position >= 149 ) position = 149; + input.data('opacityPosition', position); + opacityPicker.css('top', position).show(); + + // Calculate opacity + var alpha = parseFloat((150 - position - 1) / 150).toFixed(2); + if( alpha < 0 ) alpha = 0; + if( alpha > 1 ) alpha = 1; + + // Update opacity + input + .data('alpha', alpha) + .attr('data-opacity', alpha); + + // Set color + setColor(input, input.data('hsb'), true); + + }; + + var setColor = function(input, hsb, updateInput) { + input.data('hsb', hsb); + var hex = hsb2hex(hsb), + selector = $(input.data('selector')); + if( updateInput ) input.val( '#' + convertCase(hex, input.data('letterCase')) ); + + selector + .find('.miniColors-colors').css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 })).end() + .find('.miniColors-opacity').css('backgroundColor', '#' + hex).end(); + + var rgb = hsb2rgb(hsb); + + // Set background color (also fallback for non RGBA browsers) + input.data('trigger').css('backgroundColor', '#' + hex); + + // Set background color + opacity + if( input.data('opacity') ) { + input.data('trigger').css('backgroundColor', 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + input.attr('data-opacity') + ')'); + } + + // Fire change callback + if( input.data('change') ) { + if( (hex + ',' + input.attr('data-opacity')) === input.data('lastChange') ) return; + input.data('change').call(input.get(0), '#' + hex, $.extend(hsb2rgb(hsb), { a: parseFloat(input.attr('data-opacity')) })); + input.data('lastChange', hex + ',' + input.attr('data-opacity')); + } + + }; + + var setColorFromInput = function(input) { + + input.val('#' + cleanHex(input.val())); + var hex = expandHex(input.val()); + if( !hex ) return false; + + // Get HSB equivalent + var hsb = hex2hsb(hex); + + // Set colorPicker position + var colorPosition = getColorPositionFromHSB(hsb); + var colorPicker = $(input.data('colorPicker')); + colorPicker.css('top', colorPosition.y + 'px').css('left', colorPosition.x + 'px'); + input.data('colorPosition', colorPosition); + + // Set huePosition position + var huePosition = getHuePositionFromHSB(hsb); + var huePicker = $(input.data('huePicker')); + huePicker.css('top', huePosition + 'px'); + input.data('huePosition', huePosition); + + // Set opacity position + var opacityPosition = getOpacityPositionFromAlpha(input.attr('data-opacity')); + var opacityPicker = $(input.data('opacityPicker')); + opacityPicker.css('top', opacityPosition + 'px'); + input.data('opacityPosition', opacityPosition); + setColor(input, hsb); + + return true; + + }; + + var convertCase = function(string, letterCase) { + if( letterCase === 'uppercase' ) { + return string.toUpperCase(); + } else { + return string.toLowerCase(); + } + }; + + var getColorPositionFromHSB = function(hsb) { + var x = Math.ceil(hsb.s / 0.67); + if( x < 0 ) x = 0; + if( x > 150 ) x = 150; + var y = 150 - Math.ceil(hsb.b / 0.67); + if( y < 0 ) y = 0; + if( y > 150 ) y = 150; + return { x: x - 5, y: y - 5 }; + }; + + var getHuePositionFromHSB = function(hsb) { + var y = 150 - (hsb.h / 2.4); + if( y < 0 ) h = 0; + if( y > 150 ) h = 150; + return y; + }; + + var getOpacityPositionFromAlpha = function(alpha) { + var y = 150 * alpha; + if( y < 0 ) y = 0; + if( y > 150 ) y = 150; + return 150 - y; + }; + + var cleanHex = function(hex) { + return hex.replace(/[^A-F0-9]/ig, ''); + }; + + var expandHex = function(hex) { + hex = cleanHex(hex); + if( !hex ) return null; + if( hex.length === 3 ) hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; + return hex.length === 6 ? hex : null; + }; + + var hsb2rgb = function(hsb) { + var rgb = {}; + var h = Math.round(hsb.h); + var s = Math.round(hsb.s*255/100); + var v = Math.round(hsb.b*255/100); + if(s === 0) { + rgb.r = rgb.g = rgb.b = v; + } else { + var t1 = v; + var t2 = (255 - s) * v / 255; + var t3 = (t1 - t2) * (h % 60) / 60; + if( h === 360 ) h = 0; + if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; } + else if( h < 120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; } + else if( h < 180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; } + else if( h < 240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; } + else if( h < 300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; } + else if( h < 360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; } + else { rgb.r = 0; rgb.g = 0; rgb.b = 0; } + } + return { + r: Math.round(rgb.r), + g: Math.round(rgb.g), + b: Math.round(rgb.b) + }; + }; + + var rgb2hex = function(rgb) { + var hex = [ + rgb.r.toString(16), + rgb.g.toString(16), + rgb.b.toString(16) + ]; + $.each(hex, function(nr, val) { + if (val.length === 1) hex[nr] = '0' + val; + }); + return hex.join(''); + }; + + var hex2rgb = function(hex) { + hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16); + + return { + r: hex >> 16, + g: (hex & 0x00FF00) >> 8, + b: (hex & 0x0000FF) + }; + }; + + var rgb2hsb = function(rgb) { + var hsb = { h: 0, s: 0, b: 0 }; + var min = Math.min(rgb.r, rgb.g, rgb.b); + var max = Math.max(rgb.r, rgb.g, rgb.b); + var delta = max - min; + hsb.b = max; + hsb.s = max !== 0 ? 255 * delta / max : 0; + if( hsb.s !== 0 ) { + if( rgb.r === max ) { + hsb.h = (rgb.g - rgb.b) / delta; + } else if( rgb.g === max ) { + hsb.h = 2 + (rgb.b - rgb.r) / delta; + } else { + hsb.h = 4 + (rgb.r - rgb.g) / delta; + } + } else { + hsb.h = -1; + } + hsb.h *= 60; + if( hsb.h < 0 ) { + hsb.h += 360; + } + hsb.s *= 100/255; + hsb.b *= 100/255; + return hsb; + }; + + var hex2hsb = function(hex) { + var hsb = rgb2hsb(hex2rgb(hex)); + // Zero out hue marker for black, white, and grays (saturation === 0) + if( hsb.s === 0 ) hsb.h = 360; + return hsb; + }; + + var hsb2hex = function(hsb) { + return rgb2hex(hsb2rgb(hsb)); + }; + + + // Handle calls to $([selector]).miniColors() + switch(o) { + + case 'readonly': + + $(this).each( function() { + if( !$(this).hasClass('miniColors') ) return; + $(this).prop('readonly', data); + }); + + return $(this); + + case 'disabled': + + $(this).each( function() { + if( !$(this).hasClass('miniColors') ) return; + if( data ) { + disable($(this)); + } else { + enable($(this)); + } + }); + + return $(this); + + case 'value': + + // Getter + if( data === undefined ) { + if( !$(this).hasClass('miniColors') ) return; + var input = $(this), + hex = expandHex(input.val()); + return hex ? '#' + convertCase(hex, input.data('letterCase')) : null; + } + + // Setter + $(this).each( function() { + if( !$(this).hasClass('miniColors') ) return; + $(this).val(data); + setColorFromInput($(this)); + }); + + return $(this); + + case 'opacity': + + // Getter + if( data === undefined ) { + if( !$(this).hasClass('miniColors') ) return; + if( $(this).data('opacity') ) { + return parseFloat($(this).attr('data-opacity')); + } else { + return null; + } + } + + // Setter + $(this).each( function() { + if( !$(this).hasClass('miniColors') ) return; + if( data < 0 ) data = 0; + if( data > 1 ) data = 1; + $(this).attr('data-opacity', data).data('alpha', data); + setColorFromInput($(this)); + }); + + return $(this); + + case 'destroy': + + $(this).each( function() { + if( !$(this).hasClass('miniColors') ) return; + destroy($(this)); + }); + + return $(this); + + default: + + if( !o ) o = {}; + + $(this).each( function() { + + // Must be called on an input element + if( $(this)[0].tagName.toLowerCase() !== 'input' ) return; + + // If a trigger is present, the control was already created + if( $(this).data('trigger') ) return; + + // Create the control + create($(this), o, data); + + }); + + return $(this); + + } + + } + + }); + +})(jQuery); \ No newline at end of file diff --git a/3rdparty/miniColors/js/jquery.miniColors.min.js b/3rdparty/miniColors/js/jquery.miniColors.min.js new file mode 100755 index 0000000000..1d3346455b --- /dev/null +++ b/3rdparty/miniColors/js/jquery.miniColors.min.js @@ -0,0 +1,9 @@ +/* + * jQuery miniColors: A small color selector + * + * Copyright 2012 Cory LaViska for A Beautiful Site, LLC. (http://www.abeautifulsite.net/) + * + * Dual licensed under the MIT or GPL Version 2 licenses + * +*/ +if(jQuery)(function($){$.extend($.fn,{miniColors:function(o,data){var create=function(input,o,data){var color=expandHex(input.val())||'ffffff',hsb=hex2hsb(color),rgb=hsb2rgb(hsb),alpha=parseFloat(input.attr('data-opacity')).toFixed(2);if(alpha>1)alpha=1;if(alpha<0)alpha=0;var trigger=$('');trigger.insertAfter(input);trigger.wrap('');if(o.opacity){trigger.css('backgroundColor','rgba('+rgb.r+', '+rgb.g+', '+rgb.b+', '+alpha+')')}input.addClass('miniColors').data('original-maxlength',input.attr('maxlength')||null).data('original-autocomplete',input.attr('autocomplete')||null).data('letterCase',o.letterCase==='uppercase'?'uppercase':'lowercase').data('opacity',o.opacity?true:false).data('alpha',alpha).data('trigger',trigger).data('hsb',hsb).data('change',o.change?o.change:null).data('close',o.close?o.close:null).data('open',o.open?o.open:null).attr('maxlength',7).attr('autocomplete','off').val('#'+convertCase(color,o.letterCase));if(o.readonly||input.prop('readonly'))input.prop('readonly',true);if(o.disabled||input.prop('disabled'))disable(input);trigger.on('click.miniColors',function(event){event.preventDefault();if(input.val()==='')input.val('#');show(input)});input.on('focus.miniColors',function(event){if(input.val()==='')input.val('#');show(input)});input.on('blur.miniColors',function(event){var hex=expandHex(hsb2hex(input.data('hsb')));input.val(hex?'#'+convertCase(hex,input.data('letterCase')):'')});input.on('keydown.miniColors',function(event){if(event.keyCode===9)hide(input)});input.on('keyup.miniColors',function(event){setColorFromInput(input)});input.on('paste.miniColors',function(event){setTimeout(function(){setColorFromInput(input)},5)})};var destroy=function(input){hide();input=$(input);input.data('trigger').parent().remove();input.attr('autocomplete',input.data('original-autocomplete')).attr('maxlength',input.data('original-maxlength')).removeData().removeClass('miniColors').off('.miniColors');$(document).off('.miniColors')};var enable=function(input){input.prop('disabled',false).data('trigger').parent().removeClass('disabled')};var disable=function(input){hide(input);input.prop('disabled',true).data('trigger').parent().addClass('disabled')};var show=function(input){if(input.prop('disabled'))return false;hide();var selector=$('
                ');selector.append('
                ').append('
                ').css('display','none').addClass(input.attr('class'));if(input.data('opacity')){selector.addClass('opacity').prepend('
                ')}var hsb=input.data('hsb');selector.find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100})).end().find('.miniColors-opacity').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:hsb.s,b:hsb.b})).end();var colorPosition=input.data('colorPosition');if(!colorPosition)colorPosition=getColorPositionFromHSB(hsb);selector.find('.miniColors-colorPicker').css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');var huePosition=input.data('huePosition');if(!huePosition)huePosition=getHuePositionFromHSB(hsb);selector.find('.miniColors-huePicker').css('top',huePosition+'px');var opacityPosition=input.data('opacityPosition');if(!opacityPosition)opacityPosition=getOpacityPositionFromAlpha(input.attr('data-opacity'));selector.find('.miniColors-opacityPicker').css('top',opacityPosition+'px');input.data('selector',selector).data('huePicker',selector.find('.miniColors-huePicker')).data('opacityPicker',selector.find('.miniColors-opacityPicker')).data('colorPicker',selector.find('.miniColors-colorPicker')).data('mousebutton',0);$('BODY').append(selector);var trigger=input.data('trigger'),hidden=!input.is(':visible'),top=hidden?trigger.offset().top+trigger.outerHeight():input.offset().top+input.outerHeight(),left=hidden?trigger.offset().left:input.offset().left,selectorWidth=selector.outerWidth(),selectorHeight=selector.outerHeight(),triggerWidth=trigger.outerWidth(),triggerHeight=trigger.outerHeight(),windowHeight=$(window).height(),windowWidth=$(window).width(),scrollTop=$(window).scrollTop(),scrollLeft=$(window).scrollLeft();if((top+selectorHeight)>windowHeight+scrollTop)top=top-selectorHeight-triggerHeight;if((left+selectorWidth)>windowWidth+scrollLeft)left=left-selectorWidth+triggerWidth;selector.css({top:top,left:left}).fadeIn(100);selector.on('selectstart',function(){return false});if(!$.browser.msie||($.browser.msie&&$.browser.version>=9)){$(window).on('resize.miniColors',function(event){hide(input)})}$(document).on('mousedown.miniColors touchstart.miniColors',function(event){input.data('mousebutton',1);var testSubject=$(event.target).parents().andSelf();if(testSubject.hasClass('miniColors-colors')){event.preventDefault();input.data('moving','colors');moveColor(input,event)}if(testSubject.hasClass('miniColors-hues')){event.preventDefault();input.data('moving','hues');moveHue(input,event)}if(testSubject.hasClass('miniColors-opacity')){event.preventDefault();input.data('moving','opacity');moveOpacity(input,event)}if(testSubject.hasClass('miniColors-selector')){event.preventDefault();return}if(testSubject.hasClass('miniColors'))return;hide(input)}).on('mouseup.miniColors touchend.miniColors',function(event){event.preventDefault();input.data('mousebutton',0).removeData('moving')}).on('mousemove.miniColors touchmove.miniColors',function(event){event.preventDefault();if(input.data('mousebutton')===1){if(input.data('moving')==='colors')moveColor(input,event);if(input.data('moving')==='hues')moveHue(input,event);if(input.data('moving')==='opacity')moveOpacity(input,event)}});if(input.data('open')){input.data('open').call(input.get(0),'#'+hsb2hex(hsb),$.extend(hsb2rgb(hsb),{a:parseFloat(input.attr('data-opacity'))}))}};var hide=function(input){if(!input)input=$('.miniColors');input.each(function(){var selector=$(this).data('selector');$(this).removeData('selector');$(selector).fadeOut(100,function(){if(input.data('close')){var hsb=input.data('hsb'),hex=hsb2hex(hsb);input.data('close').call(input.get(0),'#'+hex,$.extend(hsb2rgb(hsb),{a:parseFloat(input.attr('data-opacity'))}))}$(this).remove()})});$(document).off('.miniColors')};var moveColor=function(input,event){var colorPicker=input.data('colorPicker');colorPicker.hide();var position={x:event.pageX,y:event.pageY};if(event.originalEvent.changedTouches){position.x=event.originalEvent.changedTouches[0].pageX;position.y=event.originalEvent.changedTouches[0].pageY}position.x=position.x-input.data('selector').find('.miniColors-colors').offset().left-6;position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-6;if(position.x<=-5)position.x=-5;if(position.x>=144)position.x=144;if(position.y<=-5)position.y=-5;if(position.y>=144)position.y=144;input.data('colorPosition',position);colorPicker.css('left',position.x).css('top',position.y).show();var s=Math.round((position.x+5)*0.67);if(s<0)s=0;if(s>100)s=100;var b=100-Math.round((position.y+5)*0.67);if(b<0)b=0;if(b>100)b=100;var hsb=input.data('hsb');hsb.s=s;hsb.b=b;setColor(input,hsb,true)};var moveHue=function(input,event){var huePicker=input.data('huePicker');huePicker.hide();var position=event.pageY;if(event.originalEvent.changedTouches){position=event.originalEvent.changedTouches[0].pageY}position=position-input.data('selector').find('.miniColors-colors').offset().top-1;if(position<=-1)position=-1;if(position>=149)position=149;input.data('huePosition',position);huePicker.css('top',position).show();var h=Math.round((150-position-1)*2.4);if(h<0)h=0;if(h>360)h=360;var hsb=input.data('hsb');hsb.h=h;setColor(input,hsb,true)};var moveOpacity=function(input,event){var opacityPicker=input.data('opacityPicker');opacityPicker.hide();var position=event.pageY;if(event.originalEvent.changedTouches){position=event.originalEvent.changedTouches[0].pageY}position=position-input.data('selector').find('.miniColors-colors').offset().top-1;if(position<=-1)position=-1;if(position>=149)position=149;input.data('opacityPosition',position);opacityPicker.css('top',position).show();var alpha=parseFloat((150-position-1)/150).toFixed(2);if(alpha<0)alpha=0;if(alpha>1)alpha=1;input.data('alpha',alpha).attr('data-opacity',alpha);setColor(input,input.data('hsb'),true)};var setColor=function(input,hsb,updateInput){input.data('hsb',hsb);var hex=hsb2hex(hsb),selector=$(input.data('selector'));if(updateInput)input.val('#'+convertCase(hex,input.data('letterCase')));selector.find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100})).end().find('.miniColors-opacity').css('backgroundColor','#'+hex).end();var rgb=hsb2rgb(hsb);input.data('trigger').css('backgroundColor','#'+hex);if(input.data('opacity')){input.data('trigger').css('backgroundColor','rgba('+rgb.r+', '+rgb.g+', '+rgb.b+', '+input.attr('data-opacity')+')')}if(input.data('change')){if((hex+','+input.attr('data-opacity'))===input.data('lastChange'))return;input.data('change').call(input.get(0),'#'+hex,$.extend(hsb2rgb(hsb),{a:parseFloat(input.attr('data-opacity'))}));input.data('lastChange',hex+','+input.attr('data-opacity'))}};var setColorFromInput=function(input){input.val('#'+cleanHex(input.val()));var hex=expandHex(input.val());if(!hex)return false;var hsb=hex2hsb(hex);var colorPosition=getColorPositionFromHSB(hsb);var colorPicker=$(input.data('colorPicker'));colorPicker.css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');input.data('colorPosition',colorPosition);var huePosition=getHuePositionFromHSB(hsb);var huePicker=$(input.data('huePicker'));huePicker.css('top',huePosition+'px');input.data('huePosition',huePosition);var opacityPosition=getOpacityPositionFromAlpha(input.attr('data-opacity'));var opacityPicker=$(input.data('opacityPicker'));opacityPicker.css('top',opacityPosition+'px');input.data('opacityPosition',opacityPosition);setColor(input,hsb);return true};var convertCase=function(string,letterCase){if(letterCase==='uppercase'){return string.toUpperCase()}else{return string.toLowerCase()}};var getColorPositionFromHSB=function(hsb){var x=Math.ceil(hsb.s/0.67);if(x<0)x=0;if(x>150)x=150;var y=150-Math.ceil(hsb.b/0.67);if(y<0)y=0;if(y>150)y=150;return{x:x-5,y:y-5}};var getHuePositionFromHSB=function(hsb){var y=150-(hsb.h/2.4);if(y<0)h=0;if(y>150)h=150;return y};var getOpacityPositionFromAlpha=function(alpha){var y=150*alpha;if(y<0)y=0;if(y>150)y=150;return 150-y};var cleanHex=function(hex){return hex.replace(/[^A-F0-9]/ig,'')};var expandHex=function(hex){hex=cleanHex(hex);if(!hex)return null;if(hex.length===3)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];return hex.length===6?hex:null};var hsb2rgb=function(hsb){var rgb={};var h=Math.round(hsb.h);var s=Math.round(hsb.s*255/100);var v=Math.round(hsb.b*255/100);if(s===0){rgb.r=rgb.g=rgb.b=v}else{var t1=v;var t2=(255-s)*v/255;var t3=(t1-t2)*(h%60)/60;if(h===360)h=0;if(h<60){rgb.r=t1;rgb.b=t2;rgb.g=t2+t3}else if(h<120){rgb.g=t1;rgb.b=t2;rgb.r=t1-t3}else if(h<180){rgb.g=t1;rgb.r=t2;rgb.b=t2+t3}else if(h<240){rgb.b=t1;rgb.r=t2;rgb.g=t1-t3}else if(h<300){rgb.b=t1;rgb.g=t2;rgb.r=t2+t3}else if(h<360){rgb.r=t1;rgb.g=t2;rgb.b=t1-t3}else{rgb.r=0;rgb.g=0;rgb.b=0}}return{r:Math.round(rgb.r),g:Math.round(rgb.g),b:Math.round(rgb.b)}};var rgb2hex=function(rgb){var hex=[rgb.r.toString(16),rgb.g.toString(16),rgb.b.toString(16)];$.each(hex,function(nr,val){if(val.length===1)hex[nr]='0'+val});return hex.join('')};var hex2rgb=function(hex){hex=parseInt(((hex.indexOf('#')>-1)?hex.substring(1):hex),16);return{r:hex>>16,g:(hex&0x00FF00)>>8,b:(hex&0x0000FF)}};var rgb2hsb=function(rgb){var hsb={h:0,s:0,b:0};var min=Math.min(rgb.r,rgb.g,rgb.b);var max=Math.max(rgb.r,rgb.g,rgb.b);var delta=max-min;hsb.b=max;hsb.s=max!==0?255*delta/max:0;if(hsb.s!==0){if(rgb.r===max){hsb.h=(rgb.g-rgb.b)/delta}else if(rgb.g===max){hsb.h=2+(rgb.b-rgb.r)/delta}else{hsb.h=4+(rgb.r-rgb.g)/delta}}else{hsb.h=-1}hsb.h*=60;if(hsb.h<0){hsb.h+=360}hsb.s*=100/255;hsb.b*=100/255;return hsb};var hex2hsb=function(hex){var hsb=rgb2hsb(hex2rgb(hex));if(hsb.s===0)hsb.h=360;return hsb};var hsb2hex=function(hsb){return rgb2hex(hsb2rgb(hsb))};switch(o){case'readonly':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).prop('readonly',data)});return $(this);case'disabled':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;if(data){disable($(this))}else{enable($(this))}});return $(this);case'value':if(data===undefined){if(!$(this).hasClass('miniColors'))return;var input=$(this),hex=expandHex(input.val());return hex?'#'+convertCase(hex,input.data('letterCase')):null}$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).val(data);setColorFromInput($(this))});return $(this);case'opacity':if(data===undefined){if(!$(this).hasClass('miniColors'))return;if($(this).data('opacity')){return parseFloat($(this).attr('data-opacity'))}else{return null}}$(this).each(function(){if(!$(this).hasClass('miniColors'))return;if(data<0)data=0;if(data>1)data=1;$(this).attr('data-opacity',data).data('alpha',data);setColorFromInput($(this))});return $(this);case'destroy':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;destroy($(this))});return $(this);default:if(!o)o={};$(this).each(function(){if($(this)[0].tagName.toLowerCase()!=='input')return;if($(this).data('trigger'))return;create($(this),o,data)});return $(this)}}})})(jQuery); \ No newline at end of file diff --git a/apps/user_openid/class.openid.v3.php b/3rdparty/openid/class.openid.v3.php similarity index 100% rename from apps/user_openid/class.openid.v3.php rename to 3rdparty/openid/class.openid.v3.php diff --git a/apps/user_openid/phpmyid.php b/3rdparty/openid/phpmyid.php similarity index 100% rename from apps/user_openid/phpmyid.php rename to 3rdparty/openid/phpmyid.php diff --git a/3rdparty/php-cloudfiles/cloudfiles.php b/3rdparty/php-cloudfiles/cloudfiles.php index 5f7e2100a9..7b1014265e 100644 --- a/3rdparty/php-cloudfiles/cloudfiles.php +++ b/3rdparty/php-cloudfiles/cloudfiles.php @@ -2000,7 +2000,7 @@ class CF_Object // } //use OC's mimetype detection for files - if(is_file($handle)){ + if(@is_file($handle)){ $this->content_type=OC_Helper::getMimeType($handle); }else{ $this->content_type=OC_Helper::getStringMimeType($handle); @@ -2537,7 +2537,7 @@ class CF_Object } $md5 = hash_final($ctx, false); rewind($data); - } elseif ((string)is_file($data)) { + } elseif ((string)@is_file($data)) { $md5 = md5_file($data); } else { $md5 = md5($data); diff --git a/3rdparty/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE b/3rdparty/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE deleted file mode 100644 index a65e83e876..0000000000 --- a/3rdparty/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE +++ /dev/null @@ -1,399 +0,0 @@ -Simple Test interface changes -============================= -Because the SimpleTest tool set is still evolving it is likely that tests -written with earlier versions will fail with the newest ones. The most -dramatic changes are in the alpha releases. Here is a list of possible -problems and their fixes... - -assertText() no longer finds a string inside a ', 'js'); - $this->mapHandler('comment', 'ignore'); - $this->addEntryPattern('', 'comment'); - } - - /** - * Pattern matches to start and end a tag. - * @param string $tag Name of tag to scan for. - * @access private - */ - protected function addTag($tag) { - $this->addSpecialPattern("", 'text', 'acceptEndToken'); - $this->addEntryPattern("<$tag", 'text', 'tag'); - } - - /** - * Pattern matches to parse the inside of a tag - * including the attributes and their quoting. - * @access private - */ - protected function addInTagTokens() { - $this->mapHandler('tag', 'acceptStartToken'); - $this->addSpecialPattern('\s+', 'tag', 'ignore'); - $this->addAttributeTokens(); - $this->addExitPattern('/>', 'tag'); - $this->addExitPattern('>', 'tag'); - } - - /** - * Matches attributes that are either single quoted, - * double quoted or unquoted. - * @access private - */ - protected function addAttributeTokens() { - $this->mapHandler('dq_attribute', 'acceptAttributeToken'); - $this->addEntryPattern('=\s*"', 'tag', 'dq_attribute'); - $this->addPattern("\\\\\"", 'dq_attribute'); - $this->addExitPattern('"', 'dq_attribute'); - $this->mapHandler('sq_attribute', 'acceptAttributeToken'); - $this->addEntryPattern("=\s*'", 'tag', 'sq_attribute'); - $this->addPattern("\\\\'", 'sq_attribute'); - $this->addExitPattern("'", 'sq_attribute'); - $this->mapHandler('uq_attribute', 'acceptAttributeToken'); - $this->addSpecialPattern('=\s*[^>\s]*', 'tag', 'uq_attribute'); - } -} - -/** - * Converts HTML tokens into selected SAX events. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleHtmlSaxParser { - private $lexer; - private $listener; - private $tag; - private $attributes; - private $current_attribute; - - /** - * Sets the listener. - * @param SimplePhpPageBuilder $listener SAX event handler. - * @access public - */ - function __construct($listener) { - $this->listener = $listener; - $this->lexer = $this->createLexer($this); - $this->tag = ''; - $this->attributes = array(); - $this->current_attribute = ''; - } - - /** - * Runs the content through the lexer which - * should call back to the acceptors. - * @param string $raw Page text to parse. - * @return boolean False if parse error. - * @access public - */ - function parse($raw) { - return $this->lexer->parse($raw); - } - - /** - * Sets up the matching lexer. Starts in 'text' mode. - * @param SimpleSaxParser $parser Event generator, usually $self. - * @return SimpleLexer Lexer suitable for this parser. - * @access public - */ - static function createLexer(&$parser) { - return new SimpleHtmlLexer($parser); - } - - /** - * Accepts a token from the tag mode. If the - * starting element completes then the element - * is dispatched and the current attributes - * set back to empty. The element or attribute - * name is converted to lower case. - * @param string $token Incoming characters. - * @param integer $event Lexer event type. - * @return boolean False if parse error. - * @access public - */ - function acceptStartToken($token, $event) { - if ($event == LEXER_ENTER) { - $this->tag = strtolower(substr($token, 1)); - return true; - } - if ($event == LEXER_EXIT) { - $success = $this->listener->startElement( - $this->tag, - $this->attributes); - $this->tag = ''; - $this->attributes = array(); - return $success; - } - if ($token != '=') { - $this->current_attribute = strtolower(html_entity_decode($token, ENT_QUOTES)); - $this->attributes[$this->current_attribute] = ''; - } - return true; - } - - /** - * Accepts a token from the end tag mode. - * The element name is converted to lower case. - * @param string $token Incoming characters. - * @param integer $event Lexer event type. - * @return boolean False if parse error. - * @access public - */ - function acceptEndToken($token, $event) { - if (! preg_match('/<\/(.*)>/', $token, $matches)) { - return false; - } - return $this->listener->endElement(strtolower($matches[1])); - } - - /** - * Part of the tag data. - * @param string $token Incoming characters. - * @param integer $event Lexer event type. - * @return boolean False if parse error. - * @access public - */ - function acceptAttributeToken($token, $event) { - if ($this->current_attribute) { - if ($event == LEXER_UNMATCHED) { - $this->attributes[$this->current_attribute] .= - html_entity_decode($token, ENT_QUOTES); - } - if ($event == LEXER_SPECIAL) { - $this->attributes[$this->current_attribute] .= - preg_replace('/^=\s*/' , '', html_entity_decode($token, ENT_QUOTES)); - } - } - return true; - } - - /** - * A character entity. - * @param string $token Incoming characters. - * @param integer $event Lexer event type. - * @return boolean False if parse error. - * @access public - */ - function acceptEntityToken($token, $event) { - } - - /** - * Character data between tags regarded as - * important. - * @param string $token Incoming characters. - * @param integer $event Lexer event type. - * @return boolean False if parse error. - * @access public - */ - function acceptTextToken($token, $event) { - return $this->listener->addContent($token); - } - - /** - * Incoming data to be ignored. - * @param string $token Incoming characters. - * @param integer $event Lexer event type. - * @return boolean False if parse error. - * @access public - */ - function ignore($token, $event) { - return true; - } -} - -/** - * SAX event handler. Maintains a list of - * open tags and dispatches them as they close. - * @package SimpleTest - * @subpackage WebTester - */ -class SimplePhpPageBuilder { - private $tags; - private $page; - private $private_content_tag; - private $open_forms = array(); - private $complete_forms = array(); - private $frameset = false; - private $loading_frames = array(); - private $frameset_nesting_level = 0; - private $left_over_labels = array(); - - /** - * Frees up any references so as to allow the PHP garbage - * collection from unset() to work. - * @access public - */ - function free() { - unset($this->tags); - unset($this->page); - unset($this->private_content_tags); - $this->open_forms = array(); - $this->complete_forms = array(); - $this->frameset = false; - $this->loading_frames = array(); - $this->frameset_nesting_level = 0; - $this->left_over_labels = array(); - } - - /** - * This builder is always available. - * @return boolean Always true. - */ - function can() { - return true; - } - - /** - * Reads the raw content and send events - * into the page to be built. - * @param $response SimpleHttpResponse Fetched response. - * @return SimplePage Newly parsed page. - * @access public - */ - function parse($response) { - $this->tags = array(); - $this->page = $this->createPage($response); - $parser = $this->createParser($this); - $parser->parse($response->getContent()); - $this->acceptPageEnd(); - $page = $this->page; - $this->free(); - return $page; - } - - /** - * Creates an empty page. - * @return SimplePage New unparsed page. - * @access protected - */ - protected function createPage($response) { - return new SimplePage($response); - } - - /** - * Creates the parser used with the builder. - * @param SimplePhpPageBuilder $listener Target of parser. - * @return SimpleSaxParser Parser to generate - * events for the builder. - * @access protected - */ - protected function createParser(&$listener) { - return new SimpleHtmlSaxParser($listener); - } - - /** - * Start of element event. Opens a new tag. - * @param string $name Element name. - * @param hash $attributes Attributes without content - * are marked as true. - * @return boolean False on parse error. - * @access public - */ - function startElement($name, $attributes) { - $factory = new SimpleTagBuilder(); - $tag = $factory->createTag($name, $attributes); - if (! $tag) { - return true; - } - if ($tag->getTagName() == 'label') { - $this->acceptLabelStart($tag); - $this->openTag($tag); - return true; - } - if ($tag->getTagName() == 'form') { - $this->acceptFormStart($tag); - return true; - } - if ($tag->getTagName() == 'frameset') { - $this->acceptFramesetStart($tag); - return true; - } - if ($tag->getTagName() == 'frame') { - $this->acceptFrame($tag); - return true; - } - if ($tag->isPrivateContent() && ! isset($this->private_content_tag)) { - $this->private_content_tag = &$tag; - } - if ($tag->expectEndTag()) { - $this->openTag($tag); - return true; - } - $this->acceptTag($tag); - return true; - } - - /** - * End of element event. - * @param string $name Element name. - * @return boolean False on parse error. - * @access public - */ - function endElement($name) { - if ($name == 'label') { - $this->acceptLabelEnd(); - return true; - } - if ($name == 'form') { - $this->acceptFormEnd(); - return true; - } - if ($name == 'frameset') { - $this->acceptFramesetEnd(); - return true; - } - if ($this->hasNamedTagOnOpenTagStack($name)) { - $tag = array_pop($this->tags[$name]); - if ($tag->isPrivateContent() && $this->private_content_tag->getTagName() == $name) { - unset($this->private_content_tag); - } - $this->addContentTagToOpenTags($tag); - $this->acceptTag($tag); - return true; - } - return true; - } - - /** - * Test to see if there are any open tags awaiting - * closure that match the tag name. - * @param string $name Element name. - * @return boolean True if any are still open. - * @access private - */ - protected function hasNamedTagOnOpenTagStack($name) { - return isset($this->tags[$name]) && (count($this->tags[$name]) > 0); - } - - /** - * Unparsed, but relevant data. The data is added - * to every open tag. - * @param string $text May include unparsed tags. - * @return boolean False on parse error. - * @access public - */ - function addContent($text) { - if (isset($this->private_content_tag)) { - $this->private_content_tag->addContent($text); - } else { - $this->addContentToAllOpenTags($text); - } - return true; - } - - /** - * Any content fills all currently open tags unless it - * is part of an option tag. - * @param string $text May include unparsed tags. - * @access private - */ - protected function addContentToAllOpenTags($text) { - foreach (array_keys($this->tags) as $name) { - for ($i = 0, $count = count($this->tags[$name]); $i < $count; $i++) { - $this->tags[$name][$i]->addContent($text); - } - } - } - - /** - * Parsed data in tag form. The parsed tag is added - * to every open tag. Used for adding options to select - * fields only. - * @param SimpleTag $tag Option tags only. - * @access private - */ - protected function addContentTagToOpenTags(&$tag) { - if ($tag->getTagName() != 'option') { - return; - } - foreach (array_keys($this->tags) as $name) { - for ($i = 0, $count = count($this->tags[$name]); $i < $count; $i++) { - $this->tags[$name][$i]->addTag($tag); - } - } - } - - /** - * Opens a tag for receiving content. Multiple tags - * will be receiving input at the same time. - * @param SimpleTag $tag New content tag. - * @access private - */ - protected function openTag($tag) { - $name = $tag->getTagName(); - if (! in_array($name, array_keys($this->tags))) { - $this->tags[$name] = array(); - } - $this->tags[$name][] = $tag; - } - - /** - * Adds a tag to the page. - * @param SimpleTag $tag Tag to accept. - * @access public - */ - protected function acceptTag($tag) { - if ($tag->getTagName() == "a") { - $this->page->addLink($tag); - } elseif ($tag->getTagName() == "base") { - $this->page->setBase($tag->getAttribute('href')); - } elseif ($tag->getTagName() == "title") { - $this->page->setTitle($tag); - } elseif ($this->isFormElement($tag->getTagName())) { - for ($i = 0; $i < count($this->open_forms); $i++) { - $this->open_forms[$i]->addWidget($tag); - } - $this->last_widget = $tag; - } - } - - /** - * Opens a label for a described widget. - * @param SimpleFormTag $tag Tag to accept. - * @access public - */ - protected function acceptLabelStart($tag) { - $this->label = $tag; - unset($this->last_widget); - } - - /** - * Closes the most recently opened label. - * @access public - */ - protected function acceptLabelEnd() { - if (isset($this->label)) { - if (isset($this->last_widget)) { - $this->last_widget->setLabel($this->label->getText()); - unset($this->last_widget); - } else { - $this->left_over_labels[] = SimpleTestCompatibility::copy($this->label); - } - unset($this->label); - } - } - - /** - * Tests to see if a tag is a possible form - * element. - * @param string $name HTML element name. - * @return boolean True if form element. - * @access private - */ - protected function isFormElement($name) { - return in_array($name, array('input', 'button', 'textarea', 'select')); - } - - /** - * Opens a form. New widgets go here. - * @param SimpleFormTag $tag Tag to accept. - * @access public - */ - protected function acceptFormStart($tag) { - $this->open_forms[] = new SimpleForm($tag, $this->page); - } - - /** - * Closes the most recently opened form. - * @access public - */ - protected function acceptFormEnd() { - if (count($this->open_forms)) { - $this->complete_forms[] = array_pop($this->open_forms); - } - } - - /** - * Opens a frameset. A frameset may contain nested - * frameset tags. - * @param SimpleFramesetTag $tag Tag to accept. - * @access public - */ - protected function acceptFramesetStart($tag) { - if (! $this->isLoadingFrames()) { - $this->frameset = $tag; - } - $this->frameset_nesting_level++; - } - - /** - * Closes the most recently opened frameset. - * @access public - */ - protected function acceptFramesetEnd() { - if ($this->isLoadingFrames()) { - $this->frameset_nesting_level--; - } - } - - /** - * Takes a single frame tag and stashes it in - * the current frame set. - * @param SimpleFrameTag $tag Tag to accept. - * @access public - */ - protected function acceptFrame($tag) { - if ($this->isLoadingFrames()) { - if ($tag->getAttribute('src')) { - $this->loading_frames[] = $tag; - } - } - } - - /** - * Test to see if in the middle of reading - * a frameset. - * @return boolean True if inframeset. - * @access private - */ - protected function isLoadingFrames() { - return $this->frameset and $this->frameset_nesting_level > 0; - } - - /** - * Marker for end of complete page. Any work in - * progress can now be closed. - * @access public - */ - protected function acceptPageEnd() { - while (count($this->open_forms)) { - $this->complete_forms[] = array_pop($this->open_forms); - } - foreach ($this->left_over_labels as $label) { - for ($i = 0, $count = count($this->complete_forms); $i < $count; $i++) { - $this->complete_forms[$i]->attachLabelBySelector( - new SimpleById($label->getFor()), - $label->getText()); - } - } - $this->page->setForms($this->complete_forms); - $this->page->setFrames($this->loading_frames); - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/recorder.php b/3rdparty/simpletest/recorder.php deleted file mode 100644 index b3d0d01c62..0000000000 --- a/3rdparty/simpletest/recorder.php +++ /dev/null @@ -1,101 +0,0 @@ -time, $this->breadcrumb, $this->message) = - array(time(), $breadcrumb, $message); - } -} - -/** - * A single pass captured for later. - * @package SimpleTest - * @subpackage Extensions - */ -class SimpleResultOfPass extends SimpleResult { } - -/** - * A single failure captured for later. - * @package SimpleTest - * @subpackage Extensions - */ -class SimpleResultOfFail extends SimpleResult { } - -/** - * A single exception captured for later. - * @package SimpleTest - * @subpackage Extensions - */ -class SimpleResultOfException extends SimpleResult { } - -/** - * Array-based test recorder. Returns an array - * with timestamp, status, test name and message for each pass and failure. - * @package SimpleTest - * @subpackage Extensions - */ -class Recorder extends SimpleReporterDecorator { - public $results = array(); - - /** - * Stashes the pass as a SimpleResultOfPass - * for later retrieval. - * @param string $message Pass message to be displayed - * eventually. - */ - function paintPass($message) { - parent::paintPass($message); - $this->results[] = new SimpleResultOfPass(parent::getTestList(), $message); - } - - /** - * Stashes the fail as a SimpleResultOfFail - * for later retrieval. - * @param string $message Failure message to be displayed - * eventually. - */ - function paintFail($message) { - parent::paintFail($message); - $this->results[] = new SimpleResultOfFail(parent::getTestList(), $message); - } - - /** - * Stashes the exception as a SimpleResultOfException - * for later retrieval. - * @param string $message Exception message to be displayed - * eventually. - */ - function paintException($message) { - parent::paintException($message); - $this->results[] = new SimpleResultOfException(parent::getTestList(), $message); - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/reflection_php4.php b/3rdparty/simpletest/reflection_php4.php deleted file mode 100644 index 39801ea1bd..0000000000 --- a/3rdparty/simpletest/reflection_php4.php +++ /dev/null @@ -1,136 +0,0 @@ -_interface = $interface; - } - - /** - * Checks that a class has been declared. - * @return boolean True if defined. - * @access public - */ - function classExists() { - return class_exists($this->_interface); - } - - /** - * Needed to kill the autoload feature in PHP5 - * for classes created dynamically. - * @return boolean True if defined. - * @access public - */ - function classExistsSansAutoload() { - return class_exists($this->_interface); - } - - /** - * Checks that a class or interface has been - * declared. - * @return boolean True if defined. - * @access public - */ - function classOrInterfaceExists() { - return class_exists($this->_interface); - } - - /** - * Needed to kill the autoload feature in PHP5 - * for classes created dynamically. - * @return boolean True if defined. - * @access public - */ - function classOrInterfaceExistsSansAutoload() { - return class_exists($this->_interface); - } - - /** - * Gets the list of methods on a class or - * interface. - * @returns array List of method names. - * @access public - */ - function getMethods() { - return get_class_methods($this->_interface); - } - - /** - * Gets the list of interfaces from a class. If the - * class name is actually an interface then just that - * interface is returned. - * @returns array List of interfaces. - * @access public - */ - function getInterfaces() { - return array(); - } - - /** - * Finds the parent class name. - * @returns string Parent class name. - * @access public - */ - function getParent() { - return strtolower(get_parent_class($this->_interface)); - } - - /** - * Determines if the class is abstract, which for PHP 4 - * will never be the case. - * @returns boolean True if abstract. - * @access public - */ - function isAbstract() { - return false; - } - - /** - * Determines if the the entity is an interface, which for PHP 4 - * will never be the case. - * @returns boolean True if interface. - * @access public - */ - function isInterface() { - return false; - } - - /** - * Scans for final methods, but as it's PHP 4 there - * aren't any. - * @returns boolean True if the class has a final method. - * @access public - */ - function hasFinal() { - return false; - } - - /** - * Gets the source code matching the declaration - * of a method. - * @param string $method Method name. - * @access public - */ - function getSignature($method) { - return "function &$method()"; - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/reflection_php5.php b/3rdparty/simpletest/reflection_php5.php deleted file mode 100644 index 43d8a7b287..0000000000 --- a/3rdparty/simpletest/reflection_php5.php +++ /dev/null @@ -1,386 +0,0 @@ -interface = $interface; - } - - /** - * Checks that a class has been declared. Versions - * before PHP5.0.2 need a check that it's not really - * an interface. - * @return boolean True if defined. - * @access public - */ - function classExists() { - if (! class_exists($this->interface)) { - return false; - } - $reflection = new ReflectionClass($this->interface); - return ! $reflection->isInterface(); - } - - /** - * Needed to kill the autoload feature in PHP5 - * for classes created dynamically. - * @return boolean True if defined. - * @access public - */ - function classExistsSansAutoload() { - return class_exists($this->interface, false); - } - - /** - * Checks that a class or interface has been - * declared. - * @return boolean True if defined. - * @access public - */ - function classOrInterfaceExists() { - return $this->classOrInterfaceExistsWithAutoload($this->interface, true); - } - - /** - * Needed to kill the autoload feature in PHP5 - * for classes created dynamically. - * @return boolean True if defined. - * @access public - */ - function classOrInterfaceExistsSansAutoload() { - return $this->classOrInterfaceExistsWithAutoload($this->interface, false); - } - - /** - * Needed to select the autoload feature in PHP5 - * for classes created dynamically. - * @param string $interface Class or interface name. - * @param boolean $autoload True totriggerautoload. - * @return boolean True if interface defined. - * @access private - */ - protected function classOrInterfaceExistsWithAutoload($interface, $autoload) { - if (function_exists('interface_exists')) { - if (interface_exists($this->interface, $autoload)) { - return true; - } - } - return class_exists($this->interface, $autoload); - } - - /** - * Gets the list of methods on a class or - * interface. - * @returns array List of method names. - * @access public - */ - function getMethods() { - return array_unique(get_class_methods($this->interface)); - } - - /** - * Gets the list of interfaces from a class. If the - * class name is actually an interface then just that - * interface is returned. - * @returns array List of interfaces. - * @access public - */ - function getInterfaces() { - $reflection = new ReflectionClass($this->interface); - if ($reflection->isInterface()) { - return array($this->interface); - } - return $this->onlyParents($reflection->getInterfaces()); - } - - /** - * Gets the list of methods for the implemented - * interfaces only. - * @returns array List of enforced method signatures. - * @access public - */ - function getInterfaceMethods() { - $methods = array(); - foreach ($this->getInterfaces() as $interface) { - $methods = array_merge($methods, get_class_methods($interface)); - } - return array_unique($methods); - } - - /** - * Checks to see if the method signature has to be tightly - * specified. - * @param string $method Method name. - * @returns boolean True if enforced. - * @access private - */ - protected function isInterfaceMethod($method) { - return in_array($method, $this->getInterfaceMethods()); - } - - /** - * Finds the parent class name. - * @returns string Parent class name. - * @access public - */ - function getParent() { - $reflection = new ReflectionClass($this->interface); - $parent = $reflection->getParentClass(); - if ($parent) { - return $parent->getName(); - } - return false; - } - - /** - * Trivially determines if the class is abstract. - * @returns boolean True if abstract. - * @access public - */ - function isAbstract() { - $reflection = new ReflectionClass($this->interface); - return $reflection->isAbstract(); - } - - /** - * Trivially determines if the class is an interface. - * @returns boolean True if interface. - * @access public - */ - function isInterface() { - $reflection = new ReflectionClass($this->interface); - return $reflection->isInterface(); - } - - /** - * Scans for final methods, as they screw up inherited - * mocks by not allowing you to override them. - * @returns boolean True if the class has a final method. - * @access public - */ - function hasFinal() { - $reflection = new ReflectionClass($this->interface); - foreach ($reflection->getMethods() as $method) { - if ($method->isFinal()) { - return true; - } - } - return false; - } - - /** - * Whittles a list of interfaces down to only the - * necessary top level parents. - * @param array $interfaces Reflection API interfaces - * to reduce. - * @returns array List of parent interface names. - * @access private - */ - protected function onlyParents($interfaces) { - $parents = array(); - $blacklist = array(); - foreach ($interfaces as $interface) { - foreach($interfaces as $possible_parent) { - if ($interface->getName() == $possible_parent->getName()) { - continue; - } - if ($interface->isSubClassOf($possible_parent)) { - $blacklist[$possible_parent->getName()] = true; - } - } - if (!isset($blacklist[$interface->getName()])) { - $parents[] = $interface->getName(); - } - } - return $parents; - } - - /** - * Checks whether a method is abstract or not. - * @param string $name Method name. - * @return bool true if method is abstract, else false - * @access private - */ - protected function isAbstractMethod($name) { - $interface = new ReflectionClass($this->interface); - if (! $interface->hasMethod($name)) { - return false; - } - return $interface->getMethod($name)->isAbstract(); - } - - /** - * Checks whether a method is the constructor. - * @param string $name Method name. - * @return bool true if method is the constructor - * @access private - */ - protected function isConstructor($name) { - return ($name == '__construct') || ($name == $this->interface); - } - - /** - * Checks whether a method is abstract in all parents or not. - * @param string $name Method name. - * @return bool true if method is abstract in parent, else false - * @access private - */ - protected function isAbstractMethodInParents($name) { - $interface = new ReflectionClass($this->interface); - $parent = $interface->getParentClass(); - while($parent) { - if (! $parent->hasMethod($name)) { - return false; - } - if ($parent->getMethod($name)->isAbstract()) { - return true; - } - $parent = $parent->getParentClass(); - } - return false; - } - - /** - * Checks whether a method is static or not. - * @param string $name Method name - * @return bool true if method is static, else false - * @access private - */ - protected function isStaticMethod($name) { - $interface = new ReflectionClass($this->interface); - if (! $interface->hasMethod($name)) { - return false; - } - return $interface->getMethod($name)->isStatic(); - } - - /** - * Writes the source code matching the declaration - * of a method. - * @param string $name Method name. - * @return string Method signature up to last - * bracket. - * @access public - */ - function getSignature($name) { - if ($name == '__set') { - return 'function __set($key, $value)'; - } - if ($name == '__call') { - return 'function __call($method, $arguments)'; - } - if (version_compare(phpversion(), '5.1.0', '>=')) { - if (in_array($name, array('__get', '__isset', $name == '__unset'))) { - return "function {$name}(\$key)"; - } - } - if ($name == '__toString') { - return "function $name()"; - } - - // This wonky try-catch is a work around for a faulty method_exists() - // in early versions of PHP 5 which would return false for static - // methods. The Reflection classes work fine, but hasMethod() - // doesn't exist prior to PHP 5.1.0, so we need to use a more crude - // detection method. - try { - $interface = new ReflectionClass($this->interface); - $interface->getMethod($name); - } catch (ReflectionException $e) { - return "function $name()"; - } - return $this->getFullSignature($name); - } - - /** - * For a signature specified in an interface, full - * details must be replicated to be a valid implementation. - * @param string $name Method name. - * @return string Method signature up to last - * bracket. - * @access private - */ - protected function getFullSignature($name) { - $interface = new ReflectionClass($this->interface); - $method = $interface->getMethod($name); - $reference = $method->returnsReference() ? '&' : ''; - $static = $method->isStatic() ? 'static ' : ''; - return "{$static}function $reference$name(" . - implode(', ', $this->getParameterSignatures($method)) . - ")"; - } - - /** - * Gets the source code for each parameter. - * @param ReflectionMethod $method Method object from - * reflection API - * @return array List of strings, each - * a snippet of code. - * @access private - */ - protected function getParameterSignatures($method) { - $signatures = array(); - foreach ($method->getParameters() as $parameter) { - $signature = ''; - $type = $parameter->getClass(); - if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) { - $signature .= 'array '; - } elseif (!is_null($type)) { - $signature .= $type->getName() . ' '; - } - if ($parameter->isPassedByReference()) { - $signature .= '&'; - } - $signature .= '$' . $this->suppressSpurious($parameter->getName()); - if ($this->isOptional($parameter)) { - $signature .= ' = null'; - } - $signatures[] = $signature; - } - return $signatures; - } - - /** - * The SPL library has problems with the - * Reflection library. In particular, you can - * get extra characters in parameter names :(. - * @param string $name Parameter name. - * @return string Cleaner name. - * @access private - */ - protected function suppressSpurious($name) { - return str_replace(array('[', ']', ' '), '', $name); - } - - /** - * Test of a reflection parameter being optional - * that works with early versions of PHP5. - * @param reflectionParameter $parameter Is this optional. - * @return boolean True if optional. - * @access private - */ - protected function isOptional($parameter) { - if (method_exists($parameter, 'isOptional')) { - return $parameter->isOptional(); - } - return false; - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/remote.php b/3rdparty/simpletest/remote.php deleted file mode 100644 index 4bb37b7c51..0000000000 --- a/3rdparty/simpletest/remote.php +++ /dev/null @@ -1,115 +0,0 @@ -url = $url; - $this->dry_url = $dry_url ? $dry_url : $url; - $this->size = false; - } - - /** - * Accessor for the test name for subclasses. - * @return string Name of the test. - * @access public - */ - function getLabel() { - return $this->url; - } - - /** - * Runs the top level test for this class. Currently - * reads the data as a single chunk. I'll fix this - * once I have added iteration to the browser. - * @param SimpleReporter $reporter Target of test results. - * @returns boolean True if no failures. - * @access public - */ - function run($reporter) { - $browser = $this->createBrowser(); - $xml = $browser->get($this->url); - if (! $xml) { - trigger_error('Cannot read remote test URL [' . $this->url . ']'); - return false; - } - $parser = $this->createParser($reporter); - if (! $parser->parse($xml)) { - trigger_error('Cannot parse incoming XML from [' . $this->url . ']'); - return false; - } - return true; - } - - /** - * Creates a new web browser object for fetching - * the XML report. - * @return SimpleBrowser New browser. - * @access protected - */ - protected function createBrowser() { - return new SimpleBrowser(); - } - - /** - * Creates the XML parser. - * @param SimpleReporter $reporter Target of test results. - * @return SimpleTestXmlListener XML reader. - * @access protected - */ - protected function createParser($reporter) { - return new SimpleTestXmlParser($reporter); - } - - /** - * Accessor for the number of subtests. - * @return integer Number of test cases. - * @access public - */ - function getSize() { - if ($this->size === false) { - $browser = $this->createBrowser(); - $xml = $browser->get($this->dry_url); - if (! $xml) { - trigger_error('Cannot read remote test URL [' . $this->dry_url . ']'); - return false; - } - $reporter = new SimpleReporter(); - $parser = $this->createParser($reporter); - if (! $parser->parse($xml)) { - trigger_error('Cannot parse incoming XML from [' . $this->dry_url . ']'); - return false; - } - $this->size = $reporter->getTestCaseCount(); - } - return $this->size; - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/reporter.php b/3rdparty/simpletest/reporter.php deleted file mode 100644 index bd4f3fa41d..0000000000 --- a/3rdparty/simpletest/reporter.php +++ /dev/null @@ -1,445 +0,0 @@ -character_set = $character_set; - } - - /** - * Paints the top of the web page setting the - * title to the name of the starting test. - * @param string $test_name Name class of test. - * @access public - */ - function paintHeader($test_name) { - $this->sendNoCacheHeaders(); - print ""; - print "\n\n$test_name\n"; - print "\n"; - print "\n"; - print "\n\n"; - print "

                $test_name

                \n"; - flush(); - } - - /** - * Send the headers necessary to ensure the page is - * reloaded on every request. Otherwise you could be - * scratching your head over out of date test data. - * @access public - */ - static function sendNoCacheHeaders() { - if (! headers_sent()) { - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - } - } - - /** - * Paints the CSS. Add additional styles here. - * @return string CSS code as text. - * @access protected - */ - protected function getCss() { - return ".fail { background-color: inherit; color: red; }" . - ".pass { background-color: inherit; color: green; }" . - " pre { background-color: lightgray; color: inherit; }"; - } - - /** - * Paints the end of the test with a summary of - * the passes and failures. - * @param string $test_name Name class of test. - * @access public - */ - function paintFooter($test_name) { - $colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green"); - print "
                "; - print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount(); - print " test cases complete:\n"; - print "" . $this->getPassCount() . " passes, "; - print "" . $this->getFailCount() . " fails and "; - print "" . $this->getExceptionCount() . " exceptions."; - print "
                \n"; - print "\n\n"; - } - - /** - * Paints the test failure with a breadcrumbs - * trail of the nesting test suites below the - * top level test. - * @param string $message Failure message displayed in - * the context of the other tests. - */ - function paintFail($message) { - parent::paintFail($message); - print "Fail: "; - $breadcrumb = $this->getTestList(); - array_shift($breadcrumb); - print implode(" -> ", $breadcrumb); - print " -> " . $this->htmlEntities($message) . "
                \n"; - } - - /** - * Paints a PHP error. - * @param string $message Message is ignored. - * @access public - */ - function paintError($message) { - parent::paintError($message); - print "Exception: "; - $breadcrumb = $this->getTestList(); - array_shift($breadcrumb); - print implode(" -> ", $breadcrumb); - print " -> " . $this->htmlEntities($message) . "
                \n"; - } - - /** - * Paints a PHP exception. - * @param Exception $exception Exception to display. - * @access public - */ - function paintException($exception) { - parent::paintException($exception); - print "Exception: "; - $breadcrumb = $this->getTestList(); - array_shift($breadcrumb); - print implode(" -> ", $breadcrumb); - $message = 'Unexpected exception of type [' . get_class($exception) . - '] with message ['. $exception->getMessage() . - '] in ['. $exception->getFile() . - ' line ' . $exception->getLine() . ']'; - print " -> " . $this->htmlEntities($message) . "
                \n"; - } - - /** - * Prints the message for skipping tests. - * @param string $message Text of skip condition. - * @access public - */ - function paintSkip($message) { - parent::paintSkip($message); - print "Skipped: "; - $breadcrumb = $this->getTestList(); - array_shift($breadcrumb); - print implode(" -> ", $breadcrumb); - print " -> " . $this->htmlEntities($message) . "
                \n"; - } - - /** - * Paints formatted text such as dumped privateiables. - * @param string $message Text to show. - * @access public - */ - function paintFormattedMessage($message) { - print '
                ' . $this->htmlEntities($message) . '
                '; - } - - /** - * Character set adjusted entity conversion. - * @param string $message Plain text or Unicode message. - * @return string Browser readable message. - * @access protected - */ - protected function htmlEntities($message) { - return htmlentities($message, ENT_COMPAT, $this->character_set); - } -} - -/** - * Sample minimal test displayer. Generates only - * failure messages and a pass count. For command - * line use. I've tried to make it look like JUnit, - * but I wanted to output the errors as they arrived - * which meant dropping the dots. - * @package SimpleTest - * @subpackage UnitTester - */ -class TextReporter extends SimpleReporter { - - /** - * Does nothing yet. The first output will - * be sent on the first test start. - */ - function __construct() { - parent::__construct(); - } - - /** - * Paints the title only. - * @param string $test_name Name class of test. - * @access public - */ - function paintHeader($test_name) { - if (! SimpleReporter::inCli()) { - header('Content-type: text/plain'); - } - print "$test_name\n"; - flush(); - } - - /** - * Paints the end of the test with a summary of - * the passes and failures. - * @param string $test_name Name class of test. - * @access public - */ - function paintFooter($test_name) { - if ($this->getFailCount() + $this->getExceptionCount() == 0) { - print "OK\n"; - } else { - print "FAILURES!!!\n"; - } - print "Test cases run: " . $this->getTestCaseProgress() . - "/" . $this->getTestCaseCount() . - ", Passes: " . $this->getPassCount() . - ", Failures: " . $this->getFailCount() . - ", Exceptions: " . $this->getExceptionCount() . "\n"; - } - - /** - * Paints the test failure as a stack trace. - * @param string $message Failure message displayed in - * the context of the other tests. - * @access public - */ - function paintFail($message) { - parent::paintFail($message); - print $this->getFailCount() . ") $message\n"; - $breadcrumb = $this->getTestList(); - array_shift($breadcrumb); - print "\tin " . implode("\n\tin ", array_reverse($breadcrumb)); - print "\n"; - } - - /** - * Paints a PHP error or exception. - * @param string $message Message to be shown. - * @access public - * @abstract - */ - function paintError($message) { - parent::paintError($message); - print "Exception " . $this->getExceptionCount() . "!\n$message\n"; - $breadcrumb = $this->getTestList(); - array_shift($breadcrumb); - print "\tin " . implode("\n\tin ", array_reverse($breadcrumb)); - print "\n"; - } - - /** - * Paints a PHP error or exception. - * @param Exception $exception Exception to describe. - * @access public - * @abstract - */ - function paintException($exception) { - parent::paintException($exception); - $message = 'Unexpected exception of type [' . get_class($exception) . - '] with message ['. $exception->getMessage() . - '] in ['. $exception->getFile() . - ' line ' . $exception->getLine() . ']'; - print "Exception " . $this->getExceptionCount() . "!\n$message\n"; - $breadcrumb = $this->getTestList(); - array_shift($breadcrumb); - print "\tin " . implode("\n\tin ", array_reverse($breadcrumb)); - print "\n"; - } - - /** - * Prints the message for skipping tests. - * @param string $message Text of skip condition. - * @access public - */ - function paintSkip($message) { - parent::paintSkip($message); - print "Skip: $message\n"; - } - - /** - * Paints formatted text such as dumped privateiables. - * @param string $message Text to show. - * @access public - */ - function paintFormattedMessage($message) { - print "$message\n"; - flush(); - } -} - -/** - * Runs just a single test group, a single case or - * even a single test within that case. - * @package SimpleTest - * @subpackage UnitTester - */ -class SelectiveReporter extends SimpleReporterDecorator { - private $just_this_case = false; - private $just_this_test = false; - private $on; - - /** - * Selects the test case or group to be run, - * and optionally a specific test. - * @param SimpleScorer $reporter Reporter to receive events. - * @param string $just_this_case Only this case or group will run. - * @param string $just_this_test Only this test method will run. - */ - function __construct($reporter, $just_this_case = false, $just_this_test = false) { - if (isset($just_this_case) && $just_this_case) { - $this->just_this_case = strtolower($just_this_case); - $this->off(); - } else { - $this->on(); - } - if (isset($just_this_test) && $just_this_test) { - $this->just_this_test = strtolower($just_this_test); - } - parent::__construct($reporter); - } - - /** - * Compares criteria to actual the case/group name. - * @param string $test_case The incoming test. - * @return boolean True if matched. - * @access protected - */ - protected function matchesTestCase($test_case) { - return $this->just_this_case == strtolower($test_case); - } - - /** - * Compares criteria to actual the test name. If no - * name was specified at the beginning, then all tests - * can run. - * @param string $method The incoming test method. - * @return boolean True if matched. - * @access protected - */ - protected function shouldRunTest($test_case, $method) { - if ($this->isOn() || $this->matchesTestCase($test_case)) { - if ($this->just_this_test) { - return $this->just_this_test == strtolower($method); - } else { - return true; - } - } - return false; - } - - /** - * Switch on testing for the group or subgroup. - * @access private - */ - protected function on() { - $this->on = true; - } - - /** - * Switch off testing for the group or subgroup. - * @access private - */ - protected function off() { - $this->on = false; - } - - /** - * Is this group actually being tested? - * @return boolean True if the current test group is active. - * @access private - */ - protected function isOn() { - return $this->on; - } - - /** - * Veto everything that doesn't match the method wanted. - * @param string $test_case Name of test case. - * @param string $method Name of test method. - * @return boolean True if test should be run. - * @access public - */ - function shouldInvoke($test_case, $method) { - if ($this->shouldRunTest($test_case, $method)) { - return $this->reporter->shouldInvoke($test_case, $method); - } - return false; - } - - /** - * Paints the start of a group test. - * @param string $test_case Name of test or other label. - * @param integer $size Number of test cases starting. - * @access public - */ - function paintGroupStart($test_case, $size) { - if ($this->just_this_case && $this->matchesTestCase($test_case)) { - $this->on(); - } - $this->reporter->paintGroupStart($test_case, $size); - } - - /** - * Paints the end of a group test. - * @param string $test_case Name of test or other label. - * @access public - */ - function paintGroupEnd($test_case) { - $this->reporter->paintGroupEnd($test_case); - if ($this->just_this_case && $this->matchesTestCase($test_case)) { - $this->off(); - } - } -} - -/** - * Suppresses skip messages. - * @package SimpleTest - * @subpackage UnitTester - */ -class NoSkipsReporter extends SimpleReporterDecorator { - - /** - * Does nothing. - * @param string $message Text of skip condition. - * @access public - */ - function paintSkip($message) { } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/scorer.php b/3rdparty/simpletest/scorer.php deleted file mode 100644 index 27776f4b63..0000000000 --- a/3rdparty/simpletest/scorer.php +++ /dev/null @@ -1,875 +0,0 @@ -passes = 0; - $this->fails = 0; - $this->exceptions = 0; - $this->is_dry_run = false; - } - - /** - * Signals that the next evaluation will be a dry - * run. That is, the structure events will be - * recorded, but no tests will be run. - * @param boolean $is_dry Dry run if true. - * @access public - */ - function makeDry($is_dry = true) { - $this->is_dry_run = $is_dry; - } - - /** - * The reporter has a veto on what should be run. - * @param string $test_case_name name of test case. - * @param string $method Name of test method. - * @access public - */ - function shouldInvoke($test_case_name, $method) { - return ! $this->is_dry_run; - } - - /** - * Can wrap the invoker in preperation for running - * a test. - * @param SimpleInvoker $invoker Individual test runner. - * @return SimpleInvoker Wrapped test runner. - * @access public - */ - function createInvoker($invoker) { - return $invoker; - } - - /** - * Accessor for current status. Will be false - * if there have been any failures or exceptions. - * Used for command line tools. - * @return boolean True if no failures. - * @access public - */ - function getStatus() { - if ($this->exceptions + $this->fails > 0) { - return false; - } - return true; - } - - /** - * Paints the start of a group test. - * @param string $test_name Name of test or other label. - * @param integer $size Number of test cases starting. - * @access public - */ - function paintGroupStart($test_name, $size) { - } - - /** - * Paints the end of a group test. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintGroupEnd($test_name) { - } - - /** - * Paints the start of a test case. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintCaseStart($test_name) { - } - - /** - * Paints the end of a test case. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintCaseEnd($test_name) { - } - - /** - * Paints the start of a test method. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintMethodStart($test_name) { - } - - /** - * Paints the end of a test method. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintMethodEnd($test_name) { - } - - /** - * Increments the pass count. - * @param string $message Message is ignored. - * @access public - */ - function paintPass($message) { - $this->passes++; - } - - /** - * Increments the fail count. - * @param string $message Message is ignored. - * @access public - */ - function paintFail($message) { - $this->fails++; - } - - /** - * Deals with PHP 4 throwing an error. - * @param string $message Text of error formatted by - * the test case. - * @access public - */ - function paintError($message) { - $this->exceptions++; - } - - /** - * Deals with PHP 5 throwing an exception. - * @param Exception $exception The actual exception thrown. - * @access public - */ - function paintException($exception) { - $this->exceptions++; - } - - /** - * Prints the message for skipping tests. - * @param string $message Text of skip condition. - * @access public - */ - function paintSkip($message) { - } - - /** - * Accessor for the number of passes so far. - * @return integer Number of passes. - * @access public - */ - function getPassCount() { - return $this->passes; - } - - /** - * Accessor for the number of fails so far. - * @return integer Number of fails. - * @access public - */ - function getFailCount() { - return $this->fails; - } - - /** - * Accessor for the number of untrapped errors - * so far. - * @return integer Number of exceptions. - * @access public - */ - function getExceptionCount() { - return $this->exceptions; - } - - /** - * Paints a simple supplementary message. - * @param string $message Text to display. - * @access public - */ - function paintMessage($message) { - } - - /** - * Paints a formatted ASCII message such as a - * privateiable dump. - * @param string $message Text to display. - * @access public - */ - function paintFormattedMessage($message) { - } - - /** - * By default just ignores user generated events. - * @param string $type Event type as text. - * @param mixed $payload Message or object. - * @access public - */ - function paintSignal($type, $payload) { - } -} - -/** - * Recipient of generated test messages that can display - * page footers and headers. Also keeps track of the - * test nesting. This is the main base class on which - * to build the finished test (page based) displays. - * @package SimpleTest - * @subpackage UnitTester - */ -class SimpleReporter extends SimpleScorer { - private $test_stack; - private $size; - private $progress; - - /** - * Starts the display with no results in. - * @access public - */ - function __construct() { - parent::__construct(); - $this->test_stack = array(); - $this->size = null; - $this->progress = 0; - } - - /** - * Gets the formatter for small generic data items. - * @return SimpleDumper Formatter. - * @access public - */ - function getDumper() { - return new SimpleDumper(); - } - - /** - * Paints the start of a group test. Will also paint - * the page header and footer if this is the - * first test. Will stash the size if the first - * start. - * @param string $test_name Name of test that is starting. - * @param integer $size Number of test cases starting. - * @access public - */ - function paintGroupStart($test_name, $size) { - if (! isset($this->size)) { - $this->size = $size; - } - if (count($this->test_stack) == 0) { - $this->paintHeader($test_name); - } - $this->test_stack[] = $test_name; - } - - /** - * Paints the end of a group test. Will paint the page - * footer if the stack of tests has unwound. - * @param string $test_name Name of test that is ending. - * @param integer $progress Number of test cases ending. - * @access public - */ - function paintGroupEnd($test_name) { - array_pop($this->test_stack); - if (count($this->test_stack) == 0) { - $this->paintFooter($test_name); - } - } - - /** - * Paints the start of a test case. Will also paint - * the page header and footer if this is the - * first test. Will stash the size if the first - * start. - * @param string $test_name Name of test that is starting. - * @access public - */ - function paintCaseStart($test_name) { - if (! isset($this->size)) { - $this->size = 1; - } - if (count($this->test_stack) == 0) { - $this->paintHeader($test_name); - } - $this->test_stack[] = $test_name; - } - - /** - * Paints the end of a test case. Will paint the page - * footer if the stack of tests has unwound. - * @param string $test_name Name of test that is ending. - * @access public - */ - function paintCaseEnd($test_name) { - $this->progress++; - array_pop($this->test_stack); - if (count($this->test_stack) == 0) { - $this->paintFooter($test_name); - } - } - - /** - * Paints the start of a test method. - * @param string $test_name Name of test that is starting. - * @access public - */ - function paintMethodStart($test_name) { - $this->test_stack[] = $test_name; - } - - /** - * Paints the end of a test method. Will paint the page - * footer if the stack of tests has unwound. - * @param string $test_name Name of test that is ending. - * @access public - */ - function paintMethodEnd($test_name) { - array_pop($this->test_stack); - } - - /** - * Paints the test document header. - * @param string $test_name First test top level - * to start. - * @access public - * @abstract - */ - function paintHeader($test_name) { - } - - /** - * Paints the test document footer. - * @param string $test_name The top level test. - * @access public - * @abstract - */ - function paintFooter($test_name) { - } - - /** - * Accessor for internal test stack. For - * subclasses that need to see the whole test - * history for display purposes. - * @return array List of methods in nesting order. - * @access public - */ - function getTestList() { - return $this->test_stack; - } - - /** - * Accessor for total test size in number - * of test cases. Null until the first - * test is started. - * @return integer Total number of cases at start. - * @access public - */ - function getTestCaseCount() { - return $this->size; - } - - /** - * Accessor for the number of test cases - * completed so far. - * @return integer Number of ended cases. - * @access public - */ - function getTestCaseProgress() { - return $this->progress; - } - - /** - * Static check for running in the comand line. - * @return boolean True if CLI. - * @access public - */ - static function inCli() { - return php_sapi_name() == 'cli'; - } -} - -/** - * For modifying the behaviour of the visual reporters. - * @package SimpleTest - * @subpackage UnitTester - */ -class SimpleReporterDecorator { - protected $reporter; - - /** - * Mediates between the reporter and the test case. - * @param SimpleScorer $reporter Reporter to receive events. - */ - function __construct($reporter) { - $this->reporter = $reporter; - } - - /** - * Signals that the next evaluation will be a dry - * run. That is, the structure events will be - * recorded, but no tests will be run. - * @param boolean $is_dry Dry run if true. - * @access public - */ - function makeDry($is_dry = true) { - $this->reporter->makeDry($is_dry); - } - - /** - * Accessor for current status. Will be false - * if there have been any failures or exceptions. - * Used for command line tools. - * @return boolean True if no failures. - * @access public - */ - function getStatus() { - return $this->reporter->getStatus(); - } - - /** - * The nesting of the test cases so far. Not - * all reporters have this facility. - * @return array Test list if accessible. - * @access public - */ - function getTestList() { - if (method_exists($this->reporter, 'getTestList')) { - return $this->reporter->getTestList(); - } else { - return array(); - } - } - - /** - * The reporter has a veto on what should be run. - * @param string $test_case_name Name of test case. - * @param string $method Name of test method. - * @return boolean True if test should be run. - * @access public - */ - function shouldInvoke($test_case_name, $method) { - return $this->reporter->shouldInvoke($test_case_name, $method); - } - - /** - * Can wrap the invoker in preparation for running - * a test. - * @param SimpleInvoker $invoker Individual test runner. - * @return SimpleInvoker Wrapped test runner. - * @access public - */ - function createInvoker($invoker) { - return $this->reporter->createInvoker($invoker); - } - - /** - * Gets the formatter for privateiables and other small - * generic data items. - * @return SimpleDumper Formatter. - * @access public - */ - function getDumper() { - return $this->reporter->getDumper(); - } - - /** - * Paints the start of a group test. - * @param string $test_name Name of test or other label. - * @param integer $size Number of test cases starting. - * @access public - */ - function paintGroupStart($test_name, $size) { - $this->reporter->paintGroupStart($test_name, $size); - } - - /** - * Paints the end of a group test. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintGroupEnd($test_name) { - $this->reporter->paintGroupEnd($test_name); - } - - /** - * Paints the start of a test case. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintCaseStart($test_name) { - $this->reporter->paintCaseStart($test_name); - } - - /** - * Paints the end of a test case. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintCaseEnd($test_name) { - $this->reporter->paintCaseEnd($test_name); - } - - /** - * Paints the start of a test method. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintMethodStart($test_name) { - $this->reporter->paintMethodStart($test_name); - } - - /** - * Paints the end of a test method. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintMethodEnd($test_name) { - $this->reporter->paintMethodEnd($test_name); - } - - /** - * Chains to the wrapped reporter. - * @param string $message Message is ignored. - * @access public - */ - function paintPass($message) { - $this->reporter->paintPass($message); - } - - /** - * Chains to the wrapped reporter. - * @param string $message Message is ignored. - * @access public - */ - function paintFail($message) { - $this->reporter->paintFail($message); - } - - /** - * Chains to the wrapped reporter. - * @param string $message Text of error formatted by - * the test case. - * @access public - */ - function paintError($message) { - $this->reporter->paintError($message); - } - - /** - * Chains to the wrapped reporter. - * @param Exception $exception Exception to show. - * @access public - */ - function paintException($exception) { - $this->reporter->paintException($exception); - } - - /** - * Prints the message for skipping tests. - * @param string $message Text of skip condition. - * @access public - */ - function paintSkip($message) { - $this->reporter->paintSkip($message); - } - - /** - * Chains to the wrapped reporter. - * @param string $message Text to display. - * @access public - */ - function paintMessage($message) { - $this->reporter->paintMessage($message); - } - - /** - * Chains to the wrapped reporter. - * @param string $message Text to display. - * @access public - */ - function paintFormattedMessage($message) { - $this->reporter->paintFormattedMessage($message); - } - - /** - * Chains to the wrapped reporter. - * @param string $type Event type as text. - * @param mixed $payload Message or object. - * @return boolean Should return false if this - * type of signal should fail the - * test suite. - * @access public - */ - function paintSignal($type, $payload) { - $this->reporter->paintSignal($type, $payload); - } -} - -/** - * For sending messages to multiple reporters at - * the same time. - * @package SimpleTest - * @subpackage UnitTester - */ -class MultipleReporter { - private $reporters = array(); - - /** - * Adds a reporter to the subscriber list. - * @param SimpleScorer $reporter Reporter to receive events. - * @access public - */ - function attachReporter($reporter) { - $this->reporters[] = $reporter; - } - - /** - * Signals that the next evaluation will be a dry - * run. That is, the structure events will be - * recorded, but no tests will be run. - * @param boolean $is_dry Dry run if true. - * @access public - */ - function makeDry($is_dry = true) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->makeDry($is_dry); - } - } - - /** - * Accessor for current status. Will be false - * if there have been any failures or exceptions. - * If any reporter reports a failure, the whole - * suite fails. - * @return boolean True if no failures. - * @access public - */ - function getStatus() { - for ($i = 0; $i < count($this->reporters); $i++) { - if (! $this->reporters[$i]->getStatus()) { - return false; - } - } - return true; - } - - /** - * The reporter has a veto on what should be run. - * It requires all reporters to want to run the method. - * @param string $test_case_name name of test case. - * @param string $method Name of test method. - * @access public - */ - function shouldInvoke($test_case_name, $method) { - for ($i = 0; $i < count($this->reporters); $i++) { - if (! $this->reporters[$i]->shouldInvoke($test_case_name, $method)) { - return false; - } - } - return true; - } - - /** - * Every reporter gets a chance to wrap the invoker. - * @param SimpleInvoker $invoker Individual test runner. - * @return SimpleInvoker Wrapped test runner. - * @access public - */ - function createInvoker($invoker) { - for ($i = 0; $i < count($this->reporters); $i++) { - $invoker = $this->reporters[$i]->createInvoker($invoker); - } - return $invoker; - } - - /** - * Gets the formatter for privateiables and other small - * generic data items. - * @return SimpleDumper Formatter. - * @access public - */ - function getDumper() { - return new SimpleDumper(); - } - - /** - * Paints the start of a group test. - * @param string $test_name Name of test or other label. - * @param integer $size Number of test cases starting. - * @access public - */ - function paintGroupStart($test_name, $size) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintGroupStart($test_name, $size); - } - } - - /** - * Paints the end of a group test. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintGroupEnd($test_name) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintGroupEnd($test_name); - } - } - - /** - * Paints the start of a test case. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintCaseStart($test_name) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintCaseStart($test_name); - } - } - - /** - * Paints the end of a test case. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintCaseEnd($test_name) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintCaseEnd($test_name); - } - } - - /** - * Paints the start of a test method. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintMethodStart($test_name) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintMethodStart($test_name); - } - } - - /** - * Paints the end of a test method. - * @param string $test_name Name of test or other label. - * @access public - */ - function paintMethodEnd($test_name) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintMethodEnd($test_name); - } - } - - /** - * Chains to the wrapped reporter. - * @param string $message Message is ignored. - * @access public - */ - function paintPass($message) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintPass($message); - } - } - - /** - * Chains to the wrapped reporter. - * @param string $message Message is ignored. - * @access public - */ - function paintFail($message) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintFail($message); - } - } - - /** - * Chains to the wrapped reporter. - * @param string $message Text of error formatted by - * the test case. - * @access public - */ - function paintError($message) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintError($message); - } - } - - /** - * Chains to the wrapped reporter. - * @param Exception $exception Exception to display. - * @access public - */ - function paintException($exception) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintException($exception); - } - } - - /** - * Prints the message for skipping tests. - * @param string $message Text of skip condition. - * @access public - */ - function paintSkip($message) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintSkip($message); - } - } - - /** - * Chains to the wrapped reporter. - * @param string $message Text to display. - * @access public - */ - function paintMessage($message) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintMessage($message); - } - } - - /** - * Chains to the wrapped reporter. - * @param string $message Text to display. - * @access public - */ - function paintFormattedMessage($message) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintFormattedMessage($message); - } - } - - /** - * Chains to the wrapped reporter. - * @param string $type Event type as text. - * @param mixed $payload Message or object. - * @return boolean Should return false if this - * type of signal should fail the - * test suite. - * @access public - */ - function paintSignal($type, $payload) { - for ($i = 0; $i < count($this->reporters); $i++) { - $this->reporters[$i]->paintSignal($type, $payload); - } - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/selector.php b/3rdparty/simpletest/selector.php deleted file mode 100644 index ba2fed312a..0000000000 --- a/3rdparty/simpletest/selector.php +++ /dev/null @@ -1,141 +0,0 @@ -name = $name; - } - - /** - * Accessor for name. - * @returns string $name Name to match. - */ - function getName() { - return $this->name; - } - - /** - * Compares with name attribute of widget. - * @param SimpleWidget $widget Control to compare. - * @access public - */ - function isMatch($widget) { - return ($widget->getName() == $this->name); - } -} - -/** - * Used to extract form elements for testing against. - * Searches by visible label or alt text. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleByLabel { - private $label; - - /** - * Stashes the name for later comparison. - * @param string $label Visible text to match. - */ - function __construct($label) { - $this->label = $label; - } - - /** - * Comparison. Compares visible text of widget or - * related label. - * @param SimpleWidget $widget Control to compare. - * @access public - */ - function isMatch($widget) { - if (! method_exists($widget, 'isLabel')) { - return false; - } - return $widget->isLabel($this->label); - } -} - -/** - * Used to extract form elements for testing against. - * Searches dy id attribute. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleById { - private $id; - - /** - * Stashes the name for later comparison. - * @param string $id ID atribute to match. - */ - function __construct($id) { - $this->id = $id; - } - - /** - * Comparison. Compares id attribute of widget. - * @param SimpleWidget $widget Control to compare. - * @access public - */ - function isMatch($widget) { - return $widget->isId($this->id); - } -} - -/** - * Used to extract form elements for testing against. - * Searches by visible label, name or alt text. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleByLabelOrName { - private $label; - - /** - * Stashes the name/label for later comparison. - * @param string $label Visible text to match. - */ - function __construct($label) { - $this->label = $label; - } - - /** - * Comparison. Compares visible text of widget or - * related label or name. - * @param SimpleWidget $widget Control to compare. - * @access public - */ - function isMatch($widget) { - if (method_exists($widget, 'isLabel')) { - if ($widget->isLabel($this->label)) { - return true; - } - } - return ($widget->getName() == $this->label); - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/shell_tester.php b/3rdparty/simpletest/shell_tester.php deleted file mode 100644 index 9a3bd389ee..0000000000 --- a/3rdparty/simpletest/shell_tester.php +++ /dev/null @@ -1,330 +0,0 @@ -output = false; - } - - /** - * Actually runs the command. Does not trap the - * error stream output as this need PHP 4.3+. - * @param string $command The actual command line - * to run. - * @return integer Exit code. - * @access public - */ - function execute($command) { - $this->output = false; - exec($command, $this->output, $ret); - return $ret; - } - - /** - * Accessor for the last output. - * @return string Output as text. - * @access public - */ - function getOutput() { - return implode("\n", $this->output); - } - - /** - * Accessor for the last output. - * @return array Output as array of lines. - * @access public - */ - function getOutputAsList() { - return $this->output; - } -} - -/** - * Test case for testing of command line scripts and - * utilities. Usually scripts that are external to the - * PHP code, but support it in some way. - * @package SimpleTest - * @subpackage UnitTester - */ -class ShellTestCase extends SimpleTestCase { - private $current_shell; - private $last_status; - private $last_command; - - /** - * Creates an empty test case. Should be subclassed - * with test methods for a functional test case. - * @param string $label Name of test case. Will use - * the class name if none specified. - * @access public - */ - function __construct($label = false) { - parent::__construct($label); - $this->current_shell = $this->createShell(); - $this->last_status = false; - $this->last_command = ''; - } - - /** - * Executes a command and buffers the results. - * @param string $command Command to run. - * @return boolean True if zero exit code. - * @access public - */ - function execute($command) { - $shell = $this->getShell(); - $this->last_status = $shell->execute($command); - $this->last_command = $command; - return ($this->last_status === 0); - } - - /** - * Dumps the output of the last command. - * @access public - */ - function dumpOutput() { - $this->dump($this->getOutput()); - } - - /** - * Accessor for the last output. - * @return string Output as text. - * @access public - */ - function getOutput() { - $shell = $this->getShell(); - return $shell->getOutput(); - } - - /** - * Accessor for the last output. - * @return array Output as array of lines. - * @access public - */ - function getOutputAsList() { - $shell = $this->getShell(); - return $shell->getOutputAsList(); - } - - /** - * Called from within the test methods to register - * passes and failures. - * @param boolean $result Pass on true. - * @param string $message Message to display describing - * the test state. - * @return boolean True on pass - * @access public - */ - function assertTrue($result, $message = false) { - return $this->assert(new TrueExpectation(), $result, $message); - } - - /** - * Will be true on false and vice versa. False - * is the PHP definition of false, so that null, - * empty strings, zero and an empty array all count - * as false. - * @param boolean $result Pass on false. - * @param string $message Message to display. - * @return boolean True on pass - * @access public - */ - function assertFalse($result, $message = '%s') { - return $this->assert(new FalseExpectation(), $result, $message); - } - - /** - * Will trigger a pass if the two parameters have - * the same value only. Otherwise a fail. This - * is for testing hand extracted text, etc. - * @param mixed $first Value to compare. - * @param mixed $second Value to compare. - * @param string $message Message to display. - * @return boolean True on pass - * @access public - */ - function assertEqual($first, $second, $message = "%s") { - return $this->assert( - new EqualExpectation($first), - $second, - $message); - } - - /** - * Will trigger a pass if the two parameters have - * a different value. Otherwise a fail. This - * is for testing hand extracted text, etc. - * @param mixed $first Value to compare. - * @param mixed $second Value to compare. - * @param string $message Message to display. - * @return boolean True on pass - * @access public - */ - function assertNotEqual($first, $second, $message = "%s") { - return $this->assert( - new NotEqualExpectation($first), - $second, - $message); - } - - /** - * Tests the last status code from the shell. - * @param integer $status Expected status of last - * command. - * @param string $message Message to display. - * @return boolean True if pass. - * @access public - */ - function assertExitCode($status, $message = "%s") { - $message = sprintf($message, "Expected status code of [$status] from [" . - $this->last_command . "], but got [" . - $this->last_status . "]"); - return $this->assertTrue($status === $this->last_status, $message); - } - - /** - * Attempt to exactly match the combined STDERR and - * STDOUT output. - * @param string $expected Expected output. - * @param string $message Message to display. - * @return boolean True if pass. - * @access public - */ - function assertOutput($expected, $message = "%s") { - $shell = $this->getShell(); - return $this->assert( - new EqualExpectation($expected), - $shell->getOutput(), - $message); - } - - /** - * Scans the output for a Perl regex. If found - * anywhere it passes, else it fails. - * @param string $pattern Regex to search for. - * @param string $message Message to display. - * @return boolean True if pass. - * @access public - */ - function assertOutputPattern($pattern, $message = "%s") { - $shell = $this->getShell(); - return $this->assert( - new PatternExpectation($pattern), - $shell->getOutput(), - $message); - } - - /** - * If a Perl regex is found anywhere in the current - * output then a failure is generated, else a pass. - * @param string $pattern Regex to search for. - * @param $message Message to display. - * @return boolean True if pass. - * @access public - */ - function assertNoOutputPattern($pattern, $message = "%s") { - $shell = $this->getShell(); - return $this->assert( - new NoPatternExpectation($pattern), - $shell->getOutput(), - $message); - } - - /** - * File existence check. - * @param string $path Full filename and path. - * @param string $message Message to display. - * @return boolean True if pass. - * @access public - */ - function assertFileExists($path, $message = "%s") { - $message = sprintf($message, "File [$path] should exist"); - return $this->assertTrue(file_exists($path), $message); - } - - /** - * File non-existence check. - * @param string $path Full filename and path. - * @param string $message Message to display. - * @return boolean True if pass. - * @access public - */ - function assertFileNotExists($path, $message = "%s") { - $message = sprintf($message, "File [$path] should not exist"); - return $this->assertFalse(file_exists($path), $message); - } - - /** - * Scans a file for a Perl regex. If found - * anywhere it passes, else it fails. - * @param string $pattern Regex to search for. - * @param string $path Full filename and path. - * @param string $message Message to display. - * @return boolean True if pass. - * @access public - */ - function assertFilePattern($pattern, $path, $message = "%s") { - return $this->assert( - new PatternExpectation($pattern), - implode('', file($path)), - $message); - } - - /** - * If a Perl regex is found anywhere in the named - * file then a failure is generated, else a pass. - * @param string $pattern Regex to search for. - * @param string $path Full filename and path. - * @param string $message Message to display. - * @return boolean True if pass. - * @access public - */ - function assertNoFilePattern($pattern, $path, $message = "%s") { - return $this->assert( - new NoPatternExpectation($pattern), - implode('', file($path)), - $message); - } - - /** - * Accessor for current shell. Used for testing the - * the tester itself. - * @return Shell Current shell. - * @access protected - */ - protected function getShell() { - return $this->current_shell; - } - - /** - * Factory for the shell to run the command on. - * @return Shell New shell object. - * @access protected - */ - protected function createShell() { - return new SimpleShell(); - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/simpletest.php b/3rdparty/simpletest/simpletest.php deleted file mode 100644 index 425c869a82..0000000000 --- a/3rdparty/simpletest/simpletest.php +++ /dev/null @@ -1,391 +0,0 @@ -getParent()) { - SimpleTest::ignore($parent); - } - } - } - } - - /** - * Puts the object to the global pool of 'preferred' objects - * which can be retrieved with SimpleTest :: preferred() method. - * Instances of the same class are overwritten. - * @param object $object Preferred object - * @see preferred() - */ - static function prefer($object) { - $registry = &SimpleTest::getRegistry(); - $registry['Preferred'][] = $object; - } - - /** - * Retrieves 'preferred' objects from global pool. Class filter - * can be applied in order to retrieve the object of the specific - * class - * @param array|string $classes Allowed classes or interfaces. - * @return array|object|null - * @see prefer() - */ - static function preferred($classes) { - if (! is_array($classes)) { - $classes = array($classes); - } - $registry = &SimpleTest::getRegistry(); - for ($i = count($registry['Preferred']) - 1; $i >= 0; $i--) { - foreach ($classes as $class) { - if (SimpleTestCompatibility::isA($registry['Preferred'][$i], $class)) { - return $registry['Preferred'][$i]; - } - } - } - return null; - } - - /** - * Test to see if a test case is in the ignore - * list. Quite obviously the ignore list should - * be a separate object and will be one day. - * This method is internal to SimpleTest. Don't - * use it. - * @param string $class Class name to test. - * @return boolean True if should not be run. - */ - static function isIgnored($class) { - $registry = &SimpleTest::getRegistry(); - return isset($registry['IgnoreList'][strtolower($class)]); - } - - /** - * Sets proxy to use on all requests for when - * testing from behind a firewall. Set host - * to false to disable. This will take effect - * if there are no other proxy settings. - * @param string $proxy Proxy host as URL. - * @param string $username Proxy username for authentication. - * @param string $password Proxy password for authentication. - */ - static function useProxy($proxy, $username = false, $password = false) { - $registry = &SimpleTest::getRegistry(); - $registry['DefaultProxy'] = $proxy; - $registry['DefaultProxyUsername'] = $username; - $registry['DefaultProxyPassword'] = $password; - } - - /** - * Accessor for default proxy host. - * @return string Proxy URL. - */ - static function getDefaultProxy() { - $registry = &SimpleTest::getRegistry(); - return $registry['DefaultProxy']; - } - - /** - * Accessor for default proxy username. - * @return string Proxy username for authentication. - */ - static function getDefaultProxyUsername() { - $registry = &SimpleTest::getRegistry(); - return $registry['DefaultProxyUsername']; - } - - /** - * Accessor for default proxy password. - * @return string Proxy password for authentication. - */ - static function getDefaultProxyPassword() { - $registry = &SimpleTest::getRegistry(); - return $registry['DefaultProxyPassword']; - } - - /** - * Accessor for default HTML parsers. - * @return array List of parsers to try in - * order until one responds true - * to can(). - */ - static function getParsers() { - $registry = &SimpleTest::getRegistry(); - return $registry['Parsers']; - } - - /** - * Set the list of HTML parsers to attempt to use by default. - * @param array $parsers List of parsers to try in - * order until one responds true - * to can(). - */ - static function setParsers($parsers) { - $registry = &SimpleTest::getRegistry(); - $registry['Parsers'] = $parsers; - } - - /** - * Accessor for global registry of options. - * @return hash All stored values. - */ - protected static function &getRegistry() { - static $registry = false; - if (! $registry) { - $registry = SimpleTest::getDefaults(); - } - return $registry; - } - - /** - * Accessor for the context of the current - * test run. - * @return SimpleTestContext Current test run. - */ - static function getContext() { - static $context = false; - if (! $context) { - $context = new SimpleTestContext(); - } - return $context; - } - - /** - * Constant default values. - * @return hash All registry defaults. - */ - protected static function getDefaults() { - return array( - 'Parsers' => false, - 'MockBaseClass' => 'SimpleMock', - 'IgnoreList' => array(), - 'DefaultProxy' => false, - 'DefaultProxyUsername' => false, - 'DefaultProxyPassword' => false, - 'Preferred' => array(new HtmlReporter(), new TextReporter(), new XmlReporter())); - } - - /** - * @deprecated - */ - static function setMockBaseClass($mock_base) { - $registry = &SimpleTest::getRegistry(); - $registry['MockBaseClass'] = $mock_base; - } - - /** - * @deprecated - */ - static function getMockBaseClass() { - $registry = &SimpleTest::getRegistry(); - return $registry['MockBaseClass']; - } -} - -/** - * Container for all components for a specific - * test run. Makes things like error queues - * available to PHP event handlers, and also - * gets around some nasty reference issues in - * the mocks. - * @package SimpleTest - */ -class SimpleTestContext { - private $test; - private $reporter; - private $resources; - - /** - * Clears down the current context. - * @access public - */ - function clear() { - $this->resources = array(); - } - - /** - * Sets the current test case instance. This - * global instance can be used by the mock objects - * to send message to the test cases. - * @param SimpleTestCase $test Test case to register. - */ - function setTest($test) { - $this->clear(); - $this->test = $test; - } - - /** - * Accessor for currently running test case. - * @return SimpleTestCase Current test. - */ - function getTest() { - return $this->test; - } - - /** - * Sets the current reporter. This - * global instance can be used by the mock objects - * to send messages. - * @param SimpleReporter $reporter Reporter to register. - */ - function setReporter($reporter) { - $this->clear(); - $this->reporter = $reporter; - } - - /** - * Accessor for current reporter. - * @return SimpleReporter Current reporter. - */ - function getReporter() { - return $this->reporter; - } - - /** - * Accessor for the Singleton resource. - * @return object Global resource. - */ - function get($resource) { - if (! isset($this->resources[$resource])) { - $this->resources[$resource] = new $resource(); - } - return $this->resources[$resource]; - } -} - -/** - * Interrogates the stack trace to recover the - * failure point. - * @package SimpleTest - * @subpackage UnitTester - */ -class SimpleStackTrace { - private $prefixes; - - /** - * Stashes the list of target prefixes. - * @param array $prefixes List of method prefixes - * to search for. - */ - function __construct($prefixes) { - $this->prefixes = $prefixes; - } - - /** - * Extracts the last method name that was not within - * Simpletest itself. Captures a stack trace if none given. - * @param array $stack List of stack frames. - * @return string Snippet of test report with line - * number and file. - */ - function traceMethod($stack = false) { - $stack = $stack ? $stack : $this->captureTrace(); - foreach ($stack as $frame) { - if ($this->frameLiesWithinSimpleTestFolder($frame)) { - continue; - } - if ($this->frameMatchesPrefix($frame)) { - return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']'; - } - } - return ''; - } - - /** - * Test to see if error is generated by SimpleTest itself. - * @param array $frame PHP stack frame. - * @return boolean True if a SimpleTest file. - */ - protected function frameLiesWithinSimpleTestFolder($frame) { - if (isset($frame['file'])) { - $path = substr(SIMPLE_TEST, 0, -1); - if (strpos($frame['file'], $path) === 0) { - if (dirname($frame['file']) == $path) { - return true; - } - } - } - return false; - } - - /** - * Tries to determine if the method call is an assert, etc. - * @param array $frame PHP stack frame. - * @return boolean True if matches a target. - */ - protected function frameMatchesPrefix($frame) { - foreach ($this->prefixes as $prefix) { - if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) { - return true; - } - } - return false; - } - - /** - * Grabs a current stack trace. - * @return array Fulle trace. - */ - protected function captureTrace() { - if (function_exists('debug_backtrace')) { - return array_reverse(debug_backtrace()); - } - return array(); - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/socket.php b/3rdparty/simpletest/socket.php deleted file mode 100644 index 06e8ca62d0..0000000000 --- a/3rdparty/simpletest/socket.php +++ /dev/null @@ -1,312 +0,0 @@ -clearError(); - } - - /** - * Test for an outstanding error. - * @return boolean True if there is an error. - * @access public - */ - function isError() { - return ($this->error != ''); - } - - /** - * Accessor for an outstanding error. - * @return string Empty string if no error otherwise - * the error message. - * @access public - */ - function getError() { - return $this->error; - } - - /** - * Sets the internal error. - * @param string Error message to stash. - * @access protected - */ - function setError($error) { - $this->error = $error; - } - - /** - * Resets the error state to no error. - * @access protected - */ - function clearError() { - $this->setError(''); - } -} - -/** - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleFileSocket extends SimpleStickyError { - private $handle; - private $is_open = false; - private $sent = ''; - private $block_size; - - /** - * Opens a socket for reading and writing. - * @param SimpleUrl $file Target URI to fetch. - * @param integer $block_size Size of chunk to read. - * @access public - */ - function __construct($file, $block_size = 1024) { - parent::__construct(); - if (! ($this->handle = $this->openFile($file, $error))) { - $file_string = $file->asString(); - $this->setError("Cannot open [$file_string] with [$error]"); - return; - } - $this->is_open = true; - $this->block_size = $block_size; - } - - /** - * Writes some data to the socket and saves alocal copy. - * @param string $message String to send to socket. - * @return boolean True if successful. - * @access public - */ - function write($message) { - return true; - } - - /** - * Reads data from the socket. The error suppresion - * is a workaround for PHP4 always throwing a warning - * with a secure socket. - * @return integer/boolean Incoming bytes. False - * on error. - * @access public - */ - function read() { - $raw = @fread($this->handle, $this->block_size); - if ($raw === false) { - $this->setError('Cannot read from socket'); - $this->close(); - } - return $raw; - } - - /** - * Accessor for socket open state. - * @return boolean True if open. - * @access public - */ - function isOpen() { - return $this->is_open; - } - - /** - * Closes the socket preventing further reads. - * Cannot be reopened once closed. - * @return boolean True if successful. - * @access public - */ - function close() { - if (!$this->is_open) return false; - $this->is_open = false; - return fclose($this->handle); - } - - /** - * Accessor for content so far. - * @return string Bytes sent only. - * @access public - */ - function getSent() { - return $this->sent; - } - - /** - * Actually opens the low level socket. - * @param SimpleUrl $file SimpleUrl file target. - * @param string $error Recipient of error message. - * @param integer $timeout Maximum time to wait for connection. - * @access protected - */ - protected function openFile($file, &$error) { - return @fopen($file->asString(), 'r'); - } -} - -/** - * Wrapper for TCP/IP socket. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleSocket extends SimpleStickyError { - private $handle; - private $is_open = false; - private $sent = ''; - private $lock_size; - - /** - * Opens a socket for reading and writing. - * @param string $host Hostname to send request to. - * @param integer $port Port on remote machine to open. - * @param integer $timeout Connection timeout in seconds. - * @param integer $block_size Size of chunk to read. - * @access public - */ - function __construct($host, $port, $timeout, $block_size = 255) { - parent::__construct(); - if (! ($this->handle = $this->openSocket($host, $port, $error_number, $error, $timeout))) { - $this->setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds"); - return; - } - $this->is_open = true; - $this->block_size = $block_size; - SimpleTestCompatibility::setTimeout($this->handle, $timeout); - } - - /** - * Writes some data to the socket and saves alocal copy. - * @param string $message String to send to socket. - * @return boolean True if successful. - * @access public - */ - function write($message) { - if ($this->isError() || ! $this->isOpen()) { - return false; - } - $count = fwrite($this->handle, $message); - if (! $count) { - if ($count === false) { - $this->setError('Cannot write to socket'); - $this->close(); - } - return false; - } - fflush($this->handle); - $this->sent .= $message; - return true; - } - - /** - * Reads data from the socket. The error suppresion - * is a workaround for PHP4 always throwing a warning - * with a secure socket. - * @return integer/boolean Incoming bytes. False - * on error. - * @access public - */ - function read() { - if ($this->isError() || ! $this->isOpen()) { - return false; - } - $raw = @fread($this->handle, $this->block_size); - if ($raw === false) { - $this->setError('Cannot read from socket'); - $this->close(); - } - return $raw; - } - - /** - * Accessor for socket open state. - * @return boolean True if open. - * @access public - */ - function isOpen() { - return $this->is_open; - } - - /** - * Closes the socket preventing further reads. - * Cannot be reopened once closed. - * @return boolean True if successful. - * @access public - */ - function close() { - $this->is_open = false; - return fclose($this->handle); - } - - /** - * Accessor for content so far. - * @return string Bytes sent only. - * @access public - */ - function getSent() { - return $this->sent; - } - - /** - * Actually opens the low level socket. - * @param string $host Host to connect to. - * @param integer $port Port on host. - * @param integer $error_number Recipient of error code. - * @param string $error Recipoent of error message. - * @param integer $timeout Maximum time to wait for connection. - * @access protected - */ - protected function openSocket($host, $port, &$error_number, &$error, $timeout) { - return @fsockopen($host, $port, $error_number, $error, $timeout); - } -} - -/** - * Wrapper for TCP/IP socket over TLS. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleSecureSocket extends SimpleSocket { - - /** - * Opens a secure socket for reading and writing. - * @param string $host Hostname to send request to. - * @param integer $port Port on remote machine to open. - * @param integer $timeout Connection timeout in seconds. - * @access public - */ - function __construct($host, $port, $timeout) { - parent::__construct($host, $port, $timeout); - } - - /** - * Actually opens the low level socket. - * @param string $host Host to connect to. - * @param integer $port Port on host. - * @param integer $error_number Recipient of error code. - * @param string $error Recipient of error message. - * @param integer $timeout Maximum time to wait for connection. - * @access protected - */ - function openSocket($host, $port, &$error_number, &$error, $timeout) { - return parent::openSocket("tls://$host", $port, $error_number, $error, $timeout); - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/tag.php b/3rdparty/simpletest/tag.php deleted file mode 100644 index afe649ec5d..0000000000 --- a/3rdparty/simpletest/tag.php +++ /dev/null @@ -1,1527 +0,0 @@ - 'SimpleAnchorTag', - 'title' => 'SimpleTitleTag', - 'base' => 'SimpleBaseTag', - 'button' => 'SimpleButtonTag', - 'textarea' => 'SimpleTextAreaTag', - 'option' => 'SimpleOptionTag', - 'label' => 'SimpleLabelTag', - 'form' => 'SimpleFormTag', - 'frame' => 'SimpleFrameTag'); - $attributes = $this->keysToLowerCase($attributes); - if (array_key_exists($name, $map)) { - $tag_class = $map[$name]; - return new $tag_class($attributes); - } elseif ($name == 'select') { - return $this->createSelectionTag($attributes); - } elseif ($name == 'input') { - return $this->createInputTag($attributes); - } - return new SimpleTag($name, $attributes); - } - - /** - * Factory for selection fields. - * @param hash $attributes Element attributes. - * @return SimpleTag Tag object. - * @access protected - */ - protected function createSelectionTag($attributes) { - if (isset($attributes['multiple'])) { - return new MultipleSelectionTag($attributes); - } - return new SimpleSelectionTag($attributes); - } - - /** - * Factory for input tags. - * @param hash $attributes Element attributes. - * @return SimpleTag Tag object. - * @access protected - */ - protected function createInputTag($attributes) { - if (! isset($attributes['type'])) { - return new SimpleTextTag($attributes); - } - $type = strtolower(trim($attributes['type'])); - $map = array( - 'submit' => 'SimpleSubmitTag', - 'image' => 'SimpleImageSubmitTag', - 'checkbox' => 'SimpleCheckboxTag', - 'radio' => 'SimpleRadioButtonTag', - 'text' => 'SimpleTextTag', - 'hidden' => 'SimpleTextTag', - 'password' => 'SimpleTextTag', - 'file' => 'SimpleUploadTag'); - if (array_key_exists($type, $map)) { - $tag_class = $map[$type]; - return new $tag_class($attributes); - } - return false; - } - - /** - * Make the keys lower case for case insensitive look-ups. - * @param hash $map Hash to convert. - * @return hash Unchanged values, but keys lower case. - * @access private - */ - protected function keysToLowerCase($map) { - $lower = array(); - foreach ($map as $key => $value) { - $lower[strtolower($key)] = $value; - } - return $lower; - } -} - -/** - * HTML or XML tag. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleTag { - private $name; - private $attributes; - private $content; - - /** - * Starts with a named tag with attributes only. - * @param string $name Tag name. - * @param hash $attributes Attribute names and - * string values. Note that - * the keys must have been - * converted to lower case. - */ - function __construct($name, $attributes) { - $this->name = strtolower(trim($name)); - $this->attributes = $attributes; - $this->content = ''; - } - - /** - * Check to see if the tag can have both start and - * end tags with content in between. - * @return boolean True if content allowed. - * @access public - */ - function expectEndTag() { - return true; - } - - /** - * The current tag should not swallow all content for - * itself as it's searchable page content. Private - * content tags are usually widgets that contain default - * values. - * @return boolean False as content is available - * to other tags by default. - * @access public - */ - function isPrivateContent() { - return false; - } - - /** - * Appends string content to the current content. - * @param string $content Additional text. - * @access public - */ - function addContent($content) { - $this->content .= (string)$content; - return $this; - } - - /** - * Adds an enclosed tag to the content. - * @param SimpleTag $tag New tag. - * @access public - */ - function addTag($tag) { - } - - /** - * Adds multiple enclosed tags to the content. - * @param array List of SimpleTag objects to be added. - */ - function addTags($tags) { - foreach ($tags as $tag) { - $this->addTag($tag); - } - } - - /** - * Accessor for tag name. - * @return string Name of tag. - * @access public - */ - function getTagName() { - return $this->name; - } - - /** - * List of legal child elements. - * @return array List of element names. - * @access public - */ - function getChildElements() { - return array(); - } - - /** - * Accessor for an attribute. - * @param string $label Attribute name. - * @return string Attribute value. - * @access public - */ - function getAttribute($label) { - $label = strtolower($label); - if (! isset($this->attributes[$label])) { - return false; - } - return (string)$this->attributes[$label]; - } - - /** - * Sets an attribute. - * @param string $label Attribute name. - * @return string $value New attribute value. - * @access protected - */ - protected function setAttribute($label, $value) { - $this->attributes[strtolower($label)] = $value; - } - - /** - * Accessor for the whole content so far. - * @return string Content as big raw string. - * @access public - */ - function getContent() { - return $this->content; - } - - /** - * Accessor for content reduced to visible text. Acts - * like a text mode browser, normalising space and - * reducing images to their alt text. - * @return string Content as plain text. - * @access public - */ - function getText() { - return SimplePage::normalise($this->content); - } - - /** - * Test to see if id attribute matches. - * @param string $id ID to test against. - * @return boolean True on match. - * @access public - */ - function isId($id) { - return ($this->getAttribute('id') == $id); - } -} - -/** - * Base url. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleBaseTag extends SimpleTag { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('base', $attributes); - } - - /** - * Base tag is not a block tag. - * @return boolean false - * @access public - */ - function expectEndTag() { - return false; - } -} - -/** - * Page title. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleTitleTag extends SimpleTag { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('title', $attributes); - } -} - -/** - * Link. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleAnchorTag extends SimpleTag { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('a', $attributes); - } - - /** - * Accessor for URL as string. - * @return string Coerced as string. - * @access public - */ - function getHref() { - $url = $this->getAttribute('href'); - if (is_bool($url)) { - $url = ''; - } - return $url; - } -} - -/** - * Form element. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleWidget extends SimpleTag { - private $value; - private $label; - private $is_set; - - /** - * Starts with a named tag with attributes only. - * @param string $name Tag name. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($name, $attributes) { - parent::__construct($name, $attributes); - $this->value = false; - $this->label = false; - $this->is_set = false; - } - - /** - * Accessor for name submitted as the key in - * GET/POST privateiables hash. - * @return string Parsed value. - * @access public - */ - function getName() { - return $this->getAttribute('name'); - } - - /** - * Accessor for default value parsed with the tag. - * @return string Parsed value. - * @access public - */ - function getDefault() { - return $this->getAttribute('value'); - } - - /** - * Accessor for currently set value or default if - * none. - * @return string Value set by form or default - * if none. - * @access public - */ - function getValue() { - if (! $this->is_set) { - return $this->getDefault(); - } - return $this->value; - } - - /** - * Sets the current form element value. - * @param string $value New value. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - $this->value = $value; - $this->is_set = true; - return true; - } - - /** - * Resets the form element value back to the - * default. - * @access public - */ - function resetValue() { - $this->is_set = false; - } - - /** - * Allows setting of a label externally, say by a - * label tag. - * @param string $label Label to attach. - * @access public - */ - function setLabel($label) { - $this->label = trim($label); - return $this; - } - - /** - * Reads external or internal label. - * @param string $label Label to test. - * @return boolean True is match. - * @access public - */ - function isLabel($label) { - return $this->label == trim($label); - } - - /** - * Dispatches the value into the form encoded packet. - * @param SimpleEncoding $encoding Form packet. - * @access public - */ - function write($encoding) { - if ($this->getName()) { - $encoding->add($this->getName(), $this->getValue()); - } - } -} - -/** - * Text, password and hidden field. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleTextTag extends SimpleWidget { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('input', $attributes); - if ($this->getAttribute('value') === false) { - $this->setAttribute('value', ''); - } - } - - /** - * Tag contains no content. - * @return boolean False. - * @access public - */ - function expectEndTag() { - return false; - } - - /** - * Sets the current form element value. Cannot - * change the value of a hidden field. - * @param string $value New value. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - if ($this->getAttribute('type') == 'hidden') { - return false; - } - return parent::setValue($value); - } -} - -/** - * Submit button as input tag. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleSubmitTag extends SimpleWidget { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('input', $attributes); - if ($this->getAttribute('value') === false) { - $this->setAttribute('value', 'Submit'); - } - } - - /** - * Tag contains no end element. - * @return boolean False. - * @access public - */ - function expectEndTag() { - return false; - } - - /** - * Disables the setting of the button value. - * @param string $value Ignored. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - return false; - } - - /** - * Value of browser visible text. - * @return string Visible label. - * @access public - */ - function getLabel() { - return $this->getValue(); - } - - /** - * Test for a label match when searching. - * @param string $label Label to test. - * @return boolean True on match. - * @access public - */ - function isLabel($label) { - return trim($label) == trim($this->getLabel()); - } -} - -/** - * Image button as input tag. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleImageSubmitTag extends SimpleWidget { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('input', $attributes); - } - - /** - * Tag contains no end element. - * @return boolean False. - * @access public - */ - function expectEndTag() { - return false; - } - - /** - * Disables the setting of the button value. - * @param string $value Ignored. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - return false; - } - - /** - * Value of browser visible text. - * @return string Visible label. - * @access public - */ - function getLabel() { - if ($this->getAttribute('title')) { - return $this->getAttribute('title'); - } - return $this->getAttribute('alt'); - } - - /** - * Test for a label match when searching. - * @param string $label Label to test. - * @return boolean True on match. - * @access public - */ - function isLabel($label) { - return trim($label) == trim($this->getLabel()); - } - - /** - * Dispatches the value into the form encoded packet. - * @param SimpleEncoding $encoding Form packet. - * @param integer $x X coordinate of click. - * @param integer $y Y coordinate of click. - * @access public - */ - function write($encoding, $x = 1, $y = 1) { - if ($this->getName()) { - $encoding->add($this->getName() . '.x', $x); - $encoding->add($this->getName() . '.y', $y); - } else { - $encoding->add('x', $x); - $encoding->add('y', $y); - } - } -} - -/** - * Submit button as button tag. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleButtonTag extends SimpleWidget { - - /** - * Starts with a named tag with attributes only. - * Defaults are very browser dependent. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('button', $attributes); - } - - /** - * Check to see if the tag can have both start and - * end tags with content in between. - * @return boolean True if content allowed. - * @access public - */ - function expectEndTag() { - return true; - } - - /** - * Disables the setting of the button value. - * @param string $value Ignored. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - return false; - } - - /** - * Value of browser visible text. - * @return string Visible label. - * @access public - */ - function getLabel() { - return $this->getContent(); - } - - /** - * Test for a label match when searching. - * @param string $label Label to test. - * @return boolean True on match. - * @access public - */ - function isLabel($label) { - return trim($label) == trim($this->getLabel()); - } -} - -/** - * Content tag for text area. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleTextAreaTag extends SimpleWidget { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('textarea', $attributes); - } - - /** - * Accessor for starting value. - * @return string Parsed value. - * @access public - */ - function getDefault() { - return $this->wrap(html_entity_decode($this->getContent(), ENT_QUOTES)); - } - - /** - * Applies word wrapping if needed. - * @param string $value New value. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - return parent::setValue($this->wrap($value)); - } - - /** - * Test to see if text should be wrapped. - * @return boolean True if wrapping on. - * @access private - */ - function wrapIsEnabled() { - if ($this->getAttribute('cols')) { - $wrap = $this->getAttribute('wrap'); - if (($wrap == 'physical') || ($wrap == 'hard')) { - return true; - } - } - return false; - } - - /** - * Performs the formatting that is peculiar to - * this tag. There is strange behaviour in this - * one, including stripping a leading new line. - * Go figure. I am using Firefox as a guide. - * @param string $text Text to wrap. - * @return string Text wrapped with carriage - * returns and line feeds - * @access private - */ - protected function wrap($text) { - $text = str_replace("\r\r\n", "\r\n", str_replace("\n", "\r\n", $text)); - $text = str_replace("\r\n\n", "\r\n", str_replace("\r", "\r\n", $text)); - if (strncmp($text, "\r\n", strlen("\r\n")) == 0) { - $text = substr($text, strlen("\r\n")); - } - if ($this->wrapIsEnabled()) { - return wordwrap( - $text, - (integer)$this->getAttribute('cols'), - "\r\n"); - } - return $text; - } - - /** - * The content of textarea is not part of the page. - * @return boolean True. - * @access public - */ - function isPrivateContent() { - return true; - } -} - -/** - * File upload widget. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleUploadTag extends SimpleWidget { - - /** - * Starts with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('input', $attributes); - } - - /** - * Tag contains no content. - * @return boolean False. - * @access public - */ - function expectEndTag() { - return false; - } - - /** - * Dispatches the value into the form encoded packet. - * @param SimpleEncoding $encoding Form packet. - * @access public - */ - function write($encoding) { - if (! file_exists($this->getValue())) { - return; - } - $encoding->attach( - $this->getName(), - implode('', file($this->getValue())), - basename($this->getValue())); - } -} - -/** - * Drop down widget. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleSelectionTag extends SimpleWidget { - private $options; - private $choice; - - /** - * Starts with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('select', $attributes); - $this->options = array(); - $this->choice = false; - } - - /** - * Adds an option tag to a selection field. - * @param SimpleOptionTag $tag New option. - * @access public - */ - function addTag($tag) { - if ($tag->getTagName() == 'option') { - $this->options[] = $tag; - } - } - - /** - * Text within the selection element is ignored. - * @param string $content Ignored. - * @access public - */ - function addContent($content) { - return $this; - } - - /** - * Scans options for defaults. If none, then - * the first option is selected. - * @return string Selected field. - * @access public - */ - function getDefault() { - for ($i = 0, $count = count($this->options); $i < $count; $i++) { - if ($this->options[$i]->getAttribute('selected') !== false) { - return $this->options[$i]->getDefault(); - } - } - if ($count > 0) { - return $this->options[0]->getDefault(); - } - return ''; - } - - /** - * Can only set allowed values. - * @param string $value New choice. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - for ($i = 0, $count = count($this->options); $i < $count; $i++) { - if ($this->options[$i]->isValue($value)) { - $this->choice = $i; - return true; - } - } - return false; - } - - /** - * Accessor for current selection value. - * @return string Value attribute or - * content of opton. - * @access public - */ - function getValue() { - if ($this->choice === false) { - return $this->getDefault(); - } - return $this->options[$this->choice]->getValue(); - } -} - -/** - * Drop down widget. - * @package SimpleTest - * @subpackage WebTester - */ -class MultipleSelectionTag extends SimpleWidget { - private $options; - private $values; - - /** - * Starts with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('select', $attributes); - $this->options = array(); - $this->values = false; - } - - /** - * Adds an option tag to a selection field. - * @param SimpleOptionTag $tag New option. - * @access public - */ - function addTag($tag) { - if ($tag->getTagName() == 'option') { - $this->options[] = &$tag; - } - } - - /** - * Text within the selection element is ignored. - * @param string $content Ignored. - * @access public - */ - function addContent($content) { - return $this; - } - - /** - * Scans options for defaults to populate the - * value array(). - * @return array Selected fields. - * @access public - */ - function getDefault() { - $default = array(); - for ($i = 0, $count = count($this->options); $i < $count; $i++) { - if ($this->options[$i]->getAttribute('selected') !== false) { - $default[] = $this->options[$i]->getDefault(); - } - } - return $default; - } - - /** - * Can only set allowed values. Any illegal value - * will result in a failure, but all correct values - * will be set. - * @param array $desired New choices. - * @return boolean True if all allowed. - * @access public - */ - function setValue($desired) { - $achieved = array(); - foreach ($desired as $value) { - $success = false; - for ($i = 0, $count = count($this->options); $i < $count; $i++) { - if ($this->options[$i]->isValue($value)) { - $achieved[] = $this->options[$i]->getValue(); - $success = true; - break; - } - } - if (! $success) { - return false; - } - } - $this->values = $achieved; - return true; - } - - /** - * Accessor for current selection value. - * @return array List of currently set options. - * @access public - */ - function getValue() { - if ($this->values === false) { - return $this->getDefault(); - } - return $this->values; - } -} - -/** - * Option for selection field. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleOptionTag extends SimpleWidget { - - /** - * Stashes the attributes. - */ - function __construct($attributes) { - parent::__construct('option', $attributes); - } - - /** - * Does nothing. - * @param string $value Ignored. - * @return boolean Not allowed. - * @access public - */ - function setValue($value) { - return false; - } - - /** - * Test to see if a value matches the option. - * @param string $compare Value to compare with. - * @return boolean True if possible match. - * @access public - */ - function isValue($compare) { - $compare = trim($compare); - if (trim($this->getValue()) == $compare) { - return true; - } - return trim(strip_tags($this->getContent())) == $compare; - } - - /** - * Accessor for starting value. Will be set to - * the option label if no value exists. - * @return string Parsed value. - * @access public - */ - function getDefault() { - if ($this->getAttribute('value') === false) { - return strip_tags($this->getContent()); - } - return $this->getAttribute('value'); - } - - /** - * The content of options is not part of the page. - * @return boolean True. - * @access public - */ - function isPrivateContent() { - return true; - } -} - -/** - * Radio button. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleRadioButtonTag extends SimpleWidget { - - /** - * Stashes the attributes. - * @param array $attributes Hash of attributes. - */ - function __construct($attributes) { - parent::__construct('input', $attributes); - if ($this->getAttribute('value') === false) { - $this->setAttribute('value', 'on'); - } - } - - /** - * Tag contains no content. - * @return boolean False. - * @access public - */ - function expectEndTag() { - return false; - } - - /** - * The only allowed value sn the one in the - * "value" attribute. - * @param string $value New value. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - if ($value === false) { - return parent::setValue($value); - } - if ($value != $this->getAttribute('value')) { - return false; - } - return parent::setValue($value); - } - - /** - * Accessor for starting value. - * @return string Parsed value. - * @access public - */ - function getDefault() { - if ($this->getAttribute('checked') !== false) { - return $this->getAttribute('value'); - } - return false; - } -} - -/** - * Checkbox widget. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleCheckboxTag extends SimpleWidget { - - /** - * Starts with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('input', $attributes); - if ($this->getAttribute('value') === false) { - $this->setAttribute('value', 'on'); - } - } - - /** - * Tag contains no content. - * @return boolean False. - * @access public - */ - function expectEndTag() { - return false; - } - - /** - * The only allowed value in the one in the - * "value" attribute. The default for this - * attribute is "on". If this widget is set to - * true, then the usual value will be taken. - * @param string $value New value. - * @return boolean True if allowed. - * @access public - */ - function setValue($value) { - if ($value === false) { - return parent::setValue($value); - } - if ($value === true) { - return parent::setValue($this->getAttribute('value')); - } - if ($value != $this->getAttribute('value')) { - return false; - } - return parent::setValue($value); - } - - /** - * Accessor for starting value. The default - * value is "on". - * @return string Parsed value. - * @access public - */ - function getDefault() { - if ($this->getAttribute('checked') !== false) { - return $this->getAttribute('value'); - } - return false; - } -} - -/** - * A group of multiple widgets with some shared behaviour. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleTagGroup { - private $widgets = array(); - - /** - * Adds a tag to the group. - * @param SimpleWidget $widget - * @access public - */ - function addWidget($widget) { - $this->widgets[] = $widget; - } - - /** - * Accessor to widget set. - * @return array All widgets. - * @access protected - */ - protected function &getWidgets() { - return $this->widgets; - } - - /** - * Accessor for an attribute. - * @param string $label Attribute name. - * @return boolean Always false. - * @access public - */ - function getAttribute($label) { - return false; - } - - /** - * Fetches the name for the widget from the first - * member. - * @return string Name of widget. - * @access public - */ - function getName() { - if (count($this->widgets) > 0) { - return $this->widgets[0]->getName(); - } - } - - /** - * Scans the widgets for one with the appropriate - * ID field. - * @param string $id ID value to try. - * @return boolean True if matched. - * @access public - */ - function isId($id) { - for ($i = 0, $count = count($this->widgets); $i < $count; $i++) { - if ($this->widgets[$i]->isId($id)) { - return true; - } - } - return false; - } - - /** - * Scans the widgets for one with the appropriate - * attached label. - * @param string $label Attached label to try. - * @return boolean True if matched. - * @access public - */ - function isLabel($label) { - for ($i = 0, $count = count($this->widgets); $i < $count; $i++) { - if ($this->widgets[$i]->isLabel($label)) { - return true; - } - } - return false; - } - - /** - * Dispatches the value into the form encoded packet. - * @param SimpleEncoding $encoding Form packet. - * @access public - */ - function write($encoding) { - $encoding->add($this->getName(), $this->getValue()); - } -} - -/** - * A group of tags with the same name within a form. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleCheckboxGroup extends SimpleTagGroup { - - /** - * Accessor for current selected widget or false - * if none. - * @return string/array Widget values or false if none. - * @access public - */ - function getValue() { - $values = array(); - $widgets = $this->getWidgets(); - for ($i = 0, $count = count($widgets); $i < $count; $i++) { - if ($widgets[$i]->getValue() !== false) { - $values[] = $widgets[$i]->getValue(); - } - } - return $this->coerceValues($values); - } - - /** - * Accessor for starting value that is active. - * @return string/array Widget values or false if none. - * @access public - */ - function getDefault() { - $values = array(); - $widgets = $this->getWidgets(); - for ($i = 0, $count = count($widgets); $i < $count; $i++) { - if ($widgets[$i]->getDefault() !== false) { - $values[] = $widgets[$i]->getDefault(); - } - } - return $this->coerceValues($values); - } - - /** - * Accessor for current set values. - * @param string/array/boolean $values Either a single string, a - * hash or false for nothing set. - * @return boolean True if all values can be set. - * @access public - */ - function setValue($values) { - $values = $this->makeArray($values); - if (! $this->valuesArePossible($values)) { - return false; - } - $widgets = $this->getWidgets(); - for ($i = 0, $count = count($widgets); $i < $count; $i++) { - $possible = $widgets[$i]->getAttribute('value'); - if (in_array($widgets[$i]->getAttribute('value'), $values)) { - $widgets[$i]->setValue($possible); - } else { - $widgets[$i]->setValue(false); - } - } - return true; - } - - /** - * Tests to see if a possible value set is legal. - * @param string/array/boolean $values Either a single string, a - * hash or false for nothing set. - * @return boolean False if trying to set a - * missing value. - * @access private - */ - protected function valuesArePossible($values) { - $matches = array(); - $widgets = &$this->getWidgets(); - for ($i = 0, $count = count($widgets); $i < $count; $i++) { - $possible = $widgets[$i]->getAttribute('value'); - if (in_array($possible, $values)) { - $matches[] = $possible; - } - } - return ($values == $matches); - } - - /** - * Converts the output to an appropriate format. This means - * that no values is false, a single value is just that - * value and only two or more are contained in an array. - * @param array $values List of values of widgets. - * @return string/array/boolean Expected format for a tag. - * @access private - */ - protected function coerceValues($values) { - if (count($values) == 0) { - return false; - } elseif (count($values) == 1) { - return $values[0]; - } else { - return $values; - } - } - - /** - * Converts false or string into array. The opposite of - * the coercian method. - * @param string/array/boolean $value A single item is converted - * to a one item list. False - * gives an empty list. - * @return array List of values, possibly empty. - * @access private - */ - protected function makeArray($value) { - if ($value === false) { - return array(); - } - if (is_string($value)) { - return array($value); - } - return $value; - } -} - -/** - * A group of tags with the same name within a form. - * Used for radio buttons. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleRadioGroup extends SimpleTagGroup { - - /** - * Each tag is tried in turn until one is - * successfully set. The others will be - * unchecked if successful. - * @param string $value New value. - * @return boolean True if any allowed. - * @access public - */ - function setValue($value) { - if (! $this->valueIsPossible($value)) { - return false; - } - $index = false; - $widgets = $this->getWidgets(); - for ($i = 0, $count = count($widgets); $i < $count; $i++) { - if (! $widgets[$i]->setValue($value)) { - $widgets[$i]->setValue(false); - } - } - return true; - } - - /** - * Tests to see if a value is allowed. - * @param string Attempted value. - * @return boolean True if a valid value. - * @access private - */ - protected function valueIsPossible($value) { - $widgets = $this->getWidgets(); - for ($i = 0, $count = count($widgets); $i < $count; $i++) { - if ($widgets[$i]->getAttribute('value') == $value) { - return true; - } - } - return false; - } - - /** - * Accessor for current selected widget or false - * if none. - * @return string/boolean Value attribute or - * content of opton. - * @access public - */ - function getValue() { - $widgets = $this->getWidgets(); - for ($i = 0, $count = count($widgets); $i < $count; $i++) { - if ($widgets[$i]->getValue() !== false) { - return $widgets[$i]->getValue(); - } - } - return false; - } - - /** - * Accessor for starting value that is active. - * @return string/boolean Value of first checked - * widget or false if none. - * @access public - */ - function getDefault() { - $widgets = $this->getWidgets(); - for ($i = 0, $count = count($widgets); $i < $count; $i++) { - if ($widgets[$i]->getDefault() !== false) { - return $widgets[$i]->getDefault(); - } - } - return false; - } -} - -/** - * Tag to keep track of labels. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleLabelTag extends SimpleTag { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('label', $attributes); - } - - /** - * Access for the ID to attach the label to. - * @return string For attribute. - * @access public - */ - function getFor() { - return $this->getAttribute('for'); - } -} - -/** - * Tag to aid parsing the form. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleFormTag extends SimpleTag { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('form', $attributes); - } -} - -/** - * Tag to aid parsing the frames in a page. - * @package SimpleTest - * @subpackage WebTester - */ -class SimpleFrameTag extends SimpleTag { - - /** - * Starts with a named tag with attributes only. - * @param hash $attributes Attribute names and - * string values. - */ - function __construct($attributes) { - parent::__construct('frame', $attributes); - } - - /** - * Tag contains no content. - * @return boolean False. - * @access public - */ - function expectEndTag() { - return false; - } -} -?> \ No newline at end of file diff --git a/3rdparty/simpletest/test_case.php b/3rdparty/simpletest/test_case.php deleted file mode 100644 index ba023c3b2e..0000000000 --- a/3rdparty/simpletest/test_case.php +++ /dev/null @@ -1,658 +0,0 @@ -label = $label; - } - } - - /** - * Accessor for the test name for subclasses. - * @return string Name of the test. - * @access public - */ - function getLabel() { - return $this->label ? $this->label : get_class($this); - } - - /** - * This is a placeholder for skipping tests. In this - * method you place skipIf() and skipUnless() calls to - * set the skipping state. - * @access public - */ - function skip() { - } - - /** - * Will issue a message to the reporter and tell the test - * case to skip if the incoming flag is true. - * @param string $should_skip Condition causing the tests to be skipped. - * @param string $message Text of skip condition. - * @access public - */ - function skipIf($should_skip, $message = '%s') { - if ($should_skip && ! $this->should_skip) { - $this->should_skip = true; - $message = sprintf($message, 'Skipping [' . get_class($this) . ']'); - $this->reporter->paintSkip($message . $this->getAssertionLine()); - } - } - - /** - * Accessor for the private variable $_shoud_skip - * @access public - */ - function shouldSkip() { - return $this->should_skip; - } - - /** - * Will issue a message to the reporter and tell the test - * case to skip if the incoming flag is false. - * @param string $shouldnt_skip Condition causing the tests to be run. - * @param string $message Text of skip condition. - * @access public - */ - function skipUnless($shouldnt_skip, $message = false) { - $this->skipIf(! $shouldnt_skip, $message); - } - - /** - * Used to invoke the single tests. - * @return SimpleInvoker Individual test runner. - * @access public - */ - function createInvoker() { - return new SimpleErrorTrappingInvoker( - new SimpleExceptionTrappingInvoker(new SimpleInvoker($this))); - } - - /** - * Uses reflection to run every method within itself - * starting with the string "test" unless a method - * is specified. - * @param SimpleReporter $reporter Current test reporter. - * @return boolean True if all tests passed. - * @access public - */ - function run($reporter) { - $context = SimpleTest::getContext(); - $context->setTest($this); - $context->setReporter($reporter); - $this->reporter = $reporter; - $started = false; - foreach ($this->getTests() as $method) { - if ($reporter->shouldInvoke($this->getLabel(), $method)) { - $this->skip(); - if ($this->should_skip) { - break; - } - if (! $started) { - $reporter->paintCaseStart($this->getLabel()); - $started = true; - } - $invoker = $this->reporter->createInvoker($this->createInvoker()); - $invoker->before($method); - $invoker->invoke($method); - $invoker->after($method); - } - } - if ($started) { - $reporter->paintCaseEnd($this->getLabel()); - } - unset($this->reporter); - $context->setTest(null); - return $reporter->getStatus(); - } - - /** - * Gets a list of test names. Normally that will - * be all internal methods that start with the - * name "test". This method should be overridden - * if you want a different rule. - * @return array List of test names. - * @access public - */ - function getTests() { - $methods = array(); - foreach (get_class_methods(get_class($this)) as $method) { - if ($this->isTest($method)) { - $methods[] = $method; - } - } - return $methods; - } - - /** - * Tests to see if the method is a test that should - * be run. Currently any method that starts with 'test' - * is a candidate unless it is the constructor. - * @param string $method Method name to try. - * @return boolean True if test method. - * @access protected - */ - protected function isTest($method) { - if (strtolower(substr($method, 0, 4)) == 'test') { - return ! SimpleTestCompatibility::isA($this, strtolower($method)); - } - return false; - } - - /** - * Announces the start of the test. - * @param string $method Test method just started. - * @access public - */ - function before($method) { - $this->reporter->paintMethodStart($method); - $this->observers = array(); - } - - /** - * Sets up unit test wide variables at the start - * of each test method. To be overridden in - * actual user test cases. - * @access public - */ - function setUp() { - } - - /** - * Clears the data set in the setUp() method call. - * To be overridden by the user in actual user test cases. - * @access public - */ - function tearDown() { - } - - /** - * Announces the end of the test. Includes private clean up. - * @param string $method Test method just finished. - * @access public - */ - function after($method) { - for ($i = 0; $i < count($this->observers); $i++) { - $this->observers[$i]->atTestEnd($method, $this); - } - $this->reporter->paintMethodEnd($method); - } - - /** - * Sets up an observer for the test end. - * @param object $observer Must have atTestEnd() - * method. - * @access public - */ - function tell($observer) { - $this->observers[] = &$observer; - } - - /** - * @deprecated - */ - function pass($message = "Pass") { - if (! isset($this->reporter)) { - trigger_error('Can only make assertions within test methods'); - } - $this->reporter->paintPass( - $message . $this->getAssertionLine()); - return true; - } - - /** - * Sends a fail event with a message. - * @param string $message Message to send. - * @access public - */ - function fail($message = "Fail") { - if (! isset($this->reporter)) { - trigger_error('Can only make assertions within test methods'); - } - $this->reporter->paintFail( - $message . $this->getAssertionLine()); - return false; - } - - /** - * Formats a PHP error and dispatches it to the - * reporter. - * @param integer $severity PHP error code. - * @param string $message Text of error. - * @param string $file File error occoured in. - * @param integer $line Line number of error. - * @access public - */ - function error($severity, $message, $file, $line) { - if (! isset($this->reporter)) { - trigger_error('Can only make assertions within test methods'); - } - $this->reporter->paintError( - "Unexpected PHP error [$message] severity [$severity] in [$file line $line]"); - } - - /** - * Formats an exception and dispatches it to the - * reporter. - * @param Exception $exception Object thrown. - * @access public - */ - function exception($exception) { - $this->reporter->paintException($exception); - } - - /** - * For user defined expansion of the available messages. - * @param string $type Tag for sorting the signals. - * @param mixed $payload Extra user specific information. - */ - function signal($type, $payload) { - if (! isset($this->reporter)) { - trigger_error('Can only make assertions within test methods'); - } - $this->reporter->paintSignal($type, $payload); - } - - /** - * Runs an expectation directly, for extending the - * tests with new expectation classes. - * @param SimpleExpectation $expectation Expectation subclass. - * @param mixed $compare Value to compare. - * @param string $message Message to display. - * @return boolean True on pass - * @access public - */ - function assert($expectation, $compare, $message = '%s') { - if ($expectation->test($compare)) { - return $this->pass(sprintf( - $message, - $expectation->overlayMessage($compare, $this->reporter->getDumper()))); - } else { - return $this->fail(sprintf( - $message, - $expectation->overlayMessage($compare, $this->reporter->getDumper()))); - } - } - - /** - * Uses a stack trace to find the line of an assertion. - * @return string Line number of first assert* - * method embedded in format string. - * @access public - */ - function getAssertionLine() { - $trace = new SimpleStackTrace(array('assert', 'expect', 'pass', 'fail', 'skip')); - return $trace->traceMethod(); - } - - /** - * Sends a formatted dump of a variable to the - * test suite for those emergency debugging - * situations. - * @param mixed $variable Variable to display. - * @param string $message Message to display. - * @return mixed The original variable. - * @access public - */ - function dump($variable, $message = false) { - $dumper = $this->reporter->getDumper(); - $formatted = $dumper->dump($variable); - if ($message) { - $formatted = $message . "\n" . $formatted; - } - $this->reporter->paintFormattedMessage($formatted); - return $variable; - } - - /** - * Accessor for the number of subtests including myelf. - * @return integer Number of test cases. - * @access public - */ - function getSize() { - return 1; - } -} - -/** - * Helps to extract test cases automatically from a file. - * @package SimpleTest - * @subpackage UnitTester - */ -class SimpleFileLoader { - - /** - * Builds a test suite from a library of test cases. - * The new suite is composed into this one. - * @param string $test_file File name of library with - * test case classes. - * @return TestSuite The new test suite. - * @access public - */ - function load($test_file) { - $existing_classes = get_declared_classes(); - $existing_globals = get_defined_vars(); - include_once($test_file); - $new_globals = get_defined_vars(); - $this->makeFileVariablesGlobal($existing_globals, $new_globals); - $new_classes = array_diff(get_declared_classes(), $existing_classes); - if (empty($new_classes)) { - $new_classes = $this->scrapeClassesFromFile($test_file); - } - $classes = $this->selectRunnableTests($new_classes); - return $this->createSuiteFromClasses($test_file, $classes); - } - - /** - * Imports new variables into the global namespace. - * @param hash $existing Variables before the file was loaded. - * @param hash $new Variables after the file was loaded. - * @access private - */ - protected function makeFileVariablesGlobal($existing, $new) { - $globals = array_diff(array_keys($new), array_keys($existing)); - foreach ($globals as $global) { - $GLOBALS[$global] = $new[$global]; - } - } - - /** - * Lookup classnames from file contents, in case the - * file may have been included before. - * Note: This is probably too clever by half. Figuring this - * out after a failed test case is going to be tricky for us, - * never mind the user. A test case should not be included - * twice anyway. - * @param string $test_file File name with classes. - * @access private - */ - protected function scrapeClassesFromFile($test_file) { - preg_match_all('~^\s*class\s+(\w+)(\s+(extends|implements)\s+\w+)*\s*\{~mi', - file_get_contents($test_file), - $matches ); - return $matches[1]; - } - - /** - * Calculates the incoming test cases. Skips abstract - * and ignored classes. - * @param array $candidates Candidate classes. - * @return array New classes which are test - * cases that shouldn't be ignored. - * @access public - */ - function selectRunnableTests($candidates) { - $classes = array(); - foreach ($candidates as $class) { - if (TestSuite::getBaseTestCase($class)) { - $reflection = new SimpleReflection($class); - if ($reflection->isAbstract()) { - SimpleTest::ignore($class); - } else { - $classes[] = $class; - } - } - } - return $classes; - } - - /** - * Builds a test suite from a class list. - * @param string $title Title of new group. - * @param array $classes Test classes. - * @return TestSuite Group loaded with the new - * test cases. - * @access public - */ - function createSuiteFromClasses($title, $classes) { - if (count($classes) == 0) { - $suite = new BadTestSuite($title, "No runnable test cases in [$title]"); - return $suite; - } - SimpleTest::ignoreParentsIfIgnored($classes); - $suite = new TestSuite($title); - foreach ($classes as $class) { - if (! SimpleTest::isIgnored($class)) { - $suite->add($class); - } - } - return $suite; - } -} - -/** - * This is a composite test class for combining - * test cases and other RunnableTest classes into - * a group test. - * @package SimpleTest - * @subpackage UnitTester - */ -class TestSuite { - private $label; - private $test_cases; - - /** - * Sets the name of the test suite. - * @param string $label Name sent at the start and end - * of the test. - * @access public - */ - function TestSuite($label = false) { - $this->label = $label; - $this->test_cases = array(); - } - - /** - * Accessor for the test name for subclasses. If the suite - * wraps a single test case the label defaults to the name of that test. - * @return string Name of the test. - * @access public - */ - function getLabel() { - if (! $this->label) { - return ($this->getSize() == 1) ? - get_class($this->test_cases[0]) : get_class($this); - } else { - return $this->label; - } - } - - /** - * Adds a test into the suite by instance or class. The class will - * be instantiated if it's a test suite. - * @param SimpleTestCase $test_case Suite or individual test - * case implementing the - * runnable test interface. - * @access public - */ - function add($test_case) { - if (! is_string($test_case)) { - $this->test_cases[] = $test_case; - } elseif (TestSuite::getBaseTestCase($test_case) == 'testsuite') { - $this->test_cases[] = new $test_case(); - } else { - $this->test_cases[] = $test_case; - } - } - - /** - * Builds a test suite from a library of test cases. - * The new suite is composed into this one. - * @param string $test_file File name of library with - * test case classes. - * @access public - */ - function addFile($test_file) { - $extractor = new SimpleFileLoader(); - $this->add($extractor->load($test_file)); - } - - /** - * Delegates to a visiting collector to add test - * files. - * @param string $path Path to scan from. - * @param SimpleCollector $collector Directory scanner. - * @access public - */ - function collect($path, $collector) { - $collector->collect($this, $path); - } - - /** - * Invokes run() on all of the held test cases, instantiating - * them if necessary. - * @param SimpleReporter $reporter Current test reporter. - * @access public - */ - function run($reporter) { - $reporter->paintGroupStart($this->getLabel(), $this->getSize()); - for ($i = 0, $count = count($this->test_cases); $i < $count; $i++) { - if (is_string($this->test_cases[$i])) { - $class = $this->test_cases[$i]; - $test = new $class(); - $test->run($reporter); - unset($test); - } else { - $this->test_cases[$i]->run($reporter); - } - } - $reporter->paintGroupEnd($this->getLabel()); - return $reporter->getStatus(); - } - - /** - * Number of contained test cases. - * @return integer Total count of cases in the group. - * @access public - */ - function getSize() { - $count = 0; - foreach ($this->test_cases as $case) { - if (is_string($case)) { - if (! SimpleTest::isIgnored($case)) { - $count++; - } - } else { - $count += $case->getSize(); - } - } - return $count; - } - - /** - * Test to see if a class is derived from the - * SimpleTestCase class. - * @param string $class Class name. - * @access public - */ - static function getBaseTestCase($class) { - while ($class = get_parent_class($class)) { - $class = strtolower($class); - if ($class == 'simpletestcase' || $class == 'testsuite') { - return $class; - } - } - return false; - } -} - -/** - * This is a failing group test for when a test suite hasn't - * loaded properly. - * @package SimpleTest - * @subpackage UnitTester - */ -class BadTestSuite { - private $label; - private $error; - - /** - * Sets the name of the test suite and error message. - * @param string $label Name sent at the start and end - * of the test. - * @access public - */ - function BadTestSuite($label, $error) { - $this->label = $label; - $this->error = $error; - } - - /** - * Accessor for the test name for subclasses. - * @return string Name of the test. - * @access public - */ - function getLabel() { - return $this->label; - } - - /** - * Sends a single error to the reporter. - * @param SimpleReporter $reporter Current test reporter. - * @access public - */ - function run($reporter) { - $reporter->paintGroupStart($this->getLabel(), $this->getSize()); - $reporter->paintFail('Bad TestSuite [' . $this->getLabel() . - '] with error [' . $this->error . ']'); - $reporter->paintGroupEnd($this->getLabel()); - return $reporter->getStatus(); - } - - /** - * Number of contained test cases. Always zero. - * @return integer Total count of cases in the group. - * @access public - */ - function getSize() { - return 0; - } -} -?> diff --git a/3rdparty/simpletest/tidy_parser.php b/3rdparty/simpletest/tidy_parser.php deleted file mode 100644 index 3d8b4b2ac7..0000000000 --- a/3rdparty/simpletest/tidy_parser.php +++ /dev/null @@ -1,382 +0,0 @@ -free(); - } - - /** - * Frees up any references so as to allow the PHP garbage - * collection from unset() to work. - */ - private function free() { - unset($this->page); - $this->forms = array(); - $this->labels = array(); - } - - /** - * This builder is only available if the 'tidy' extension is loaded. - * @return boolean True if available. - */ - function can() { - return extension_loaded('tidy'); - } - - /** - * Reads the raw content the page using HTML Tidy. - * @param $response SimpleHttpResponse Fetched response. - * @return SimplePage Newly parsed page. - */ - function parse($response) { - $this->page = new SimplePage($response); - $tidied = tidy_parse_string($input = $this->insertGuards($response->getContent()), - array('output-xml' => false, 'wrap' => '0', 'indent' => 'no'), - 'latin1'); - $this->walkTree($tidied->html()); - $this->attachLabels($this->widgets_by_id, $this->labels); - $this->page->setForms($this->forms); - $page = $this->page; - $this->free(); - return $page; - } - - /** - * Stops HTMLTidy stripping content that we wish to preserve. - * @param string The raw html. - * @return string The html with guard tags inserted. - */ - private function insertGuards($html) { - return $this->insertEmptyTagGuards($this->insertTextareaSimpleWhitespaceGuards($html)); - } - - /** - * Removes the extra content added during the parse stage - * in order to preserve content we don't want stripped - * out by HTMLTidy. - * @param string The raw html. - * @return string The html with guard tags removed. - */ - private function stripGuards($html) { - return $this->stripTextareaWhitespaceGuards($this->stripEmptyTagGuards($html)); - } - - /** - * HTML tidy strips out empty tags such as
                - - - diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 44000171a1..d49f2f4d5d 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -1,8 +1,8 @@
                - -
                + +
                t('New');?>
                -
                + - - + +
                @@ -32,10 +32,11 @@ +
                - +
                t('Nothing in here. Upload something!')?>
                @@ -43,7 +44,7 @@ - + t( 'Name' ); ?> @@ -53,10 +54,20 @@ t( 'Size' ); ?> - t( 'Modified' ); ?>t('Delete')?> <?php echo $l->t('Delete')?>" /> + + t( 'Modified' ); ?> + + + + t('Unshare')?> <?php echo $l->t('Unshare')?>" /> + + t('Delete')?> <?php echo $l->t('Delete')?>" /> + + + - + diff --git a/apps/files/templates/part.breadcrumb.php b/apps/files/templates/part.breadcrumb.php index 22d9bb4490..71b695f65f 100644 --- a/apps/files/templates/part.breadcrumb.php +++ b/apps/files/templates/part.breadcrumb.php @@ -1,6 +1,6 @@ -
                svg" data-dir='' style='background-image:url("")'> - "> +
                svg" data-dir='' style='background-image:url("")'> + ">
                diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php index 4506630c16..0f5b839b18 100644 --- a/apps/files/templates/part.list.php +++ b/apps/files/templates/part.list.php @@ -1,5 +1,13 @@ + + - ' data-write=''> + ' data-permissions=''> diff --git a/apps/files_archive/appinfo/app.php b/apps/files_archive/appinfo/app.php deleted file mode 100644 index 67376c4a03..0000000000 --- a/apps/files_archive/appinfo/app.php +++ /dev/null @@ -1,13 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -OC::$CLASSPATH['OC_Filestorage_Archive']='apps/files_archive/lib/storage.php'; - -OCP\Util::connectHook('OC_Filesystem','get_mountpoint','OC_Filestorage_Archive','autoMount'); - -OCP\Util::addscript( 'files_archive', 'archive' ); diff --git a/apps/files_archive/appinfo/info.xml b/apps/files_archive/appinfo/info.xml deleted file mode 100644 index 93ec68ee10..0000000000 --- a/apps/files_archive/appinfo/info.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - files_archive - Archive support - Transparent opening of archives - AGPL - Robin Appelman - 4 - true - - - - - diff --git a/apps/files_archive/appinfo/version b/apps/files_archive/appinfo/version deleted file mode 100644 index 2f4536184b..0000000000 --- a/apps/files_archive/appinfo/version +++ /dev/null @@ -1 +0,0 @@ -0.2 \ No newline at end of file diff --git a/apps/files_archive/js/archive.js b/apps/files_archive/js/archive.js deleted file mode 100644 index 9fb9853e29..0000000000 --- a/apps/files_archive/js/archive.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2012 Robin Appelman - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -$(document).ready(function() { - if(typeof FileActions!=='undefined'){ - FileActions.register('application/zip','Open','',function(filename){ - window.location=OC.linkTo('files', 'index.php')+'&dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename); - }); - FileActions.setDefault('application/zip','Open'); - FileActions.register('application/x-gzip','Open','',function(filename){ - window.location=OC.linkTo('files', 'index.php')+'&dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename); - }); - FileActions.setDefault('application/x-gzip','Open'); - } -}); diff --git a/apps/files_archive/lib/storage.php b/apps/files_archive/lib/storage.php deleted file mode 100644 index 8676166361..0000000000 --- a/apps/files_archive/lib/storage.php +++ /dev/null @@ -1,146 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -class OC_Filestorage_Archive extends OC_Filestorage_Common{ - /** - * underlying local storage used for missing functions - * @var OC_Archive - */ - private $archive; - private $path; - private static $mounted=array(); - private static $enableAutomount=true; - private static $rootView; - - private function stripPath($path){//files should never start with / - if(!$path || $path[0]=='/'){ - $path=substr($path,1); - } - return $path; - } - - public function __construct($params){ - $this->archive=OC_Archive::open($params['archive']); - $this->path=$params['archive']; - } - - public function mkdir($path){ - $path=$this->stripPath($path); - return $this->archive->addFolder($path); - } - public function rmdir($path){ - $path=$this->stripPath($path); - return $this->archive->remove($path.'/'); - } - public function opendir($path){ - $path=$this->stripPath($path); - $content=$this->archive->getFolder($path); - foreach($content as &$file){ - if(substr($file,-1)=='/'){ - $file=substr($file,0,-1); - } - } - $id=md5($this->path.$path); - OC_FakeDirStream::$dirs[$id]=$content; - return opendir('fakedir://'.$id); - } - public function stat($path){ - $ctime=filectime($this->path); - $path=$this->stripPath($path); - if($path==''){ - $stat=stat($this->path); - }else{ - if($this->is_dir($path)){ - $stat=array('size'=>0); - $stat['mtime']=filemtime($this->path); - }else{ - $stat=array(); - $stat['mtime']=$this->archive->mtime($path); - $stat['size']=$this->archive->filesize($path); - } - } - $stat['ctime']=$ctime; - return $stat; - } - public function filetype($path){ - $path=$this->stripPath($path); - if($path==''){ - return 'dir'; - } - if(substr($path,-1)=='/'){ - return $this->archive->fileExists($path)?'dir':'file'; - }else{ - return $this->archive->fileExists($path.'/')?'dir':'file'; - } - } - public function is_readable($path){ - return is_readable($this->path); - } - public function is_writable($path){ - return is_writable($this->path); - } - public function file_exists($path){ - $path=$this->stripPath($path); - if($path==''){ - return file_exists($this->path); - } - return $this->archive->fileExists($path); - } - public function unlink($path){ - $path=$this->stripPath($path); - return $this->archive->remove($path); - } - public function fopen($path,$mode){ - $path=$this->stripPath($path); - return $this->archive->getStream($path,$mode); - } - public function free_space($path){ - return 0; - } - public function touch($path, $mtime=null){ - if(is_null($mtime)){ - $tmpFile=OCP\Files::tmpFile(); - $this->archive->extractFile($path,$tmpFile); - $this->archive->addfile($path,$tmpFile); - }else{ - return false;//not supported - } - } - - /** - * automount paths from file hooks - * @param aray params - */ - public static function autoMount($params){ - if(!self::$enableAutomount){ - return; - } - $path=$params['path']; - if(!self::$rootView){ - self::$rootView=new OC_FilesystemView(''); - } - self::$enableAutomount=false;//prevent recursion - $supported=array('zip','tar.gz','tar.bz2','tgz'); - foreach($supported as $type){ - $ext='.'.$type.'/'; - if(($pos=strpos(strtolower($path),$ext))!==false){ - $archive=substr($path,0,$pos+strlen($ext)-1); - if(self::$rootView->file_exists($archive) and array_search($archive,self::$mounted)===false){ - $localArchive=self::$rootView->getLocalFile($archive); - OC_Filesystem::mount('OC_Filestorage_Archive',array('archive'=>$localArchive),$archive.'/'); - self::$mounted[]=$archive; - } - } - } - self::$enableAutomount=true; - } - - public function rename($path1,$path2){ - return $this->archive->rename($path1,$path2); - } -} diff --git a/apps/files_archive/tests/data/lorem.txt b/apps/files_archive/tests/data/lorem.txt deleted file mode 100644 index b62c3fb2ff..0000000000 --- a/apps/files_archive/tests/data/lorem.txt +++ /dev/null @@ -1,4 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. -Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. -Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file diff --git a/apps/files_archive/tests/storage.php b/apps/files_archive/tests/storage.php deleted file mode 100644 index 74ddf22870..0000000000 --- a/apps/files_archive/tests/storage.php +++ /dev/null @@ -1,39 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -class Test_Filestorage_Archive_Zip extends Test_FileStorage { - /** - * @var string tmpDir - */ - private $tmpFile; - - public function setUp(){ - $this->tmpFile=OCP\Files::tmpFile('.zip'); - $this->instance=new OC_Filestorage_Archive(array('archive'=>$this->tmpFile)); - } - - public function tearDown(){ - unlink($this->tmpFile); - } -} - -class Test_Filestorage_Archive_Tar extends Test_FileStorage { - /** - * @var string tmpDir - */ - private $tmpFile; - - public function setUp(){ - $this->tmpFile=OCP\Files::tmpFile('.tar.gz'); - $this->instance=new OC_Filestorage_Archive(array('archive'=>$this->tmpFile)); - } - - public function tearDown(){ - unlink($this->tmpFile); - } -} diff --git a/apps/files_encryption/appinfo/info.xml b/apps/files_encryption/appinfo/info.xml index 8e64b0cafd..48a28fde78 100644 --- a/apps/files_encryption/appinfo/info.xml +++ b/apps/files_encryption/appinfo/info.xml @@ -2,10 +2,10 @@ files_encryption Encryption - Server side encryption of files. Warning: You will lose your data if you enable this App and forget your password. Encryption is not yet compatible with LDAP. + Server side encryption of files. DEPRECATED. This app is no longer supported and will be replaced with an improved version in ownCloud 5. Only enable this features if you want to read old encrypted data. Warning: You will lose your data if you enable this App and forget your password. Encryption is not yet compatible with LDAP. AGPL Robin Appelman - 4 + 4.9 true diff --git a/apps/contacts/l10n/.gitkeep b/apps/files_encryption/l10n/.gitkeep similarity index 100% rename from apps/contacts/l10n/.gitkeep rename to apps/files_encryption/l10n/.gitkeep diff --git a/apps/files_encryption/l10n/ca.php b/apps/files_encryption/l10n/ca.php new file mode 100644 index 0000000000..8e087b3462 --- /dev/null +++ b/apps/files_encryption/l10n/ca.php @@ -0,0 +1,6 @@ + "Encriptatge", +"Exclude the following file types from encryption" => "Exclou els tipus de fitxers següents de l'encriptatge", +"None" => "Cap", +"Enable Encryption" => "Activa l'encriptatge" +); diff --git a/apps/files_encryption/l10n/cs_CZ.php b/apps/files_encryption/l10n/cs_CZ.php new file mode 100644 index 0000000000..9be2be9809 --- /dev/null +++ b/apps/files_encryption/l10n/cs_CZ.php @@ -0,0 +1,6 @@ + "Šifrování", +"Exclude the following file types from encryption" => "Při šifrování vynechat následující typy souborů", +"None" => "Žádné", +"Enable Encryption" => "Povolit šifrování" +); diff --git a/apps/files_encryption/l10n/da.php b/apps/files_encryption/l10n/da.php new file mode 100644 index 0000000000..144c9f9708 --- /dev/null +++ b/apps/files_encryption/l10n/da.php @@ -0,0 +1,6 @@ + "Kryptering", +"Exclude the following file types from encryption" => "Ekskluder følgende filtyper fra kryptering", +"None" => "Ingen", +"Enable Encryption" => "Aktivér kryptering" +); diff --git a/apps/files_encryption/l10n/de.php b/apps/files_encryption/l10n/de.php new file mode 100644 index 0000000000..d486a82322 --- /dev/null +++ b/apps/files_encryption/l10n/de.php @@ -0,0 +1,6 @@ + "Verschlüsselung", +"Exclude the following file types from encryption" => "Die folgenden Dateitypen von der Verschlüsselung ausnehmen", +"None" => "Keine", +"Enable Encryption" => "Verschlüsselung aktivieren" +); diff --git a/apps/files_encryption/l10n/el.php b/apps/files_encryption/l10n/el.php new file mode 100644 index 0000000000..40a7c6a367 --- /dev/null +++ b/apps/files_encryption/l10n/el.php @@ -0,0 +1,6 @@ + "Κρυπτογράφηση", +"Exclude the following file types from encryption" => "Εξαίρεση των παρακάτω τύπων αρχείων από την κρυπτογράφηση", +"None" => "Καμία", +"Enable Encryption" => "Ενεργοποίηση Κρυπτογράφησης" +); diff --git a/apps/files_encryption/l10n/eo.php b/apps/files_encryption/l10n/eo.php new file mode 100644 index 0000000000..af3c9ae98e --- /dev/null +++ b/apps/files_encryption/l10n/eo.php @@ -0,0 +1,6 @@ + "Ĉifrado", +"Exclude the following file types from encryption" => "Malinkluzivigi la jenajn dosiertipojn el ĉifrado", +"None" => "Nenio", +"Enable Encryption" => "Kapabligi ĉifradon" +); diff --git a/apps/files_encryption/l10n/es.php b/apps/files_encryption/l10n/es.php new file mode 100644 index 0000000000..b7e7601b35 --- /dev/null +++ b/apps/files_encryption/l10n/es.php @@ -0,0 +1,6 @@ + "Cifrado", +"Exclude the following file types from encryption" => "Excluir del cifrado los siguientes tipos de archivo", +"None" => "Ninguno", +"Enable Encryption" => "Habilitar cifrado" +); diff --git a/apps/files_encryption/l10n/es_AR.php b/apps/files_encryption/l10n/es_AR.php new file mode 100644 index 0000000000..a15c37e730 --- /dev/null +++ b/apps/files_encryption/l10n/es_AR.php @@ -0,0 +1,6 @@ + "Encriptación", +"Exclude the following file types from encryption" => "Exceptuar de la encriptación los siguientes tipos de archivo", +"None" => "Ninguno", +"Enable Encryption" => "Habilitar encriptación" +); diff --git a/apps/files_encryption/l10n/et_EE.php b/apps/files_encryption/l10n/et_EE.php new file mode 100644 index 0000000000..a7cd9395bf --- /dev/null +++ b/apps/files_encryption/l10n/et_EE.php @@ -0,0 +1,6 @@ + "Krüpteerimine", +"Exclude the following file types from encryption" => "Järgnevaid failitüüpe ära krüpteeri", +"None" => "Pole", +"Enable Encryption" => "Luba krüpteerimine" +); diff --git a/apps/files_encryption/l10n/eu.php b/apps/files_encryption/l10n/eu.php new file mode 100644 index 0000000000..57b6a4927b --- /dev/null +++ b/apps/files_encryption/l10n/eu.php @@ -0,0 +1,6 @@ + "Enkriptazioa", +"Exclude the following file types from encryption" => "Ez enkriptatu hurrengo fitxategi motak", +"None" => "Bat ere ez", +"Enable Encryption" => "Gaitu enkriptazioa" +); diff --git a/apps/files_encryption/l10n/fa.php b/apps/files_encryption/l10n/fa.php new file mode 100644 index 0000000000..0faa3f3aae --- /dev/null +++ b/apps/files_encryption/l10n/fa.php @@ -0,0 +1,5 @@ + "رمزگذاری", +"None" => "هیچ‌کدام", +"Enable Encryption" => "فعال کردن رمزگذاری" +); diff --git a/apps/files_encryption/l10n/fi_FI.php b/apps/files_encryption/l10n/fi_FI.php new file mode 100644 index 0000000000..5796499a26 --- /dev/null +++ b/apps/files_encryption/l10n/fi_FI.php @@ -0,0 +1,6 @@ + "Salaus", +"Exclude the following file types from encryption" => "Jätä seuraavat tiedostotyypit salaamatta", +"None" => "Ei mitään", +"Enable Encryption" => "Käytä salausta" +); diff --git a/apps/files_encryption/l10n/fr.php b/apps/files_encryption/l10n/fr.php new file mode 100644 index 0000000000..c9367d1a31 --- /dev/null +++ b/apps/files_encryption/l10n/fr.php @@ -0,0 +1,6 @@ + "Chiffrement", +"Exclude the following file types from encryption" => "Ne pas chiffrer les fichiers dont les types sont les suivants", +"None" => "Aucun", +"Enable Encryption" => "Activer le chiffrement" +); diff --git a/apps/files_encryption/l10n/gl.php b/apps/files_encryption/l10n/gl.php new file mode 100644 index 0000000000..1434ff48aa --- /dev/null +++ b/apps/files_encryption/l10n/gl.php @@ -0,0 +1,6 @@ + "Encriptado", +"Exclude the following file types from encryption" => "Excluír os seguintes tipos de ficheiro da encriptación", +"None" => "Nada", +"Enable Encryption" => "Habilitar encriptación" +); diff --git a/apps/files_encryption/l10n/hu_HU.php b/apps/files_encryption/l10n/hu_HU.php new file mode 100644 index 0000000000..4352d8b771 --- /dev/null +++ b/apps/files_encryption/l10n/hu_HU.php @@ -0,0 +1,6 @@ + "Titkosítás", +"Exclude the following file types from encryption" => "A következő fájl típusok kizárása a titkosításból", +"None" => "Egyik sem", +"Enable Encryption" => "Titkosítás engedélyezése" +); diff --git a/apps/files_encryption/l10n/it.php b/apps/files_encryption/l10n/it.php new file mode 100644 index 0000000000..5136b06179 --- /dev/null +++ b/apps/files_encryption/l10n/it.php @@ -0,0 +1,6 @@ + "Cifratura", +"Exclude the following file types from encryption" => "Escludi i seguenti tipi di file dalla cifratura", +"None" => "Nessuna", +"Enable Encryption" => "Abilita cifratura" +); diff --git a/apps/files_encryption/l10n/ja_JP.php b/apps/files_encryption/l10n/ja_JP.php new file mode 100644 index 0000000000..2c3e5410de --- /dev/null +++ b/apps/files_encryption/l10n/ja_JP.php @@ -0,0 +1,6 @@ + "暗号化", +"Exclude the following file types from encryption" => "暗号化から除外するファイルタイプ", +"None" => "なし", +"Enable Encryption" => "暗号化を有効にする" +); diff --git a/apps/files_encryption/l10n/ku_IQ.php b/apps/files_encryption/l10n/ku_IQ.php new file mode 100644 index 0000000000..bd8977ac51 --- /dev/null +++ b/apps/files_encryption/l10n/ku_IQ.php @@ -0,0 +1,6 @@ + "نهێنیکردن", +"Exclude the following file types from encryption" => "به‌ربه‌ست کردنی ئه‌م جۆره‌ په‌ڕگانه له‌ نهێنیکردن", +"None" => "هیچ", +"Enable Encryption" => "چالاکردنی نهێنیکردن" +); diff --git a/apps/files_encryption/l10n/lt_LT.php b/apps/files_encryption/l10n/lt_LT.php new file mode 100644 index 0000000000..b939df164c --- /dev/null +++ b/apps/files_encryption/l10n/lt_LT.php @@ -0,0 +1,6 @@ + "Šifravimas", +"Exclude the following file types from encryption" => "Nešifruoti pasirinkto tipo failų", +"None" => "Nieko", +"Enable Encryption" => "Įjungti šifravimą" +); diff --git a/apps/files_encryption/l10n/nb_NO.php b/apps/files_encryption/l10n/nb_NO.php new file mode 100644 index 0000000000..e65df7b6ce --- /dev/null +++ b/apps/files_encryption/l10n/nb_NO.php @@ -0,0 +1,6 @@ + "Kryptering", +"Exclude the following file types from encryption" => "Ekskluder følgende filer fra kryptering", +"None" => "Ingen", +"Enable Encryption" => "Slå på kryptering" +); diff --git a/apps/files_encryption/l10n/nl.php b/apps/files_encryption/l10n/nl.php new file mode 100644 index 0000000000..1ea56006fc --- /dev/null +++ b/apps/files_encryption/l10n/nl.php @@ -0,0 +1,6 @@ + "Versleuteling", +"Exclude the following file types from encryption" => "Versleutel de volgende bestand types niet", +"None" => "Geen", +"Enable Encryption" => "Zet versleuteling aan" +); diff --git a/apps/files_encryption/l10n/pl.php b/apps/files_encryption/l10n/pl.php new file mode 100644 index 0000000000..5cfc707450 --- /dev/null +++ b/apps/files_encryption/l10n/pl.php @@ -0,0 +1,6 @@ + "Szyfrowanie", +"Exclude the following file types from encryption" => "Wyłącz następujące typy plików z szyfrowania", +"None" => "Brak", +"Enable Encryption" => "Włącz szyfrowanie" +); diff --git a/apps/files_encryption/l10n/pt_BR.php b/apps/files_encryption/l10n/pt_BR.php new file mode 100644 index 0000000000..5c02f52217 --- /dev/null +++ b/apps/files_encryption/l10n/pt_BR.php @@ -0,0 +1,6 @@ + "Criptografia", +"Exclude the following file types from encryption" => "Excluir os seguintes tipos de arquivo da criptografia", +"None" => "Nenhuma", +"Enable Encryption" => "Habilitar Criptografia" +); diff --git a/apps/files_encryption/l10n/pt_PT.php b/apps/files_encryption/l10n/pt_PT.php new file mode 100644 index 0000000000..570462b414 --- /dev/null +++ b/apps/files_encryption/l10n/pt_PT.php @@ -0,0 +1,6 @@ + "Encriptação", +"Exclude the following file types from encryption" => "Excluir da encriptação os seguintes tipo de ficheiros", +"None" => "Nenhum", +"Enable Encryption" => "Activar Encriptação" +); diff --git a/apps/files_encryption/l10n/ro.php b/apps/files_encryption/l10n/ro.php new file mode 100644 index 0000000000..97f3f262d7 --- /dev/null +++ b/apps/files_encryption/l10n/ro.php @@ -0,0 +1,6 @@ + "Încriptare", +"Exclude the following file types from encryption" => "Exclude următoarele tipuri de fișiere de la încriptare", +"None" => "Niciuna", +"Enable Encryption" => "Activare încriptare" +); diff --git a/apps/files_encryption/l10n/ru.php b/apps/files_encryption/l10n/ru.php new file mode 100644 index 0000000000..3a7e84b6d0 --- /dev/null +++ b/apps/files_encryption/l10n/ru.php @@ -0,0 +1,6 @@ + "Шифрование", +"Exclude the following file types from encryption" => "Исключить шифрование следующих типов файлов", +"None" => "Ничего", +"Enable Encryption" => "Включить шифрование" +); diff --git a/apps/files_encryption/l10n/ru_RU.php b/apps/files_encryption/l10n/ru_RU.php new file mode 100644 index 0000000000..1328b0d035 --- /dev/null +++ b/apps/files_encryption/l10n/ru_RU.php @@ -0,0 +1,6 @@ + "Шифрование", +"Exclude the following file types from encryption" => "Исключите следующие типы файлов из шифрования", +"None" => "Ни один", +"Enable Encryption" => "Включить шифрование" +); diff --git a/apps/files_encryption/l10n/sk_SK.php b/apps/files_encryption/l10n/sk_SK.php new file mode 100644 index 0000000000..598f1294f6 --- /dev/null +++ b/apps/files_encryption/l10n/sk_SK.php @@ -0,0 +1,6 @@ + "Šifrovanie", +"Exclude the following file types from encryption" => "Vynechať nasledujúce súbory pri šifrovaní", +"None" => "Žiadne", +"Enable Encryption" => "Zapnúť šifrovanie" +); diff --git a/apps/files_encryption/l10n/sl.php b/apps/files_encryption/l10n/sl.php new file mode 100644 index 0000000000..65807910e1 --- /dev/null +++ b/apps/files_encryption/l10n/sl.php @@ -0,0 +1,6 @@ + "Šifriranje", +"Exclude the following file types from encryption" => "Naslednje vrste datotek naj se ne šifrirajo", +"None" => "Brez", +"Enable Encryption" => "Omogoči šifriranje" +); diff --git a/apps/files_encryption/l10n/sv.php b/apps/files_encryption/l10n/sv.php new file mode 100644 index 0000000000..0a477f8346 --- /dev/null +++ b/apps/files_encryption/l10n/sv.php @@ -0,0 +1,6 @@ + "Kryptering", +"Exclude the following file types from encryption" => "Exkludera följande filtyper från kryptering", +"None" => "Ingen", +"Enable Encryption" => "Aktivera kryptering" +); diff --git a/apps/files_encryption/l10n/th_TH.php b/apps/files_encryption/l10n/th_TH.php new file mode 100644 index 0000000000..c2685de6e3 --- /dev/null +++ b/apps/files_encryption/l10n/th_TH.php @@ -0,0 +1,6 @@ + "การเข้ารหัส", +"Exclude the following file types from encryption" => "ไม่ต้องรวมชนิดของไฟล์ดังต่อไปนี้จากการเข้ารหัส", +"None" => "ไม่ต้อง", +"Enable Encryption" => "เปิดใช้งานการเข้ารหัส" +); diff --git a/apps/files_encryption/l10n/vi.php b/apps/files_encryption/l10n/vi.php new file mode 100644 index 0000000000..cabf2da7dc --- /dev/null +++ b/apps/files_encryption/l10n/vi.php @@ -0,0 +1,6 @@ + "Mã hóa", +"Exclude the following file types from encryption" => "Loại trừ các loại tập tin sau đây từ mã hóa", +"None" => "none", +"Enable Encryption" => "BẬT mã hóa" +); diff --git a/apps/files_encryption/l10n/zh_CN.GB2312.php b/apps/files_encryption/l10n/zh_CN.GB2312.php new file mode 100644 index 0000000000..297444fcf5 --- /dev/null +++ b/apps/files_encryption/l10n/zh_CN.GB2312.php @@ -0,0 +1,6 @@ + "加密", +"Exclude the following file types from encryption" => "从加密中排除如下文件类型", +"None" => "无", +"Enable Encryption" => "启用加密" +); diff --git a/apps/files_encryption/l10n/zh_CN.php b/apps/files_encryption/l10n/zh_CN.php new file mode 100644 index 0000000000..1e1247d15f --- /dev/null +++ b/apps/files_encryption/l10n/zh_CN.php @@ -0,0 +1,6 @@ + "加密", +"Exclude the following file types from encryption" => "从加密中排除列出的文件类型", +"None" => "None", +"Enable Encryption" => "开启加密" +); diff --git a/apps/files_encryption/l10n/zh_TW.php b/apps/files_encryption/l10n/zh_TW.php new file mode 100644 index 0000000000..4c62130cf4 --- /dev/null +++ b/apps/files_encryption/l10n/zh_TW.php @@ -0,0 +1,6 @@ + "加密", +"Exclude the following file types from encryption" => "下列的檔案類型不加密", +"None" => "無", +"Enable Encryption" => "啟用加密" +); diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index b1b13f2ac8..30a0caf003 100644 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -11,6 +11,7 @@ namespace OCA_Encryption; require_once "PHPUnit/Framework/TestCase.php"; require_once realpath( dirname(__FILE__).'/../../../lib/base.php' ); +require_once realpath( dirname(__FILE__).'/../lib/crypt.php' ); class Test_Crypt extends \PHPUnit_Framework_TestCase { diff --git a/apps/files_encryption/tests/out.txt b/apps/files_encryption/tests/out.txt new file mode 100644 index 0000000000..00f61adaca --- /dev/null +++ b/apps/files_encryption/tests/out.txt @@ -0,0 +1,78 @@ +PHPUnit 3.6.12 by Sebastian Bergmann. + +. + +$filename = tmp-1350393650 + + + +$rawLength = 8192 +$pointer = 0 + + +$rawEnc = vvJDGVEuiBSfz3hlAO9STgjDCfC2V37mtgL7SxLaTRoJLn6Qrb+TtPuwhUhle5rdd92N8thaiUq/9wrxkiyJ+JoDPsyLJ5xLZ1nsXkpHVaFj8sl9B1jm+7LoteXFk/4lVHVa8vLPFnTXaLhf+JWphJSxLlSatQMp8Zio0nV5oH73P2PhUdT2BFDrBy39ekGVZuuiTqGHySjK2xdhTUfNsBWp+PkQMIpAsYvz4mCdwJ3V20DRra467ghp0ZOVlRG9iXNEkTukHbQQtOA9xdnFCBuo1xV/xcjBdZIdBcKmzX5NUrGwVoHTkUnc1cvl0kkjcmHOaQ4nI0jZDthsaANio4plzwxLlygezgPjfC3z6sLIzev+vG90Yh/P8657imjsn4wNjHq6sEsEv9WEzfkV2IX32KHkXmdrkYuRU3qzprs8vbmYnL4/0axRzglzpcZN2/oE2xgji6mlyeq0O3QbDpsJJzv7qHBPtRdzizeuBwEhO6q0KgT7ztk+YncC1O0Eje8r+aXxY7lYsUHclxsfoy6m7EPfiPyOqw15ltosxeev6euZbr3WXcO6YxpZQFUEgYKzB+WtfpGKPqOLxRA9mr4aocjBPpGXXgJkNHJhvZ0RCNchVkVcD6Rs7DK+JuUx+8M24klscMSW/3lOWJQkJY/s6mOUvMWncEhNH5IFIiZPX/D6Gv0nlRIqj9yTLySWBA10+i6TvhDfOjX6m7QAtI4VgYtvYlHlP+q15Q64ZjXIjbqVJ99oVHpk0siASPHmcHUgBxhzeCznLwA+yFZniwivWBnj+zCqTqpwY+UNr5+3IlPnxDmjhEJm4Dt0wH6iqr/TqbNSP+cAW2oyywp0q0nO5UlwkPUoqb4j0R+iwzcR+P55UKmKpSJcXa6rDqxLro67kXe6A+NE9JGN05HfBaxAZOfXNakodL7D2qyQJjVFLZkrpdWrozVVraIjoCPJN70DyMfSD3cmkcOKYq6kzgeOL4ERzROk2D1tShVJli1HNcRuiU99t7Y8MrfLz59upnhUhxIrkeGQo2ubfio5Q0rrF9h/T6zS4khM6jB17XN/bc8micqefZURlKJYXzt1CwGtyCAZI+eloua3XRhy+IbFZG8QkgVmFQg/kmJ2ox3jlqTTtMuYXcAxWq2kqAstW/wjfCcz1+FRsK19IdAleWGB1wnZ61zKmop46F6fRmnR/uZkXu5JWPqeX7lJQEQ4/VT+g1S7W8A8JP8FxALXP3DIug7NfiCVUSBMP8pEiyTs29v03lKdYth4clWwbsI2/SOSgl7ownDNCdo0z72jfcLK8423k48HJvAYvGsN2rd2UK/SEGYPyiYX8oVuBCAiQg5+bOiGZqsqkFgdztJlVddXsBvjlD7Gkh2H+E8+gZVsdsgjJKsBuOTzMqS+6jqhFG9MUQl8fCo4oOU/RP52xs+t5eo+eoOV4A/RbOvJ9Pbhc8rxiPl9BaKWjV3Gg0NjqJtpu0CFbFg8pd5iD0o3rPnzKaTPfmcys1pwdxTfeNevxxIjM+CS0pAQY1Ep7kxk+T1LjXyj0jC2kNnylmnANmyO0juYXuR+20YA/huVBcKbfe8yBrrHb/8lg8GwwqCrBiwmZvCmahISRzl89bsqZJzTtwUJPa3Rkdh1PPg8hoBxkttT2kORSsfpUaGXu7FyIrR0QuTO6VQjyf9RNWyBbzFykSNmjkQauSyinKKWwsat+q6VVDHdD7ulFo0MAMpyFLbmKc+q0iyZsqSiwxfC6FWsdZ+e5ZqvZv8OHeERNk8BAOzKAYSWVrmBHWAdGTORK5QegDIbqFP38M4RpI+tuMOMxG5rKKRrq36n4ypRfOJ2tvzv5rcs+lQfzNvwYbtKrMFPbyaHN/eMwIrJSWXXd9YFYjeXyYTEVd+8iEo+DKt4JidqWl8cjA29vB/VeDMdBcxgVy2cygJ9MbuwU2J33Io6E6CLRphN2GPgWZG12hjG9veNdQAqa08OD47sjntrf+I18fwqQmNJCwwpdyC5fgcDXKYRS4EbDUmBM34iHPBuTTbJW943EloETNOM33Y+mkQnj49ag/Lm6oPTP+5Ze4vXBhVSzYXpl+lljpNdv5b3UKdkiE4qFsNqzf5HqHExUo+CzNYNRJssTPlLMYEGF+auNIcmMZcNW/qxRk8263OZngoMqldzIUV/PL/6flgt8gnnZsLQouvY8aUYOU/rwxD2dlgRcYhpyFtEsRtp0siPYQdIrswz245zPDJJSIU3CFu7gJfgI8SV45+dhQplK+SdZypK+QrjAh8R8jCZJizcyi9lQcnR8FQTGlJ5e9fTsBscrGkbQl0Li2MYunEOG1FFX2r6YIP3uf/2pcIbSZ6XdV9NHfK9sDSf5YaUrtdNfvuWcI/kiGmXkSr8/YMTm702rcHdY/NDL8/GlNsB5wMHpYPL3IMxFWF/tLjYDpFc/+cEmBRYpJ4px2fG9DI1lmirHDFcBv3oE94DdnK353ndG6tBYVS92g9gsis2jvOSRxwn0PbdE8YqOi8Ab9HEnmMgmEr0FNqRREOwqy9tUyCR209adTp7BkcH5CyxZNaAR4oZKuzT0Ol7nqVGhsAStwTZjn3Lfri9UCDxgL6xgrOSKe58R5qzm8CT0rptDxswEATfe5Rcibx8N9DcvbGF3ynYu0bMQbqqY+c40LFW55EpUqbqgmzf09VtxbLwxaHUkSXUd3Oji9jbBmksYNRfCNVrXdBhXDPVTl0yC14ByME7CqvR38ax8zmSBfMps90qMndnKp7L/cGBztqfopfqAz6hasqP07RyEpUPNp2wFxYqAYbTIf1NEsctvudXb4eAs1hNkWuYEbSjAzf08tQKSPuai5K72CKlfDZTp/9k1/fNBZKWIDsrzvK92kfOiSektm4SJ3+8G4cuLWU7iIx0CInq/x5gpcXPXN6OpjEXXP7yAsvbiPHE6/X0M7ygCq7lh7iU/bL1rM/6GGkwJho58PqRqcm8XavFkEOrOgVSu38+UHXOZOLqgnREAnxDsFJor8nN005RexzCgsHF1ejSBDAOPPuLRCLaJ00MAMxMxMPK5iG2I9KxCX1R/l5G/d0qdn+JrTylwnH8sjmv6D1CBSWsnN4St1bZfny6cnD/t9jCsNYtCJ+AIO1X1vhAX0whqn5ZNoOTsT9uMqczOdfp+M0miT+LeAU9ff/2yoyWywCUxnmJAN7acD4eErhXoz1FEDplRGZ0JlrXWJXvhIzRb8M4KZrzvIbYKBFTyjpL6/wa9A1dNTKiFr+24lrrKCuO7HnWxShc27hbrZZPDQfq62WzGjW2SM1M28XIOAnMrQotS03D4ee541IPRBmQAM6dkTxg/s7gLaPedbvLB7C8XBVOKoY0M9oziiFwtniQ4MsN1b2NpEZnuvZBUvUBzGlFQdtIVJoeikhPV4uaHFNKV0Wa4FnzgwtYk0gFStTDHv4twq1N2as/ypRjzNxeG1YgcJsnDvB4SCz5yXuJCEBpWRp3anV5jEJq8jtvUqCJVz2ZoeSN2QVHz6cnxuDZrS/+AI9X4JH65WGkBJ92xcM2oP2HwLYBo3YqIfuU841gwDF1qGhRyz6yAlv0OJZZBZLDaVeVx8Ehnflus+ximDxoWddsACMaIQZvNpCBM5pJAVMF4Y2TXbj93Y3OJJHBOlgQSLtyIoQzctpS9vTUvRyukulnnzKbVL+u9AiHGlTsiT1JmqQDodRGWZ/amqVjCucK7zqbhPkxTqTUPD/PMasu624ovUL6j8nE2i9389QBv5BvAt1Rxymd9/GJYwqZf/FEvEUNjU/40a0W6JT1fjvT6fhpNUGD5eF7iRfhUPXqTC+zzo3v1xQUxCCF/fLl99gBsTW5JXTdc1h+63dT/91RM6zD2upmYvIm6OC/Zi5a+2nLk8qFk6ckPPaBef6RFCSiXB71U2p2mbTelHwcGuOR6Pxp/xi51G1WjFYM6ZoGWM1lq8u1o2xZ9HmpNAUK5SwhssNOPMBGWMU1gtNGjbb2jL5XD1nnPeNdHH9WR9MrBZFSjJw6PEIhEPJ7FmiwnJLNc6PavCoqW7yrrsJNDBfaeip5YmGaJ6C1k2A1rcAsWo4G6kehkpb7n67mu0uHkk9UBUPVs7uuHHq5ofQXCiWKh6NBZJ/1TdveiwCgJYpSatWtQIYyAwulcmDIyseeZLTNXVmwZfv+TwFwpfI84A/w0sLXgtBoh27YlpP3knnIEmRYFh/7OslM7xqM/KqC5oP2OQa17Ll+fL41FdzNScHWtdKxts4H/6eUBNjDsA7HFeK9TyV71lubMO5Cqui+/c/1oobEqic2NlgQmE0li4aSTziCtoTBWe+cikzd/aiAptsbJ33I3ufboKhUROxQhuJqNFcPOe/sHXb0qAJRhqkhExbki7nnx4fC1kpYpNoxBxgPZURyA7wndHzFzGsRtUM29dqOoQOdN/wG2NLQ1KEDhocJDl7qelBKgnirNyz6XOe8iq5oahYOD0/3Qbi4EXu7bvh5gvWilIy+cSRfEBJSLhY7hLni6a+VyJIlJasjly5bd+DEQ/69bQBKo3zEEBXIPVbkBJ3LxRgTKZZGHuXxM5fnJNLz3zu2wVOaCCm/eYfpmKXKEQOoDgwZu8gAcLrLm7Sav3F6t3qPNPZWYctb8hwiawvt18iHzplWfwRA6ac19Qyr8gBOBXJz9nVtNvp82PhW33YplfAxjTKKsM53eZd/aVCuL3tBxW75oLfurucnzhacIEfPuoWW6du0M3Gl1wVJUXqWLhNa/xyIOkB7viFeYTeSfLde6bQ/Vp9pn0GgAyyqtdNAfMcw+8844V0w7x18Cx9K3XPpvVnNobhJnwlURpW/yRR9UVBcaDfMeqwAqsGVENFj3FpeRyCQ1KLI1PGDf2FAGXJ9dZ/LimyLtZt+fp9Sk5NPvK66oryeW70vuiVyMnXKx6tcZFVW5eFKsqQ5ZrKNXRir7vN4mZPFEpUJBtIVN37rLM+xNmthGE0a4P8am8CO36tEBrBclgju1JmGG6khxpRR7kN337Sr9LnZ3cZOffXXgrqd8AeqzJ/DMc6p2ekJg9ehJOw6UogOfG4UDtZjppRgoQNZzGNnhVBsBSwlcRgyM4qMUmZw4qifXTBtOZpiu+1/gK6sYuZtImOJkP8GYm9EIpLs7V3uCjKJmfLtBldLJ+1Y8DOEbl+kBYEXXLvkDUoopSbOgS01I8AO8+VYUmYjfSCkyBD1XKTHoopdhlhQJ+7g1JmuDyEV9ucFjgHkVkMAJeomhAmmj7sBcoBV3dcMwJdpHBXTeKUBkGoHjsjvsERqzTcKcEKXNxetTD9zZWEFogayBAPhD08xh7O1HfF1h9tXOnB/qV7h9ua+PH1vTu0/AjVrtfreh6Ax2sCMQKcwBn6CdQDwI5UJmfkWG/DcMIbHdgm8XdSJPgRm6DUv1F7M+sJ0wbaSpeYtHkAIGkTGaU9Y4i0w/Ei9O+308KZ4+M+jbsFw9RW7SsQonWwM0AsTJjZZ9RlwTSV+JmU0lCgDwLbjG/joPXguoXP3p9aNhBYdcl8/Nd3PXf8aYUSMCQdmrt96I10iC7lZX1rs8Ly9eXW5WkV64bVdv4x/nVu6rrZJAZ07IcJ+UBFoxCHyDUNAubaxPG10R2GHtbzoEhv7+p/8Q6S3g4rmWOTKUyogSS9IUFvsltVIjiKTMcYpkuvY3j7HOyfE8tPFUUZZt3yi8QWDUmFLDAOe3BgAj8z1vtupjMWEFvEQFNZfWJ15OuzQ4GdtH4aeVZxsx5RCy6hEQlJA94xsD+e0dmmbwiDZCDqtgMeyg6tclkIKCOTznrEqgFSE8Ty2K/+w+bUIDbqPkkxUX9Z+4dJ0ItougSwzWYdmovs7QSVV2F4L9xKeWVmzKRTZ4yV/23MRH/2GwCOrb1qLFifJj2EPJugO3xiZ7V5wCYdo+c8Wj282EfHMxlPbJ++z4DR/IWM2P2u8OhJZ5jwP/j/m32MiHkT2SDte7/jWfmisCDUzJEDu4H+zjscfPJiGsUJBt8BYNdy7kqNv0rGF+PBArxFfuRXWyRagHeLUuMD6sOoJbPsIK2elMmRyFWy1dwtMyccWLX4Enb7V1AjpJGXF4zHZ/UkDgPz4U2f/KpoQvgNrI4+V6lCnYuDZAq6LTT+su5JOyzDm2ZBVphmlwnEroQiLEZVfJUZIYSHxNZaCO0mcwd+v/h8agE/XYdvGljpJ4ghxnZ5TThOY3e/QvUcnIlRGDi+ZUNw9S7T5oXNhVUKa2hEQ8FYWKAGmTHhPYKACKK6g4/StCbaJJ5tp2m66xJOVDcwt+ewXzhATKRHRN/qe61tu7cKbHRHbExfGT/KsMQIID6FUA6EfSiPhlDqqteggsFOtxyFuoZUUp1LmELJT8ZntKUi1hJeNnj/F5rKwo4Z4Lpm60MYJCeWomWqR0V8euDsYWmlTgfh+ByeQhijqBGMXjJxOEDVxTiQcsFIhAarH1AXUQAKmyeMkpow8RkbwZwNZQmY4qbAq+GUVzl6km/1OnogcqnMtYTHiumHqZihtmAoGn8UJZB8lEWUPaTDH3q1Po86Z7j4IFRuKf1eVWv/oSSrD38z6i+FLYdJm1BWdMlbtxnjgI/1yFcXLK4vQ7fQH3K0p9fiDMZWYb/rMh34bS4gtgbLW4t+ee0NLqZjylaD6BwgYApqKZtQ9O3KZWATvdH5cp8Of+EUZa7GjuP0bV5BFt05XGtt2Itnm/eUMbl2rl7WNH2dD2enVtiuyJgjxb5bKM+VCXuvQD57lDJ3E5q6yPGtedlaGUM6xhNPpz0cf7mcKsQfnUvqQBEw2FLjBLtIlETPU9Gf2rlvlAr4cp1RkjmuaX1BhKCQhyKH4wabP7VXgO+loipYe2voCVpEAj4e7Gj7P4m6VxUA9SZrxL2lJced1UWNPRjiCQMb6tg49uryJ1QQO66zBIMMgMh0g9WR8TItqaHGAMBU9Wnoe6Eu+PAE2ibtGs12R/e6GxxKwWQnJkJOFbC6IN7GiZrZjqJhRVQGNRowEo/PpCCZSjBvQtRwswopzqvKDMyK09DYblJ+dfFnPprEr/lfN+rRI+TBQshisCieFJ+5UGGP0vhBV9LFVEi13HFM/yL1jWURB1MGQDFG37SMbdRg4bvl2JN/Q+A6j9Tyz58XqBDbvRZ2jcid7NuL0W2yaNctWnLLpM9FB30O/kROp2Sq7Iyx+S69nd73nGRaQg4a+xnIH2oyA2/caBlKFqmUusnIyqGe7dsWMMYSV3uQi6ArQ7ExJnnBsCKRDDz/WL7Vnq+diejypmI7SBuViv2Ucn0ieegMoP06sgRMZvHyWIqV7R8c2JOxs0L8oJyforv3ldp3qdadbzQwEckMUg5qUYcozEa8vpGUn7er+9Z0/7T6dEO7dl+ddtv3pDf28ZCzwiL+yLJbs+Y6cxfd4XWtidZOtWWUKMI017h/a4y5FqXC5PBPOZQs7XiyF/iXSzk/kdbCMzRjpNvxO5x4ZV0TrPe1mzf88CpycVpYYDWDnJtochTHTUhJ6JzHTCIZjy9XencDSI4xOxZOu6tesUQVB7hhaU+p1Aag8mvz/k56qXCsa2ZJoNO5YDu0AwmlSRDOofVouM/K2k+sw6PDoGTEVC0nVEz4dIIcGi8j/qMmjuzW6+AXNc4NGsFJb4kRvnkCAlvoBdPpRpjN8JToc6b2fNwhjwWVYHXqlXmylrm27APTrvn3Svwur41dr+MpXAfrjGAtULq0mZiChPrTmF89NYIZ3ZQwhjpKOSuLfky1RZ8IXt/PMoqFqSHcJkJU00uicsBeBK3ZrsQ712GuVeImI24t1lBPdKfsrS5ECdZuXs6R3TMly553r3w1lkNMyg5VGqft3Ym753FVi6uDIrlyu+G+kOXFFz2SSVwTmks41nzkQQgFq87NV2G72lhXWGL9s3fRP9nmSKpthwtdVjxqSEMvaacKKqk/U9HP5SCrhuLUvIVvnoPzM2PiiNoxzKHgtwg+Tl1y0/zqaRk1z+ZTnA2//kKp7QZRjMzJ9IaS02g3pICFP0FDHFPcFyyILr9PzGuwEfcuQtYUfA5H/n9z+vn0yVPwCn1jqqczlOMKcdOXCf0Vops+uFC3Y3lpRN/egGB9McDaS1SVvrubUdbkyQ+Tf+iIy7KITKimc9X7Co0fB5dgZIOGrnoyK1iKTjey+UqlEgjQvwBKWVuky00iv00M/4PgOZwLTXSOHH7xx + +written = 8192 +$this->size = 8192 + + + +$rawLength = 8192 +$pointer = 8192 + + +cache + data length = 10258 + + +$rawEnc = znvUwmPGgw9YsH3B6+6BvP7UfXmHu2ut9QsVnJDwxaI1G7AGXHc9mlQRGm7h/sunL/zfPArAirZVIK9yLUHPc1dFGHutMxTqht8yBbh3xnEQ0AkWL8ZKEGVQuSfBh9hGP7UIa036ZHlHwGIlU4c2MCGdXtUMDrnMOFF41fkkEi9NBe4BENZbDGLqYFkbmg2DIRBZycH4AUJahkb19weNJMIPFRpMqDHNw261/PPdLRhUYKp9zLvzci5jXTTV6LQPcx/lu8kbM8JN74Vx34aJNEwt8ICrqK4XuRUB2RfcIZD+SW7aXNMVA2xOVPbonLEy0ciFGsb7/nx6br2o1ca99++oo0+MtyhKQG1759j4Bo1W/N4eo6+mDsg+/zgO0BGwgKk0ND8zqtl5Bp0tB+JAP3bRFn1QcWBVWXOK4JjQGCsbg7hncILIqn4aOSNJ2SOt+MQFu8ovD2dVVzOjqtYWbuuCgTPxyItwxxeaWADcmdAuPDZ9Fy+uRO/XUE3BCYypDUqSdmG72sd2uyrCPbvPGFKG6UjhwWagmux5HOP/+GCKFAeDPi4/Nc/LrgodZbRSdwL4EAiKPH4S6u9+lOWfciZhBAqsIAXfzeaEDwIZlnarmpcIFHnTiFHt+Lf8icEebldW2pCvnLoG+ralIS5durfutbLGz1l+wXOf8ZKTQf9Uh8qa7DBkGQYA0wLR+DbsJNuq4wd4kt7rhtkXC443gmvr7NdyJ8SajvUeia7jFYUdhANYMhv10blmIHRGHlnCtjesqJquyo/hQTsAL5gMsXcB7+81lZhzE6vfMcIuo8hfansNzVciIrgrG55wqk/CvS75mZS/A2znNhCaw9N5nTVMVfkix/JiQw7I0D38G0aVwvuGShYvur2kFHoIq6eBCIHjYCe1ESlWYinAbGzvUp7RS1wDYYsLgBN+6ofRLl+ItUTVzY8daXRgrIXfHwup1MzKsTJx91PKDhvqfoSWbcs54dXWQG2A7kIokscZ4gDJ49p2tmQn9cEAcCBRWZFHx2YbKWIYH5+ylBsEhG1e7ozVvyy97iTfVaEE+LqHVtrhzWjNVkS6ff9wDnSOfz1lvUyv7MNmcbx6N/VKeeTrpd093r27hKQAcOxQJ2suFsfR3XHLcDCBNuHI9HXU8wYBxcTtxtOMgRcfARVJ9KbMka+Xz2JIqOZcqAhCJBpUbRo3xkpxscwaRZFr7nJKZsQeezPlN8s8shX9+kowvMEI6ZFZRpwHhkwwm1OQwRQmxVI6zUCf80lvf/6ZbfqRawiWYXn/fxEprZRJw28TfVuvAcgN1rnJmjsGKAqmIQfGY8pbrcCS8yVFqBGeiruCUO7dkp+fmWRDXvFIxA+BqsFTbT8emiYaA6W4hyaRxJwD+xrSswM5fDWb5+m29Ietxxr7213T7UTiJ3STAz+F4Ryv4hvLk3KOqtGCxuKGCI8HA1X1f0hmnxg1eMnuh11eZwu55cKVhNU/+E/0K4SX39jCIrxgHbsGRBTVxvM7DeDT1T6uqNZbc0uoqnBdOo/30yzdh1oJcTOAh7SQrVBAvK1rK7so5G9vsHwlOT7f/1DK2PcE71nAqJCP8XcOGD5QyHbV5O8xW4qP8HIjTyJWLYbfcvGFF2Cgj6Rtu9TBXbWYHIUSJCV2KfVhYaI2Mh8vwkKZzbDUfDD/Oea4Uvk2PfSbRbp9zYY52Xm/NJAwRhCuGfVihu76rKWKqwxtBhHP+CVZPTel/RJ9wQ+hmqqRADhsqt4Zxl+GuEjVijnIb9csHPXfJcz0FX1CPkKhPYMDOOE9g1FKrEkLAJJrgGesEc53d1dWphjoM8gkq3PHHy95eWTayM+4MN0if9Ue71uoCxkEBT07jXHInxuOilRLrlX39J6Xf92WZCiZPu8QgDfjKICJ4RGo7hBtQWBiX+rEo1SDAYIZqeT5uEBmend7ct82eEBiHJBpOpOqOGD0zcbD4sqSiqdokL7is3YpPMTYqp2+eYrOBLR9wVMyGvnzr6mRl0YZxH3uFWiPrqNfHnro2DvZDA4Glq1GIrIpPtvFboPEUrJDTtiWliJ3YxlcdI/JU1pGuRTbcx6WVt0mtS8n0peY20kydYzzozdCk6dAClG6Bmf1NRJZKLHM8UrYs/IlRAy1+/w6opwN6+Qo3YbQye4s0N9WmP21fHcg4AUP0E0fAhkpXgWlnnTO9QZ4C89hzvtb80WN1fxPnQmbHujMD6lOH8K7A/ZNhSM2GoatOR2LYzcJYr1joitZhJwNlwy3KMCIa2DgT38cnjzQWr6DrWO5x3F3ujy4sATkLviDdFCrz2cdFBCqtavqIS+b5hq0dEevRrwfF1R1BCRv4Wxw+BaLw3heLij33djS4Qvz7GJOmwGR2kDAO90YPNOuvgcPdpEG9T2xNBGwIT38ZnNfoU+J4y2EHk6xobxgGG2ZPeobtstiSQFJiO9ZRJls5Hn5anVq2F42IHrI3uq5W8zpcYT00jGC0wNKn/DgrhNgk4xy8DPVIDj6csIEL9lOWXaWNuqUkYYmpWfnxJ7QKQeZEFOz74CzVGqnlK6rpjLHHQg75qneDJV23x6ojcYH2o1uLFWbeb0zXus3aCErR/H7ipHgS7Dd6C2KzRTK8tdjZYNqnqPpByh82q8FpOQUoSSJ0cHlUpujFDhXoc+d+am/kduph/DBo+MJiKINBi9Ethy+Xoydcy5tH1G38BuspZpIvs/zEeH5+08WB6JpwNyayvGTNGLE6oMeUXFAvNNA8vxxyrSYuVEFtM7fIZ2UErYw22yyOVyHZ32CBYOgNy3Pf2e1tzn/o5yaPIZMVmcQiZ5RHvzVMvPe5g+MDR6NY6LXocErbxxL/6FvOS9eY9LkwMU+cKwPy5OUOgAIo6dVztK4MFT6/qwecfhRkBK/THKqlPVx5smiLZq3KfoPEZyCJHe2TlrA1hVSG7VBzuRJM7+MOWgkjulT0jdYoXWQ553pHxWP5lkIpkiPaJGZCvq+Hfj570XLhRbKGCtn8k2JJQ2Fap21ZzRI6+o1fG+GyPB4xEfND7ZanmFtFPIIshepUR9anCJXdcO53w8W+YUg0Dmpgn/32KiVVyoMmBn9yQpTc7tybC4/CteQAKAXKz1ZoV58CLc7KOuOkEI0pR/GsM9WssMsR13tDe4dEWCWqgOQi1gP1LjA85jylRfZZz75d6fCYwZTiHVJcx7ZuBsBE142ody5XYprEt/HpYs7Sw8dJJE51drO6XxqClAUXw6rlAjuHuss6gfYwwxxa1bAUWWeLREm0s3QYBR19o4RQTbJrOD1vkhfS1atFmuBn1nQcUGYAw12z/MAMufDFNC77n/VDdRMFrrOmLlERwSNOFKgXCrfClW6XmoXkxOSrnywh5cYwz5v7vltNxychXf2ZAN33BhleZp7VrZ3Nul5ak//tZ4zX8Tp8Hdcop7AsxdUXRs64/6QSriZKvQSTjvYP1oO33DQE8X7q7mDktAi9sSbJwUaj2seiFmGH4t2nJffbakS2ZVk4YISaRLTf2OOaqHmPcKfoxfEiJ1C67m9rLvY1qjvryGkCF6/ug8WhBdkuwa9lcoHVqCZnpNnK4XHiJIQ6srCQJZJAr0WNykfX8AwX2qZJziUp8jnlbr38oRKCtm/VozJJSo1sTpBtxqnxQPajkOCHczcUOqgXVml3SdKeqsB7AtU53cLvnrbV7aLpt4g7zS+SkdcR7PhEPkR3X5VaXSlJFhsypeTTRGiyEKMuHANnbc9QsKTS4Kx6uQEbexFDlIYA8dR/xmjIKQluwSwq+baRESqCMW74l0acbH0CRjCYZEQl+FSZo+YyyvTihrjETVUiOPKLKsCAb2SAvLjTNuDtxb/vPTt2zyBT/09lh1JEsfLJiVD+u/sJgJyaMLKp+TZyZqsFZfTZxT+bJCSi+W4pnng8vLqeG94OqIanBPZf+phPWtQiUUjfhMJtNOdubPqFFZnFia+yow99qXaSZfSjcSXFGsxTTy3Tef+xroEMSrw2dHOOv7ulTRtCAjRIbMJvWvXqnHKl/F/vtVTJYfOd4WXzfjACNmtEjATpXNZb2dl3gZulrVziLWuVsPnR1ZQLdCBdQO3R4IHYvAon8zipUwFSVfydEtCBC3FnOBfRbXEH8qG2r2nmBdsRq2DQRwacGMxWH9lhzhJPzHb2xxejMK8cyW5GQXW6GIeyk7MaVrpBr7NsuqMsesxfZAbuP3/buJajC1Tf/1Vn3BcsmP2RHSxQow4ydbJmQql/KL2UUHXXy+kvAROPOXXcZ20VJj/X9IgrZJNdvxZ2sEBjdl9zJTzHNvDlaRl+EPwYx7QVkfbuaqWkAiygLur0HDPTICgpESGpCj5x39PP3uN0ebaV6lAO/vMJtB3tnQ7ZUOxR1D/2gkHgO15MudB5M+Tccl4TgFAgI3BEVJnAL0QavQlJhptE+Oyf4+HgxZIg+Mbe+Z5V21NEXQ65etIwy5EvIpDcUX2AVDam1P4hc7D7TRNE+owQwfBXwXpDo0eTJHmkz1NWsTdt4C9MgPt5cEUBn/eSSBtMAZViXlwPnfAc0YF4c2SohBbNL553lWyrAGVJYhE+9aKErTVtRURdAqBCCE7XwOQbcH9/Pjee75t+F7PPQFeXGJ5Ezl5p3ZtHrKaDnzX/n6/fK94wn3jKCf0cmXINqxJGh78gBdIZTym1RcrEI5YT1aAIHtEhgp1EbCduXuGb2pwoLgyrcJuCQa1LSZyYSEuavfz0ub252aUu9fCz5btW+6vk5jUty0W1NgE5xhNA6xbp0TRswEZqO6IkWdEbPVuK4AQDmKu2em0UbHwV9O8kUacTJ5bXwNEyR6kFf0oA+7enmRdCusVkidp5S1Ya4saFR839oSy/I+9tFsX3BVYWsXbNmZ9WJ3owcxGH+r8eHTE+KFST/v05ySDtpyR3UNX6BBp3ROzq3OuMHAc0Nc7TLmbyUDTdAzUh6WjgURWNqLq+Kfzlo6Td53TBtrwHjWp6sYSEiRG6W8PbXSXsZCIDdpm8NqCNjukej/1yUUrtjbnwZ4HkjPVqsl+LVFvT3tu7N3b42R7rB533TGWZ1/s4MHaWmiyPQT94ReyRQGb/kISabsxGGTSqkdOjZ7URaOMlB8lDxw05VuYjdj+MBT8RRufVfRrX+N1FptcMnkmqDv4CIWMR3ekNzv6dACovzM1SruTU38lDpl8cgxGbTGMsSA1b/Ww6rHqiGpIyvSN3FAYPcBB5F4jixceEsqPrQRpvy5yg/ofAq8AWpH1uaqlgTbd1mwmIb8aNnEG3MMbRoFWRJTZeUwVkNC2CLne6vzBKiPa/va0crtiBccK/3vVES7XvaK/onteu83Uz/zXZVkUVN3hcRG7pdQgKZR5TEC/3q10KCKHF/eAAwhWlbsKPJ8UFR9aXU7yCzjRyu8U610RMQ0q5PDwmz7MoK+8Mp8CaEjCOjiTxkIPRKzJudWYO0O+uKJfMLPraREGoxARGJOCwPT+ZD7eUm4KyA7SzljA5ywJjWExvGlr2KfeXwVnyhY6SPkq4MBVOmq63Os0ZauDFfSNQSlVt5ae8H1M5iK+R0hD29cb2CuYiRYhab7dmB4/d3HT0ybJN7O9zozo0vmqplnWlQ1zW+W01gtlUfq+oKpda3G4YpoXUQ2td+blGFBKv0QcL+YAo7AjrFQ0YWA0w/6ToV6B3/Ddal0h7pQxZXskpkov5QT2xKGPLsJtADKMUOFqYWT1vl1B6n2Yd7Uw5BGeHymqNK1NoaJJGnJHoVArKfo2RzJLjtKKMUBTHGJ0zhT/0yKmnzysmA83uunU1Q6Zc0jWYKUnGYhHS8E21WfS48z2cIkHXxyFPwx7WbQAmzvQZzgg2m4yrcm4zwsMwh5lrHpQ1rypYzu2GW2tiByq2ZAbbGyJBa5ZMJZRSTiU+i2hLpsjWGmso6nmWXZ5Wy+4LQFRqm0jGDcoyniNz5R43eSJKxLkuE+05to9C69yiVbkBDd57YMwGPjkX0X4Zba3gpXMP02z2aX2JQLoZp9AszWMRiY3/BSXFg6UaqEkZbqh48pS+NqvDoe0Teib7rO58CwFVy0FEoAKq5bw+MwDoYCtwXjFavq6ygnWMshu6NBXuBWyj3it3GvqXaxf1TKxUEyXhr0+IpQBBSlosrlkC3gDXyhDVygnYNMsaLWOYykP+iUiWdlC/1t2RGn/5FhSeSBO+4bocB2g7qvntuI3c1fKaZAWTauw8XCfdRqFNyTlpC5LqsIrhayqy8SRr6y8FXwb+qFKHuJRzaSB0U1KvAhkBCliZJFuI4zfZQ0JQ3YnR+sbRfPJcdkuW9A3sLrDwrp8LVWhKnEORtRfsG56eM8A9I5t1NGY2xsWBgfAXkdpx7cpJIaoSejEO467Kc5YqmpcjTOV+iOb9IS/eR7MblaG8K0+Dri8rBLTR7B1C4js2pZcjbwS2DKJiAUyowE1ziDMxdVYry5EAr06ddaU4x2OumjIL8GFIRkWPaE7dPvoNqs9DXqCWds/ZnQ+Z9yD4Q7cAzkYoJXx3alVjxZhnPHuTNTA49JlNrlMeCxBtolzDNe8ERWgB5OQYOrwa750zEfkt+NM/5Y7WIFuSyxEZmoYwEz7bma5sU8NrkepvWg0Nt+OIoBLXnyUsTk/ekS3PONCSBvS5fTyLrQ+33NKXeaV3Ik+Fld5O4hNS/ku6dsxFwRxnamiIjgfYlfJ9xkcJxMMVs9y/KbPfKSELEtHfKmBVMJDPWT58WZbRn+OQmVscKph38/jjqi6Ftl/W/Sn+rN61jF2RLBoPZxZ/2LzWB4lXis0XDZdoSOcOq5HfSSLTMe/OC7Aqr56LXSCLo/fT5Z6X/HUVcZvKyko+oT4ux/apmemMXU8tYt9oCaRTsHL0KXH4CMCm8xSJRFHxRiCV43Oo+kLWmLdZxf8UZQCcb594g7jnGo/wXMTQPqvZ33ZL9aWlLk05aDouit+TMJWFRE7XPjiLFGP5En8j5dqbHYauF05qAIPtNZ/Hpz6TpO044PpuN1SSQI2r234+xEA3L6I8T/YMms96nugnyj1iuuwc1uOcDPzIoaeati3Km5a9BAl+0D8fYU2YsSn4cRU3nV7Kz1doIw6+F0FbR7QpAwjxGbtpn2TtoCD+6ITycgoRoo5faquyDlE8u1AUOm1VurulWNwJhGF1dtMhHzPrstvjIBljpTgT/Tb41Ai1ywhwIMtLrxAQLCubj1pesMLlBpF80zwV/mskqY69sWRVcA5mCCZVgTiCsi7xOKeqVOhQRmgs8J3medtF4rsYgFH2AWbTmewXA9uQeyW4xxs/u3XRrmQ3Q7kuvkdV4OecEdYYFu1vd/NYVmbT0Z6b7UECjw8O/ouOQbcAb8a9cKj/SZovzqdT2tm/77IxAraCGgvHnIFcLdWr9Wg8zrUME+ok3AX35NW74VsCB74SM+XCiaHQt656lNYwQj+Z1TwOncBnS/EH2WbT5E+LXJ6bunvO5mPe7zxeKw1jSnta9KJvHYBFkQg95A4oergGMRqGqXdGbvqe5wkGEWOUVn4tkLtWt64BUttot0YB8dU5HXjSdg9iybVGvkhTXPmHcSliYsvHvnSopboqkDpKoUXlRoslsmOF0w5nuoEzx5QoOV5X0qAg6GuflLrfSnHD6P3+wzGULNHbh2YRoH/Hqx+3+rdOc7YbBvvigXEUISDp3SzRyGhqNEFwkQaUVw2Cj9OB5YYTzZMH8OCIouoTZqaCknRoD0ax6iUo6T0k6pNBo+sEoVM8nhZodzmIt+jmOadU2M4ocXO/qlkVfe0ftk7lKV1oDtpRbmD4NvtZqoqCkDA81utH2MZ4mrbD6G0mFfBNH5r8GvIf4F+WHA/nE/hFTw8ZL0PbWlHtA5mnxIsRKuhgu3NtHYe8qGXDnr2nmT7gwZZGzPBr3sHedW0anKP21+ejcYFI/xj11bURDOBDivQ78bNkH9WgfWI01qsLrBMpGHOjCvoTe4Jed4H836JVn9LHb8l1++cKN5S2NYlVbby9acdLXw2oRUQtNPD0NYLEOIKi/SMXoWIWjOqmDCZQfhqFvv4qY3lRtnnTsRniZbuLBQc472avDyI28CmYwwpkC5uismVBmWFkz7ZrpVvu9HX1GiusJ8KsV+20SPXWwu+u/ORLODYPoF+iRkdcHc6tW4f8QCQKLTYEU4jOY0NEuJlB6de00iv009zGKkK9rKWzgOhM4xx + +written = 8192 +$this->size = 16384 + + + +$rawLength = 8192 +$pointer = 16384 + + +cache + data length = 12324 + + +$rawEnc = HcbO5wFhZmyZVVPWpACGJkLLsdly81NHl2GnpepBFakB90LcofLaZBp1SOJyYZKW49/sBt0g0wyW4jgNTbzRDL5c1pAFVp8hKPH9RPB0HKdF8ySIOCYRf80rMfaqX/u1+o88keLPj623xrPc1YjTdHjO7c/QjRH3UAfFOH4uk9aFuYVoFoC+GwOFUkbGwjAi5GL9I8Sa6iX2lxyAmEcgtVDyKiWuLCGshFu9yTmSe7TMTJNKGaGBanTqKyndmbBllknxHAt1uHYu/ao9ZubWOhJ24FzkPP/de2xTvnoDeHTDMxZUxwN/VUnJfpKFvH9Cl4DXqnwMtC3hDkpxpiIJDspBDczEUj1KGzSY5Y8H6voZ5tciTz2XJwC+nHY+RUFvFGETfX2lu9Ax4oFq6rbpHv4elDlBdoAY8OTZx6Xd5nZJB6OafPHn71MNFrB8DwCezKKxEN3Wx1+rEE4O9LlMsDJPGCanalHGvdzLaAhjhmGeki43FKz+nq1C7TLe/ZtRBw77HY+W9V84/lgIIFg2F0PAPjnuvfKv2Px/pez66Ol1AfSdbcDM07DszElMsmbhjxrSEq2SvtVrljTXk8Jck+tcjjIYHovTEDce9Y0JN9Z9P3pgC0MdeHrxRv31cqXM8z62Ph6XDojGLoPpXJrpXVZf7ju/iMuaTA9qcxr33D+KWI/UlOlgbdQt7ulwm30cj/ma65VMJsTwF8PKxfTlwLw9gs3IrKD6Rio2aizg5AxlnL/ffLN+TSQ1UAHnWde1Yvca90Is1TAHKiehLr038JujSkWgZopU4Z4gzpo68jxceXMr7T7bOZ19cFMD911Xl1OvwoPJqh82ks6tYT+RT0cypy4SyR/oM05dZR6UVsGyAP4GrB/pdaB7Nd9jcOu6WU1FP1DmV0PfO0qX0/Gfmt83An8W3hegai5lzgQHD6OFjGpK2ykuWpgJG2fdo5SwOgOi4rAU8FCSnuvIIanBsFJlMCKAOxNo4YUvlXNB4XxffoekqjQc1Qw1ZJottlC7pfu3mAXOAoATmAUcdZJE2Rda5rDyeRfz6lX3SOB02CLIouuXiuYQ0DkUv174LnAhBG06hJkgoOs/z7+KZTPG9uiorw2EB3fSYjTMRRZzFnRy040hreMkrIkIEk13gXLjy50zRswBj9Z/IdWHM2yxvcNcNd99zLNLUPo3TLC41GGHePje0SCTzzTeyKDJk+o0eefyVuTZ+vcN4olAlRh/VTYezTqduohONY5bvH3TpdSm16FhKQXaDVmZE19GjOp6FQlIpFQX4BGlrboLsvzTJXKh/SvidiycWHCoDdvQ0pB1rgcLJwZsMzbRhk0TiEoHS00HYaAulyT1kJxXT5jqQdOK1sscsfx1zfVv7hu17hYGTcrqI7DGUhhbz/kHr5FIt3xpbvArSbVpToDsETSx/ydyO+R61NTJulpGoCwkGirzgVdMlAb5OknBZu5jO6j4Z0D0F4WuhcR2T+pKOGTgWjIvpd8992n/QeiDZkCENFwDGCeG1mXoZjd+TLuXkGLxGbJBaURJv+7cylDX4dsTCStFkdbTHcosicqU8qILeQSttkQDF9WCAO7ZDFyDAM+pCE/wQFp6QBs2gv/Ehb2QS4Bd0r6AiQHrfWpukM1LD8lK8uxEfgXDZBvcOQdFI4DyofKMRJ2yOK53TszBf0BFbhjOpzxUJoHAUQpVyzGZp2O3zNq+Hbn6TKUdnYJF6jkMDulegE05AQYiHFBowUkk8BQVYHRhGh9Ya8HzO2JYXA806He/G7CDVLG6qQOpqepCLS4JOPM89UQy1jyFFrfEHB3dszl8CzU5rmMhfDo8fWoVN9/SyqHzuVI74EedPu+A64YxDaIxeR8enck6MIPFZO4SAtj9TrhHrfYbcWI9+7kcwvoCoU42RQaATnCfBzvmssk98LvsjiBmpihQi+msbFXvxS3VKy8GgQXlZdpfwTQAH6x04+KjquGYxKO8xsZAhRVvJ1gEw+DlBZlX7XKq5tsMtVHfZ33W6BZkJBONoVMljL5WweQueSWaFDk85Zf5uVOiU2cJ/xS3cL+FTR3wIqAFelgvhbuW+MpFTcp6l5uYJeWyfhrI7q/kSYJ5aaxNh8zlNwxeBo8zaAmxlJe5isNJrFG0xMo2YbpYBan3rd8QQ11YISetZUJzEISno+Dev7+7buwC95RxkhMQKbsL9arA6hdWKztqM+aWHdX0G44Cs89Ux3GhbC8KorUZoeXD4pWeY2LGmuj1aGUQnGmVFk7gpO0K6Sa9PhN9K7oIFxKhmP4PGni8CCjI8FO6cOrR/jW4yeZ6+ePgTnQlxFYGLwc659NtJEkqqqapW52VzBPOMy3taFlfnL3MIvuCj/zA414d+XJyFl53fgM/JdzhPQd87ZtJJttq53mR6G9k4d8Rs15yeRVRVVmuNqWVp0fwL0yB4yu17dWiOxInwEU74OxHdKZm00OP/qKsJ1KvZzutUCo7WghiVOkmKhfHjVlu2QUDmrVhmT/enbHj7A7PkE3X/y8vqAqmVXwRhbw3T6jA4pJdNrXDYW8d719PCvg6bb18zcRIvg7WhN1hRVVGfJT0Xjg673wZCW/tV+Lxb/nkdRAjT0uoIDaFzXH+WweZWv+uyh06x5f/y1xzpZLKdjhD/hKXSjebqgn13SIV5rHiAu+H6uRGdpN+wYz0if44uuoKJKzfPvvv0FplBPsnKxn2sYVkTtBnk7VNJy6HISgOqSqISZrJhGysN2uJbDHcM3jORL2xu5i/322IysBCGV1fumYFcJbCB4Y8iEpujabTe7SzgoNDH8iWps5I7oNcW9iFHkdhLZX1flazKeUedwcVli56EOYgVYfuS2Fk/AX7Kh+XM456uMqJrtV6d0yA+PVK0Paym9IMHIysXWXCi4FZw9jePGHbKYjb4oAOhgdfcB+qqb3+zWpVVv6Grc7qmZKxFsVozty0+aqkhmiZZ7ADEvfaRBC9vviVbj/SOLFyKxDIYdWavjBsBL8f0f27Ys0xU2ysTPPJRFCZ7MRMfByK7PAvHx+mxqozVDVNoa1P3TrKN2a0Wbmm/T8JesvkYQ4hU7fgGE3iPPqkRoGjg+wM296tn5wPWJ3pmtYAUhaushomS3gutgq4rIijM1tN0fMW2hWV5eSuilxi0hNGbr8pP/MyvoFns2csfmPjT1a7aHVVZZxUHiTUy5xlfSX0k1+NPSsCvWjaUDNW3e3h6sAUTqik+aLCO91M1sTRijSAp5QFgr1tuqcKSGesssWdVTKH3ZmdNeYXIboqRYngT7Gzm67X1jhvQ7S4AxIlzFoAyM0Lmov0F7uzZ2kjrbTCPVAkWCHuJfovBB1aUML3OZiGIhEyeh1IRXPUeXnqAN8b9nHbbnPNXWhc+4n2RnVV62KMm0PKFEQ0cLwv83iv5jrJpZode96m7jrWzGmxtfCAYGjv483PX9LbjXg4Nk6xFA34Mp1Juk1eqs/4hMeiqyTicPUdTYvpQjo+ZIbdRc5GWQkZakf0iUOC2+k5dpUnMiybuYONragkty7JGQO3pnB1wZFklqqWzjFD5a0mWF/ZxPniUqZq2Tw/TEj+MGJ/xhGJP9ZFpD0iB6P+Q+NW/Y7sqY9x2io9R1MzWyFvH0B4lA+eQN7MF39JJqs4SP7JWui1w0VdwkT2BXE9otEKMMQtTejKdia6C7+Ex7VzsZdZ9Wo5LZZD2hGYUoORWrGu1uOhdfxjBCJUOGdbItP4hv2tAxR9I+jVXLk/G0bb1hdJv1pFqm9E/ReXikXI3iz2c8jNWC1dSlBVPNnC2wvnHLZ1zGm+CxQWFCKTLkrrAVRSLnPWsOvRYVA20koWshvwPBz0pmV2x+Mu8FXOcABluAFsLeAjMqIymPee/YPjXRSyTX3Sr6jf7AERpw1zlViRafX+rQV7HZ8jt9tb+Tlbdk8t7sXS3cR3++1YkqEmnftJjipeMVUl3fcHYT8bfTZ0bwNZaaoQG9HHngNDrN7GJEo1eGMtzp+915CY+7FjRbD5cNutYXAqbYQtvresPhCAnMEDM6lmnDIFBcJQp+p4Ap87wdEDbStphIwT3KdQVkjou5vvPfPWE8xDMQzTua1rnwGyPbKfXBrQ5561ZiVEdka2OFUfg9o+kxxny3XyxPSYZtn0bYa+cVX9tKyCajKK4fROf85c9R8m3sZfzsRWlGjYpFJbAU6NqhkCezctbkiymMM6ZNgXTmlDYzoncBHN7Wte/9IAoqZKGbhDRBDxOQ4C8wnCAz5G6h1eZGbDoStWESQtrOCbjO4rl0ukqHkna9DZYEOzbroseE5HpfJTrGQLBEH9aEWjP2EwFlrV9sr6O8NGGGoeypC+tQAqDDvwXOPSdgcGFKt5qCHRYfVoj/TwUJtovL7on9PIXkqEQX9kQYZcirgUueWssNo+EwfvAW+3KqEuH9fD1+dSzcXrMF7eQZJhUbR1HmvYTrQh/GI1wQbDEdiDT7jKCnyKnTMXCR2i5Ip2pqE1AT04kycDktZtZcYzALVMuvtYXz5d9cIhFGBlo6zDoiWwkHwp2dlQ45YSTopVbpCabvHkHUez5JoAHeuGzBn4WJop3YmfSMGehDk09Kt4GblpmeECalaWT5Tp+UDRZSEAYfkxBm6Yw/krvbRiqrQzM336O6JbqjgepbOHgFbP4taQLx9nggSxvswUDGZ/e1H0XF1sKAqvC2gx+DsHrRzSjaXMyTOLOrXJ2aiE/k3LcWnrLIBmdjKAtL3YFP9Xj33pOyVwrvLbihx4t++Lk8TLu2LVHi5Di1x5wMZuUZy4jVUTOGO4v/Hlgo3yUVSDOlsbSucXCB43ymFW3kN0RP8B7XPWEMEC/RpN0DILcAf6N5kjg+94BS0c2anYFmuT0pGF6PFjzBrR6ImSMDOQ4ij2GhTj1GrXg+jaq7CNHDSiPFm5KlsqTqSmHhEgPAzfQHGtA3yG4/l+6rZ6EboFRYIk7M6mWJHM8+AsUiCjsclAPEkymgqgBu3F1H0fWKE+82wmhc36SucX5GdFlcPoS0BIqrXcoIruaxtTphtYfmJYX2beVrjcE5GBN/YwaKxLU3bwRjImHUDs8RZi83gA6zdOwFS0Nt8OemXOuU0lXUsdaOwUtRHA29FpCmWNFBDqcrX1KNKFm/MnlXMeFeunSGBrrSq2L4bD0Laa6IwkhOpkZJ/6qx01VBN5L2MTvLd7v13qbrUYz9XYxOI48qtPM5qas+srAeovl+umEOtELcJ6X7jqWTD9qaJvnsvpS1dKud7lA3Hh9IDgKFidQAWkXVIWWyrQ/8mBkWyjV8aZR1Sk6ioq0yIuECpaFTDgMuqPsYVd6JAbXq0IPqcCyDpscbIQj38a8UN/sgeT6MRU34imB6sgfrfxaMZ0gDYGDOiXmD5ot/R+FK/0GgqVG4rME7QvTL571IDxo6u4K1AoVR/NUnx9WM0tYwK0AisDcFOyLDS0Hd0LSglKUjSnaQWJrDHwV1PMSY0D2KFls/6QqbIrB4eDTe2crjdQq4nWxHu4B2jKunDi2Pf7R5cTSb9IEAF85w4uQPOLHMLxjIJ/W6zr5PagNaTcRIKV67knT77LB1xILfmBbG2oLCX2tmkAgrueOBGrUTXmVt/tWXCyTJIfF9taYRhKWg8ug0qaka6h6CtCJqeL6W07Rm7wd77Gc0UOSiao4VbBykA5jhuguWsZZaMUHxExpWDGu2SllORgTn7HCb5MY3RJrffDviEolq90KacR5EwUw2WPTT0vRbwfdXMrv7LgoV2VJBHtbVGX4HHdDTZXAUQ9gCPYQfk7VI8CQ3Ldyne7DVJDy7qrQpFCMc09aRI4aso5F5g5/BXm6h1X5M+MGhPykz/3jf5NOZH/bVOby3gbIJoe/R/uIpGEsbslVlldIs69CO+S/m6NVFgNfegfRLFrYYSVEcLSRcKEiElFUH+wn62F74o261XwUpobD3N9dRxpLB2lU8RAyYYS7kuy1WXnk+rru+Dk8MhqPUJ8PuSVxQIMkXPY5S3C9avMY08PT+DTgLlez2V2KsYnjnWa2s04ta6xzUkz7u0j8d6pr1ZELPyC8Ajhil6/ZI2tn1M74vV83CEihv1E/2HR7ohOjijOGX8HzBj28zOkCuh9nqZ3w04Ch3PGzbI1URC7L01RGur48xbmSNzFOPBcKs+g8UaL8KqdMbkpCvCM9nVzimSyudDxCYEae+16KOgnHlaAnJAPZNs0G1jLVnt6j21flVdM0o7/ty6FIflry/9WNit7sgvGtMZKEe+iC0nhdMvyAhcx97rkQFV5WlZ5ytiPYAEVXvbkzWIT0qJd/OAbFpyTWkfg48FlIrs79QXYF0gHnzH35r2HBiqQI9oMg/SkazMZ+5DOKZ/EbNspVT6j3MFWpJSSNT/OSPDVzFHprphLgSffX5S++pTxgHGsPzdpFSFKUs8fPfT4+tVL9iqX51O/px6XYK/6obTojz7w43VNcrW9xoQG/WtDRl9U8yhjx/xAGTPliMRiVYzanVmIiVEXPc/hhFQgVwNboSIqrGSjEimFMlEzKChC1GRXh+lmFpeAE8PiG8DXxqvM7mPmeCkaK1l4tY6ivjjUmB+1OcRqRBv1NVUoPbMm9NWKZSDgM+4rMZZfvcoGB2CYDNzFcSXgwBV8F2flZ3C8X0EehwpZZIXnIk+4pvfV5b3KqV0v/j5IGbbQzw3eCHTctjQI1m3CWPIFTnKGeKyxjXK3QiWIcBu7/wOER8arL8aSSRIEkLnkCoN912U9yKsmKwyEEKJ7Z4Io5srmpwLy5ZnSCwI+kOApIcITd9+gnWppwKEfPZVPU7McER/TXcmKP4L1bGfDpeoQOEhwZbkB69Fq4SWr9TOfYxbFRqo508RVMgiNHiB3txIzcT/tBeG5luquQML7yKtzlGZYKYqPeOY0MnFUS9NGVjgilhGx6Pp6ajkoMqD05wYy/8NoMoJlz61OqlJGxkY76bdszhVYFVd0G5jGo/g44ZK3HSXeEg418Ljl6KIaM7kzWKsxWoTCV0rdTSBHYdrAXQ2lXRJ+9RyVDIq//f40E/Ul7OEPe0eRPprVf5pwClaV+OauacDFj30r+qV2yH6MMei8nP/nMLlsK4svXAW1pk4mkM6xzPNtQup+nvCvSfmVgJse7fNWp2HW/gI0kvguNEl86fIcQ3FNl20LjZfcq2VtOVxL7vQoAKWZ8HY9PwwhWd3nv4ZDySq/ArUxhWIi9doZAt6QEUPo2VNey7yJxSCNcJAV2LLTd6+6yI8QpsD+9SLfASH4uWSEBAl2BeWSOPnOeME0Vp1l1gEii34/Wx8ere0oGJ0U4ERHsuC6RjffSoVg7z5Zw3hJq8Rn1NaCpcJLNNORAlbf+1lTL/CVn07Zr1o5dqMT17iOE161KMef6J5+qiDBS9xAEGVujxqDf5TyVtiXQcAXqNx5ppSo+orWdkeLI4dNwGvvvVXJoAvtVEYmAEjlVzodbUeuG6i4K2FmuzwdPtK/ELiqyIEoOcLi/brVvyGyejNOotCg6QHbL3eQOkmefob4bEwZYSYCCayXjuNzad62yRDgxCyOYa83Qwuu9TCE6vy2eNUKnzpVgKNMOnnBz24TTrDV4jherhx8b53NzDxVqDLMsw7NgtXcpVdX/vrcpRZ12X2CvaJi3yJ2EWab5rsCDYOv/B2KbaCM65m32ebOPhDCInRJ4Gr6aIx98f/Lt7uRMWFauM7mnJvCT0X4IvAoNySxqzmOd7vB+bMcNKQB0oQy9qtELficaYI/OIE7aa/graLkSD/+e1xUKrU4HOcb7rAdC1Obn6RaPUaeBkK4U8hoPhG8THVYjjqHZ+kg1wbJuruOk0hHltK26LlLn5T/lJEOS8jvusmLgd6WKxDXDxc12brk4+fVIHgQIvGehpZ1TsRDOhlR7oAKCz/cmDkMFFUxQOuoyqnuB576vcFLs0Qtle5PuRkoU/Z7phpHjKf4XFUeYRBRAMnV8c0jb+DvY0aLdGxN+8VRIvWrgozm7M9IQWJutTNbkdkSNTt2k/M9r7cXfIvD8mXdRT4CB1txPSeumsh/OJ/gTIE0jKJptNWpOPFfAGP3CEqOv+nn9z9PdL3/b864nVxzO3UsyVw0xpMdbI2pyQLYPilG+jB47nuoHXbPf6uCxpnhw3jX/okJrldnqPcdlOPcXeQ25COl0qFF00iv00sbQ4oOpn7O1qZ/Wzxx + +written = 8192 + + +$rawEnc = 8qBRm/MxQrRBbkF27qHgF5TfX+22Q9LmJqs25zI1ywAZk+UCPa3dNkcLpU6YQAkayLtpWi0Z3SETQv+RawwEhT0I7oj0zUXpRuRn1kZ8YZSUwmgEwZHR90twbhFMbkpMpwF6Hx/GoOMrG6TU8HbGjXi6hAEmU8vD1RRf8ksBSxeSQqhgCpQmzoH7gG/zeLQIhsLoB+lo0OZVJDWcadamt5j8/y3pI8Yyxv14GbVZsDQ9DL8fDCAb9VSnpH7Sv7S/75flG6JONlW/c/GZn4yNTIZ8yUfwvQFwqQCSAO497GvQkicKfqIj4+pO642Eru6XAUXTSiUquOKsVGg8oaCpTvXSda+ot72UIVbBJUTlX3ARbfNbJdeiSOmKwwrwbh34bMuZXaJa7nHPiI9YyMwCH7KC4bZhEcUnXNZEd7LBUuI7tDZxVYkZxsVdAZjGJLGYO8umCxUTMqsvEjaWtaEY38Noj/rgNAe9htELuNG/0q8dTMcImYuyQ5kYiEzRzaEsK1K3wLajSAY2nEt1JtGdiIrD+xzy/CP9N0JInwoLRlbCEQ/Ik3bbxA5lwnNjln+kIMDe+uXeWqFFUhOnu/ZNnam3uwPMEClmiV+knzB/MSAtw8zeyH1ousRZNy+cgwvs9vyFJammSCsFfLGAHjpdPKmeK5bLwR06QMLPQB4bixVda9odYj6G6Bp7WFIUyaiwf68RN8hTKnXhRaZWGP+cv1jn0j0a3VHIzIRqHqxB4xJNta8E4fXTesSwU2zTfa5T4IJDJhsF6mPZ8WqospxIRC/gK2LQon3frfgXTqz36lcuoYNZ4LssOT2cdYIEi2vcCJokb4Ae+teI5sEZxlKYxbfgktI0usCTeru5nFRjIGTZldS61h1+/jhBwV0yWGIYPT3K2mw6tnDZAU9bQDX2OtsValBRXNXxGjuvuNPO69vy8mI5Ed6/Oln+NwHhmW2RSNfZEOqL5QRwiiqXqw+p1yZ3CgJr5Uwx8OSExedhPtINgRagygM/xxXi/amhnPxJsk/gbtx6zEAf/adKlF6PjEchOsYeBgo/vhY1Ycuo7l+e2/HNHo+wO+RlRt1AaSzZfIMOQv72gMsXhQIser05SGCS6OAEwJjsyfUFYxqWldOUP+v/q3raKX/elDHjuPQHsQRX1n88fPqmx89N3wsirwHgefPX4Ah+85FvwS+tqr2kugVsmkkxGwvBXCW6tK0GV8T3BGBUYRG0wEgg8sOUhmxoDFHRnCw7IlCjRW/4m03hg0HY6fGo4JcV79Yq87VEFgAQmMkubop2zrwrdK7FE5ugvZgzqkUKZqgTqs62q/BQJjZwcUf80OF2GEDu9FeE9P7aD3ugb/1U0diC5QO6y8U7ywIfc6kwfqLIZ4Uwqlvawp2XV4qV2bx0cLiGjk96HyG7YLyIi0xGuCZbzRqDzefze4rDDsRH0fCx0Et/2KMdFA8V03V/sT6nDtaA1pf3bioxJ2w3xMNUEQI3vX06JlxJO2J3ZF4bLe2284FE/DZUl1NP5i9JHbExkWGrHEYUOe19JGd9ayHk9WmNudNoizZtqdjcKtyAEGDFXdaTy3GaW1NDQTnbdVA2Ih/WkRR4LLvyRp9IHSsm/9s6j+vnrPXaaqEoTwba6rRmgQaaBzjzkGbWJ1w0DbNU1c5tS+rlS/xmRDQFwQaFnWpr0CqrGV5pYLKa0Q4uHB2FuDJ/cKlSacv2P0WmWlWEwml7FKQVLi+nxysh5Banf4EJlOlerqZRao1vmr7QMJL0hA2WNFDOHISiJTMSbOsskVrd4144OJ6kEOh6xMUV0mZKVG+Zh1VS5YvIH9gDrB3tIuE9MxgpQvxzt2tq00TnsIPqICSB3lptwFow6Vg+iYscqpYHcZRzCZ99cm9ejYqgDxmodb3zy/H8TsQSPQBDsyI8XvN8kyo06ePX/iM4TQ6SjdskTh2J+lqK1l4gvgL3RQ05Cz3Z4+LMTG4v5T6VdBIYKGKIErVXF8OWl7SY40XSSiy6SI2mA+j/iGdNhdR8UyT28e6RNVqzvcAdRZqcsTK9xTlzkXtSNVm71bbibeRcTzJT6J+G721Nnq8J9VO8jxvTNIIxBn+R9zbPTfB0iCn+heu8qgOk2NVpU6Gmi9gdwhI4DDLfe9BLc5H6laPd1q8YE3j8+pfR/gCQUfst347/Bh22eGTbxP8cI2HdXCw2xKzXnyTrKj76ldFQxKX6dPMm7madCkWKxgVypzT0l4fZLaMxUOK/BczXOt2iLLdIZ52sX896Sd/Ngq4vPQu+EeRNlWLy23A5ldwbx8I8DZpm8/u3qdHCXHPyKMwNXK1dO1W0ycKC/poizoNADnKm9Bt6InJ7tex1mc5H0WKgqtRkl9bagQQp0kBsLdwOYYq6gU+dw/JQDw3B8nYQWz39k+HWZKAJc0GlYihKhFOkiBO77EG2gyS5kX73Uzq6l/xMpCTnbS8vhVjTiL6NbyVLy6t4WLyPk69BaR0H9xLXtVxx02YYog2SJPtdw2hdn0qIvhCJWRu10jJiPZVe+9qDZma7fZteCXomqtG1XcJv0shCBttuRdJzBwk8bzwOqENoDZnBctaTalv+28wHAglFPWvsQs/fpVchy3qIFFonbUo91GmPH6Oj74PVoJc0D1IsVDc0a68zFEKcqFZrlKHScm52iwTAm+cs7Eevb/d1cEJqDlq1WYtVl1ViNUGScuHGJBYv5swyEIper3VqpccNiZKeR296hTtOA2K5PP/COqdij7LNgzG17dML6Kf/9mJrwiG/fVScCw+iIu1tKGZ3msqyXTFwq78MBk1gc38V6EkUE1xD3Gv8Nki2w0/ITNzpwPThykJCB5Kn9LyH1WXlzuvEK7+/arpnNDh45ZB93KddERuY97N5oEt09hJ/klMy3EKm0zXpXrewE7I+fQBmm+4MKzuDm+n5js1O5DhZ44We4Qy8+ZkdTfMkl9ylC4/QsNYMjH0lrWQl04tCc7UpENOq3hkdQGCXLM/BFBdPQWaGG/nOoVvQi1oS45+KS9h7bkg3ten3k/TjLVtXHWUX/rttMsir9zWuUsq5r29MTMirqvSDLI5aXfGgZQW4oDdaZV4dS/+/+aVD/62FVKda05yZoeNYxm5cj9ZOAy6x5WEMYMzc0VP95izlutbI/dp73c/k9ifStt/dWLOh5nBE9HEnlbKXMDwPyhVLUz3QXtGphJHIuzYeYk8vtrTbHEIUhwQOe+iikQ/Z8q9IWS+O5cN2qbPonSm30dZhqQXicuQFa062LTjfz9KiJ7qKdggZSEcXa6caXX1uoUm0ow3JzAQbdcy0s1L0wGHuvubBOpiDMm0SLas1A0a/2TeBki49GD3/Ft56sMU5AaTlbI4BdpRE6Z+i34MAeWCy3cAgtrdiHVGODvjHGyxhAwWimcaujyTipRESBxquVmPHwrCL8hICB0YOhFsLIgPRpxkO0YtKUT1/gqQuzVNVxkyhXwUO46KWz44vr1u50abMlMDzBdz18CvOv+pL5v+cEgyqsEyqJEYhZH11c1RotmoCR53U4+0YL1PmoSC/4GrBb2HMl3DPT5axF3zIfqTEdRv/iFKzd9R7R0MgHJqmyM8n8Ut0szPpCFa9UW75LBsiLen4OruzMSDa3mhCs0nDqiIEtv++LlKlK8TlHdNc1OJ8BtQo2n/gyVfoAFsamcgXOK6PoRV+KMQdrlGsl7nUrXwu/1GuVEfqhVJWImEriC+PLFQM3ine7Yq+MtwMHY0EGF3MZ9uPvm4+PPlTHFjQscHtIvnrewFYJkc0DyYJh97EhewS2ULlJ40rgRLs+eN7Ym9/X5SMn/96kSlUDiqIEtf+L1HJlzwYmYCI97SP6aRZUW97wzOwMSc4I1fgtzZ3sa0d8utQQsACoDoue0cc5vfzMcJL10R4LtN1KcRAbGZ1uTtwdJ6zbvrwcafnmYeUR1smEQ1Eq3BhhBuj2MdLKRKwysqM2j+XCBf4Iaf2zFxCKUnbhQNMaEzHRocu2B0hUFRHJgnldWpb0AWQTSsdHNAEc7ZQg9zOTfeaHq8qD4TMTU4yNUBkXI8ICr9oiNYKsQrEQ8zZN4mKXyQwCJOW7EKYqj8jDDmbO1q6DLVEfVuzovbjw5wR8UhSfCIO/vm1llq/B8XiKwqbbKjIJ0Bm9lMpA6Lk8Td8ws97d/IKDK+qBLo6WpHoPQ0Wb9BJQWDd4eD+YKhChlH/o3LRTMnYvvDUs9U/DKjE8mQ0pafK9XW2207A8qO5FgexoFExCipWhtm7VLTr96cJz0Fp3rFVw2ZALKAOEWSpn87k78ag5e9pT9DQ6KeWSJRNFNEVQLYF0/WXQsCe5AGSUjtknCLiZnoaYR15xWsv2jMo+9hZdcmuC8Z3zUe3eU0pgWuciHaT42S/Etc+BxFEOMw8LOEZ8Juz27HYuemrABq4QluInLkNC41Jt/eOBvjR5Rh6oyBWEi2WfTLd6JoT8eWtriON7hTmLBzG9JanWdUXpghonEBSmoHmhhm2D10Rrsb21pq5AGMiKsSDM1kd0e1q7E6gn0o4IYy693y0NDvmQF2qPyGSzAa3Jqb8qYSC65faZzZfld6nlXUSF9oqW6CWSRwKyMWMxLDTobqIPRch/iVThXT/ge2qbSj1w8UjUSJCyu9jaQo1y3UzVm9rTH4KRdfgqO7HpRk7xQeEZ5jZ/aU/oDyioV+ZsYFEub62Sq6/SADwX+rvnC5CgG4R283TBCN4yFjVbIsJLwkRdzJxfbf3K0+7ADfBoI73K9vlLYk169cWtzWAW14GZ+6e17plMAIumH4nYES6DzPFNHT1LLVq1Nm2cD/oiXra8IPyrbQKzB43uu3r1arwF/apRmVgl1Dlu57UGVpJWXEvxDJr6oltqlYFBMggXMzX9TZ5YVo2ieuqrAs3dXHdns4etEGRfxLAC2Af9ZekY73E/j9qNTSY9biZJdFKhWye6fwCQUsxEggL3pBLXm3/FDRfSECPUNi1fkmVo7tZeIrXgE2qRMAupQlktmQ2pFsp7mygjvFRFUh6Lk/BT9QZ7blBbIr/aquPNg/EVE7xJ86EMLzvPSCm4k84GvLwaFitIZYi7veWN885KU2c7cRvtjDKXu0Uwd+aoUdjsL5O4bGOfyYIoezKI4UeYBnAGSPPgx9hUikNlGxlY+LBjX9reczhpDhVn5eH4vmPGnK3DTpyx1nT366qoVpspTik7RWPTu41fA9JSPP+CHLSobK14JYOVf7h8Boj389CGzL+oMyPgnoWOVVrdPKxRIbQ+sBNiKfkpl+rzo7uJQGgMyeLkvT8MeQu4fZDvnb42x0XfIGAr99eo/fxRIARcySpJM+cteiyT1H6/nUJxCRM9AD7w5zgJHtxbgwbXKWyA9/gaTk3yTcCmPM9eoszPnVYAmiSlxNWknDhluCQRS16nc6NOjvyC83QOqbQ9CxH+9Q1NZWYrZIIfbXjDvxfwHUQpnw20+g1FSwCj8Ws5YFE50iq8niRqHT3Zyn2I8SCf1M8Wj0qB3zkwkApzC6qH4z5DOMAzA7zNv5eoeYFusNlZ9sgAUsq7T57YvYes294koUX0VwzA0O8/0CRSVNyjErMvs3NEXff7OcgcxiH+F1nzshEynmhTTwbg40vTh+PFcNA+ofLCMze/W99mHqRzzfmgxdzh7LZjT41MUwPCUvU5vzdKbLRtA6D5o0O1kgQRNP0i0ixjJRC8XooCdpCtdSfbg5JfjBDCzdL41m61jvcVlFWIATx9BvTaAk7HoFDL3eD3Mfr4KR8GeOPp6HgbuD2WAroQb6NvqudjhUOQr8FaYySBYtfvjEBFPjXf2OLfyGhwvGCEZdIkqd1Q5YrJA9pM3ZyW8LomIzXNw5JFS+BxrS2GKcBeK2RLC1BqM6D8BLQCgiY05xc/pyzhbOGNagwlUPyWEHi22/7EW2P+XS3oyISxIj8UMX5DGcTmbYOq1K173z/TMpsOPSdZ7FDOyD3oTZGQzZig6L41/cGPIMHmeDeKuvyaNJ/AcwBejBbF5/GfKFJMUWD/N6MyphnCCPcTuBuIVay/aUgc9WgSmnH2jLWNZM4w5+p6GUdTN6PtXh6PArFOVHfN3uNRA5mnIFkuomenw/cbDRiYeMxBwN+JQ3MjhIO78jkaj8kIjG/F03Pp58oaLzzDGmNpUhNGl3x6dYMSDibLIHPoOp6DJKzuqmeP1lMXcpSkz/62mNXtysKkD3Wv+1t/IHreswW3IPsh8iGWsz6TvH5YrFJHeO6ZdgYH00i/l2Z3EkHJjgl7P1SygVxmQFF+82YgNWtG5RPu7IFvhpj0Tk0E7HwuPByqYrOR0FOzjg2zWQMkPUnurCtx4Wl9OknkwIwnGkqAUBjNo5KeCmBpOOdzstdIvAObuMCPXXl4mtKKk8ZcMiRNQp0VXfQIyoFc70bMgM5lD/7i40NPt9qc9voja0IVIkPqktwsSac/kx72gXFKLDnzxgHP2ZpIif8qSz1qZJAyKEhpiUcvlS3SR7YEeHQ1Ia+rmQTN3FIerN9NlGRli+9m2lS130aq5gw/Iw7FdYdsXZSHNe+YFrXXamOS5flx2x1ZwimfYp96BxuBdKdSUdp0Sj3fFJV82Up3gGmxfDn1QHbaNBe/rZZjUqZpGcAkZE4Jhkk73JELGNJbXysysrhEeQBzkOVEJH9PXD42Ww03aK31ipiEq26K4mQyPwTBDjtpj+69amPwkUwWjK5DLvxoQ9v+r8oxq7/K6O78dVxcAXdG3HfmSjZ3Sjz+18CDeLrdQg+na4hp22mshQGqv1XXVqPzkj5ceEj/EQMojr4dgdVtXoTnODuiUTUXJRyDa2Lh/h69aZcd0nKUI8eXyl0zz5TAyseTEm1BZ+9z6CUnhCUFzVPOAav+DPY+xeciUgFybBzsHvci+lK2af2Mn/CBepTGJLnM8Y3bQgseL3gmoNJXFaoKGnaKqpwgRxWfgQ3YDauk8UiwyEXNfnGYAlHPvC6oaiYdjbRU3M5G3euzXX8f1mF4UhHdlwVt4kEsLjXoqdbmTYQcuXT5JI0NCwJDeRqLXwePJKcRPDqr0Zu1SDbGKxBrbZjW/qYDN6y3WjpZyC8X2hJyv/gGQzitd0NXcG5kKTjMTkNoOLcBbnoWN9NzsLeC8RTHO0KJwFxgYP5ofbgcClPohRKBmtkSDixjS3mr8IuFWJqLCKz/WS8aaMyKx0/ov1Mp7B/DnoI730uSnshp31XRuPHXCq57I84lvXi2Unoh894lJc3V63g9S/guN99bOyQ0qzmuDQr+gGLEnKpuQpyzrmYjPBkRjUy28qi4Pgti9qegkDghNN+E61zoLDVQIUFfqiczf25bzkucPIxJQAAIVBfUrsJc5cbP+v+waFFsNshSwg8hihQHsfy7yBcPYP+7w2KybF/RxajcxL8STCo+VR4PcS9CaN07NqrLOaiSUDiLN7YjKIc2N4saOF6WGmCm7wc3JTTbDuJe6/72bLzih+ruZFpR3Yp46bayWKEbVw9PVHvhIHycFJoBI7mPU7IL0DESuOp1iFevdNI96ExlvIUkWtbT+vsM6bX8pRGGAoV2TsdvArUcZSjluNLg4ZT9wA3p5VaHHhu1JJmS+CCjlO14AnerRZpxdjOGg4SA6/Ncl+fmB/QqxQ7jdENn1FKGAIOj5vMK4Az+3azOrsKtS2EvTpsq9sNP1R84+7kdnu6JlEWqRbp2Vo/26+dJ0t7h8lgHsYDy+zp7nwdWDs5zZABq0jrJfylgDxr7gZ5KgRtjWhznYkcMhkLn7VL+xtyayZSfg7v0dnU5XRQsvAnj0pP+opBNiCk7WY+FBODjDT6DJgoElZY1BKOdXsu0sWaVfo/grHS5IDGQZt53/jDQajA0e653ZNjEx3Hc9+j1OO8ed6jQ9TMBDg/zm1G591u5uJQNwb75u/DjqCoxTRBmYSqp+8Lf30IN4Ph698sURfmKey0LBRqf4S6Gq40mUi90ApJTEFgxAeOj/mXbPci4siutXMtSUcpd4CNeoUGd4cLo63PFvUou7SkAJ0QQvPF2hdVb5jtviMxxA+QPtlmHz1/LH4f8VpWkfnBn7I46CxtXa4lMx5EMoQUrp9rufKDyjLVXSgZdLEy7C2XWDOGZrQYaGAs0nylRDfosfBH9KvtCJ/m7sVzzjGjXH877VtxSu9iUtbL14TJUnpF00iv00nIRclAfQYB7zKU8mxx + +written = 8192 +$this->size = 24576 + + + +$rawLength = 2954 +$pointer = 32768 + + +cache + data length = 3026 +$this->size = 35722 + +Array +( + [0] => vvJDGVEuiBSfz3hlAO9STgjDCfC2V37mtgL7SxLaTRoJLn6Qrb+TtPuwhUhle5rdd92N8thaiUq/9wrxkiyJ+JoDPsyLJ5xLZ1nsXkpHVaFj8sl9B1jm+7LoteXFk/4lVHVa8vLPFnTXaLhf+JWphJSxLlSatQMp8Zio0nV5oH73P2PhUdT2BFDrBy39ekGVZuuiTqGHySjK2xdhTUfNsBWp+PkQMIpAsYvz4mCdwJ3V20DRra467ghp0ZOVlRG9iXNEkTukHbQQtOA9xdnFCBuo1xV/xcjBdZIdBcKmzX5NUrGwVoHTkUnc1cvl0kkjcmHOaQ4nI0jZDthsaANio4plzwxLlygezgPjfC3z6sLIzev+vG90Yh/P8657imjsn4wNjHq6sEsEv9WEzfkV2IX32KHkXmdrkYuRU3qzprs8vbmYnL4/0axRzglzpcZN2/oE2xgji6mlyeq0O3QbDpsJJzv7qHBPtRdzizeuBwEhO6q0KgT7ztk+YncC1O0Eje8r+aXxY7lYsUHclxsfoy6m7EPfiPyOqw15ltosxeev6euZbr3WXcO6YxpZQFUEgYKzB+WtfpGKPqOLxRA9mr4aocjBPpGXXgJkNHJhvZ0RCNchVkVcD6Rs7DK+JuUx+8M24klscMSW/3lOWJQkJY/s6mOUvMWncEhNH5IFIiZPX/D6Gv0nlRIqj9yTLySWBA10+i6TvhDfOjX6m7QAtI4VgYtvYlHlP+q15Q64ZjXIjbqVJ99oVHpk0siASPHmcHUgBxhzeCznLwA+yFZniwivWBnj+zCqTqpwY+UNr5+3IlPnxDmjhEJm4Dt0wH6iqr/TqbNSP+cAW2oyywp0q0nO5UlwkPUoqb4j0R+iwzcR+P55UKmKpSJcXa6rDqxLro67kXe6A+NE9JGN05HfBaxAZOfXNakodL7D2qyQJjVFLZkrpdWrozVVraIjoCPJN70DyMfSD3cmkcOKYq6kzgeOL4ERzROk2D1tShVJli1HNcRuiU99t7Y8MrfLz59upnhUhxIrkeGQo2ubfio5Q0rrF9h/T6zS4khM6jB17XN/bc8micqefZURlKJYXzt1CwGtyCAZI+eloua3XRhy+IbFZG8QkgVmFQg/kmJ2ox3jlqTTtMuYXcAxWq2kqAstW/wjfCcz1+FRsK19IdAleWGB1wnZ61zKmop46F6fRmnR/uZkXu5JWPqeX7lJQEQ4/VT+g1S7W8A8JP8FxALXP3DIug7NfiCVUSBMP8pEiyTs29v03lKdYth4clWwbsI2/SOSgl7ownDNCdo0z72jfcLK8423k48HJvAYvGsN2rd2UK/SEGYPyiYX8oVuBCAiQg5+bOiGZqsqkFgdztJlVddXsBvjlD7Gkh2H+E8+gZVsdsgjJKsBuOTzMqS+6jqhFG9MUQl8fCo4oOU/RP52xs+t5eo+eoOV4A/RbOvJ9Pbhc8rxiPl9BaKWjV3Gg0NjqJtpu0CFbFg8pd5iD0o3rPnzKaTPfmcys1pwdxTfeNevxxIjM+CS0pAQY1Ep7kxk+T1LjXyj0jC2kNnylmnANmyO0juYXuR+20YA/huVBcKbfe8yBrrHb/8lg8GwwqCrBiwmZvCmahISRzl89bsqZJzTtwUJPa3Rkdh1PPg8hoBxkttT2kORSsfpUaGXu7FyIrR0QuTO6VQjyf9RNWyBbzFykSNmjkQauSyinKKWwsat+q6VVDHdD7ulFo0MAMpyFLbmKc+q0iyZsqSiwxfC6FWsdZ+e5ZqvZv8OHeERNk8BAOzKAYSWVrmBHWAdGTORK5QegDIbqFP38M4RpI+tuMOMxG5rKKRrq36n4ypRfOJ2tvzv5rcs+lQfzNvwYbtKrMFPbyaHN/eMwIrJSWXXd9YFYjeXyYTEVd+8iEo+DKt4JidqWl8cjA29vB/VeDMdBcxgVy2cygJ9MbuwU2J33Io6E6CLRphN2GPgWZG12hjG9veNdQAqa08OD47sjntrf+I18fwqQmNJCwwpdyC5fgcDXKYRS4EbDUmBM34iHPBuTTbJW943EloETNOM33Y+mkQnj49ag/Lm6oPTP+5Ze4vXBhVSzYXpl+lljpNdv5b3UKdkiE4qFsNqzf5HqHExUo+CzNYNRJssTPlLMYEGF+auNIcmMZcNW/qxRk8263OZngoMqldzIUV/PL/6flgt8gnnZsLQouvY8aUYOU/rwxD2dlgRcYhpyFtEsRtp0siPYQdIrswz245zPDJJSIU3CFu7gJfgI8SV45+dhQplK+SdZypK+QrjAh8R8jCZJizcyi9lQcnR8FQTGlJ5e9fTsBscrGkbQl0Li2MYunEOG1FFX2r6YIP3uf/2pcIbSZ6XdV9NHfK9sDSf5YaUrtdNfvuWcI/kiGmXkSr8/YMTm702rcHdY/NDL8/GlNsB5wMHpYPL3IMxFWF/tLjYDpFc/+cEmBRYpJ4px2fG9DI1lmirHDFcBv3oE94DdnK353ndG6tBYVS92g9gsis2jvOSRxwn0PbdE8YqOi8Ab9HEnmMgmEr0FNqRREOwqy9tUyCR209adTp7BkcH5CyxZNaAR4oZKuzT0Ol7nqVGhsAStwTZjn3Lfri9UCDxgL6xgrOSKe58R5qzm8CT0rptDxswEATfe5Rcibx8N9DcvbGF3ynYu0bMQbqqY+c40LFW55EpUqbqgmzf09VtxbLwxaHUkSXUd3Oji9jbBmksYNRfCNVrXdBhXDPVTl0yC14ByME7CqvR38ax8zmSBfMps90qMndnKp7L/cGBztqfopfqAz6hasqP07RyEpUPNp2wFxYqAYbTIf1NEsctvudXb4eAs1hNkWuYEbSjAzf08tQKSPuai5K72CKlfDZTp/9k1/fNBZKWIDsrzvK92kfOiSektm4SJ3+8G4cuLWU7iIx0CInq/x5gpcXPXN6OpjEXXP7yAsvbiPHE6/X0M7ygCq7lh7iU/bL1rM/6GGkwJho58PqRqcm8XavFkEOrOgVSu38+UHXOZOLqgnREAnxDsFJor8nN005RexzCgsHF1ejSBDAOPPuLRCLaJ00MAMxMxMPK5iG2I9KxCX1R/l5G/d0qdn+JrTylwnH8sjmv6D1CBSWsnN4St1bZfny6cnD/t9jCsNYtCJ+AIO1X1vhAX0whqn5ZNoOTsT9uMqczOdfp+M0miT+LeAU9ff/2yoyWywCUxnmJAN7acD4eErhXoz1FEDplRGZ0JlrXWJXvhIzRb8M4KZrzvIbYKBFTyjpL6/wa9A1dNTKiFr+24lrrKCuO7HnWxShc27hbrZZPDQfq62WzGjW2SM1M28XIOAnMrQotS03D4ee541IPRBmQAM6dkTxg/s7gLaPedbvLB7C8XBVOKoY0M9oziiFwtniQ4MsN1b2NpEZnuvZBUvUBzGlFQdtIVJoeikhPV4uaHFNKV0Wa4FnzgwtYk0gFStTDHv4twq1N2as/ypRjzNxeG1YgcJsnDvB4SCz5yXuJCEBpWRp3anV5jEJq8jtvUqCJVz2ZoeSN2QVHz6cnxuDZrS/+AI9X4JH65WGkBJ92xcM2oP2HwLYBo3YqIfuU841gwDF1qGhRyz6yAlv0OJZZBZLDaVeVx8Ehnflus+ximDxoWddsACMaIQZvNpCBM5pJAVMF4Y2TXbj93Y3OJJHBOlgQSLtyIoQzctpS9vTUvRyukulnnzKbVL+u9AiHGlTsiT1JmqQDodRGWZ/amqVjCucK7zqbhPkxTqTUPD/PMasu624ovUL6j8nE2i9389QBv5BvAt1Rxymd9/GJYwqZf/FEvEUNjU/40a0W6JT1fjvT6fhpNUGD5eF7iRfhUPXqTC+zzo3v1xQUxCCF/fLl99gBsTW5JXTdc1h+63dT/91RM6zD2upmYvIm6OC/Zi5a+2nLk8qFk6ckPPaBef6RFCSiXB71U2p2mbTelHwcGuOR6Pxp/xi51G1WjFYM6ZoGWM1lq8u1o2xZ9HmpNAUK5SwhssNOPMBGWMU1gtNGjbb2jL5XD1nnPeNdHH9WR9MrBZFSjJw6PEIhEPJ7FmiwnJLNc6PavCoqW7yrrsJNDBfaeip5YmGaJ6C1k2A1rcAsWo4G6kehkpb7n67mu0uHkk9UBUPVs7uuHHq5ofQXCiWKh6NBZJ/1TdveiwCgJYpSatWtQIYyAwulcmDIyseeZLTNXVmwZfv+TwFwpfI84A/w0sLXgtBoh27YlpP3knnIEmRYFh/7OslM7xqM/KqC5oP2OQa17Ll+fL41FdzNScHWtdKxts4H/6eUBNjDsA7HFeK9TyV71lubMO5Cqui+/c/1oobEqic2NlgQmE0li4aSTziCtoTBWe+cikzd/aiAptsbJ33I3ufboKhUROxQhuJqNFcPOe/sHXb0qAJRhqkhExbki7nnx4fC1kpYpNoxBxgPZURyA7wndHzFzGsRtUM29dqOoQOdN/wG2NLQ1KEDhocJDl7qelBKgnirNyz6XOe8iq5oahYOD0/3Qbi4EXu7bvh5gvWilIy+cSRfEBJSLhY7hLni6a+VyJIlJasjly5bd+DEQ/69bQBKo3zEEBXIPVbkBJ3LxRgTKZZGHuXxM5fnJNLz3zu2wVOaCCm/eYfpmKXKEQOoDgwZu8gAcLrLm7Sav3F6t3qPNPZWYctb8hwiawvt18iHzplWfwRA6ac19Qyr8gBOBXJz9nVtNvp82PhW33YplfAxjTKKsM53eZd/aVCuL3tBxW75oLfurucnzhacIEfPuoWW6du0M3Gl1wVJUXqWLhNa/xyIOkB7viFeYTeSfLde6bQ/Vp9pn0GgAyyqtdNAfMcw+8844V0w7x18Cx9K3XPpvVnNobhJnwlURpW/yRR9UVBcaDfMeqwAqsGVENFj3FpeRyCQ1KLI1PGDf2FAGXJ9dZ/LimyLtZt+fp9Sk5NPvK66oryeW70vuiVyMnXKx6tcZFVW5eFKsqQ5ZrKNXRir7vN4mZPFEpUJBtIVN37rLM+xNmthGE0a4P8am8CO36tEBrBclgju1JmGG6khxpRR7kN337Sr9LnZ3cZOffXXgrqd8AeqzJ/DMc6p2ekJg9ehJOw6UogOfG4UDtZjppRgoQNZzGNnhVBsBSwlcRgyM4qMUmZw4qifXTBtOZpiu+1/gK6sYuZtImOJkP8GYm9EIpLs7V3uCjKJmfLtBldLJ+1Y8DOEbl+kBYEXXLvkDUoopSbOgS01I8AO8+VYUmYjfSCkyBD1XKTHoopdhlhQJ+7g1JmuDyEV9ucFjgHkVkMAJeomhAmmj7sBcoBV3dcMwJdpHBXTeKUBkGoHjsjvsERqzTcKcEKXNxetTD9zZWEFogayBAPhD08xh7O1HfF1h9tXOnB/qV7h9ua+PH1vTu0/AjVrtfreh6Ax2sCMQKcwBn6CdQDwI5UJmfkWG/DcMIbHdgm8XdSJPgRm6DUv1F7M+sJ0wbaSpeYtHkAIGkTGaU9Y4i0w/Ei9O+308KZ4+M+jbsFw9RW7SsQonWwM0AsTJjZZ9RlwTSV+JmU0lCgDwLbjG/joPXguoXP3p9aNhBYdcl8/Nd3PXf8aYUSMCQdmrt96I10iC7lZX1rs8Ly9eXW5WkV64bVdv4x/nVu6rrZJAZ07IcJ+UBFoxCHyDUNAubaxPG10R2GHtbzoEhv7+p/8Q6S3g4rmWOTKUyogSS9IUFvsltVIjiKTMcYpkuvY3j7HOyfE8tPFUUZZt3yi8QWDUmFLDAOe3BgAj8z1vtupjMWEFvEQFNZfWJ15OuzQ4GdtH4aeVZxsx5RCy6hEQlJA94xsD+e0dmmbwiDZCDqtgMeyg6tclkIKCOTznrEqgFSE8Ty2K/+w+bUIDbqPkkxUX9Z+4dJ0ItougSwzWYdmovs7QSVV2F4L9xKeWVmzKRTZ4yV/23MRH/2GwCOrb1qLFifJj2EPJugO3xiZ7V5wCYdo+c8Wj282EfHMxlPbJ++z4DR/IWM2P2u8OhJZ5jwP/j/m32MiHkT2SDte7/jWfmisCDUzJEDu4H+zjscfPJiGsUJBt8BYNdy7kqNv0rGF+PBArxFfuRXWyRagHeLUuMD6sOoJbPsIK2elMmRyFWy1dwtMyccWLX4Enb7V1AjpJGXF4zHZ/UkDgPz4U2f/KpoQvgNrI4+V6lCnYuDZAq6LTT+su5JOyzDm2ZBVphmlwnEroQiLEZVfJUZIYSHxNZaCO0mcwd+v/h8agE/XYdvGljpJ4ghxnZ5TThOY3e/QvUcnIlRGDi+ZUNw9S7T5oXNhVUKa2hEQ8FYWKAGmTHhPYKACKK6g4/StCbaJJ5tp2m66xJOVDcwt+ewXzhATKRHRN/qe61tu7cKbHRHbExfGT/KsMQIID6FUA6EfSiPhlDqqteggsFOtxyFuoZUUp1LmELJT8ZntKUi1hJeNnj/F5rKwo4Z4Lpm60MYJCeWomWqR0V8euDsYWmlTgfh+ByeQhijqBGMXjJxOEDVxTiQcsFIhAarH1AXUQAKmyeMkpow8RkbwZwNZQmY4qbAq+GUVzl6km/1OnogcqnMtYTHiumHqZihtmAoGn8UJZB8lEWUPaTDH3q1Po86Z7j4IFRuKf1eVWv/oSSrD38z6i+FLYdJm1BWdMlbtxnjgI/1yFcXLK4vQ7fQH3K0p9fiDMZWYb/rMh34bS4gtgbLW4t+ee0NLqZjylaD6BwgYApqKZtQ9O3KZWATvdH5cp8Of+EUZa7GjuP0bV5BFt05XGtt2Itnm/eUMbl2rl7WNH2dD2enVtiuyJgjxb5bKM+VCXuvQD57lDJ3E5q6yPGtedlaGUM6xhNPpz0cf7mcKsQfnUvqQBEw2FLjBLtIlETPU9Gf2rlvlAr4cp1RkjmuaX1BhKCQhyKH4wabP7VXgO+loipYe2voCVpEAj4e7Gj7P4m6VxUA9SZrxL2lJced1UWNPRjiCQMb6tg49uryJ1QQO66zBIMMgMh0g9WR8TItqaHGAMBU9Wnoe6Eu+PAE2ibtGs12R/e6GxxKwWQnJkJOFbC6IN7GiZrZjqJhRVQGNRowEo/PpCCZSjBvQtRwswopzqvKDMyK09DYblJ+dfFnPprEr/lfN+rRI+TBQshisCieFJ+5UGGP0vhBV9LFVEi13HFM/yL1jWURB1MGQDFG37SMbdRg4bvl2JN/Q+A6j9Tyz58XqBDbvRZ2jcid7NuL0W2yaNctWnLLpM9FB30O/kROp2Sq7Iyx+S69nd73nGRaQg4a+xnIH2oyA2/caBlKFqmUusnIyqGe7dsWMMYSV3uQi6ArQ7ExJnnBsCKRDDz/WL7Vnq+diejypmI7SBuViv2Ucn0ieegMoP06sgRMZvHyWIqV7R8c2JOxs0L8oJyforv3ldp3qdadbzQwEckMUg5qUYcozEa8vpGUn7er+9Z0/7T6dEO7dl+ddtv3pDf28ZCzwiL+yLJbs+Y6cxfd4XWtidZOtWWUKMI017h/a4y5FqXC5PBPOZQs7XiyF/iXSzk/kdbCMzRjpNvxO5x4ZV0TrPe1mzf88CpycVpYYDWDnJtochTHTUhJ6JzHTCIZjy9XencDSI4xOxZOu6tesUQVB7hhaU+p1Aag8mvz/k56qXCsa2ZJoNO5YDu0AwmlSRDOofVouM/K2k+sw6PDoGTEVC0nVEz4dIIcGi8j/qMmjuzW6+AXNc4NGsFJb4kRvnkCAlvoBdPpRpjN8JToc6b2fNwhjwWVYHXqlXmylrm27APTrvn3Svwur41dr+MpXAfrjGAtULq0mZiChPrTmF89NYIZ3ZQwhjpKOSuLfky1RZ8IXt/PMoqFqSHcJkJU00uicsBeBK3ZrsQ712GuVeImI24t1lBPdKfsrS5ECdZuXs6R3TMly553r3w1lkNMyg5VGqft3Ym753FVi6uDIrlyu+G+kOXFFz2SSVwTmks41nzkQQgFq87NV2G72lhXWGL9s3fRP9nmSKpthwtdVjxqSEMvaacKKqk/U9HP5SCrhuLUvIVvnoPzM2PiiNoxzKHgtwg+Tl1y0/zqaRk1z+ZTnA2//kKp7QZRjMzJ9IaS02g3pICFP0FDHFPcFyyILr9PzGuwEfcuQtYUfA5H/n9z+vn0yVPwCn1jqqczlOMKcdOXCf0Vops+uFC3Y3lpRN/egGB9McDaS1SVvrubUdbkyQ+Tf+iIy7KITKimc9X7Co0fB5dgZIOGrnoyK1iKTjey+UqlEgjQvwBKWVuky + [1] => 00iv00M/4PgOZwLTXSOHH7xx + [2] => znvUwmPGgw9YsH3B6+6BvP7UfXmHu2ut9QsVnJDwxaI1G7AGXHc9mlQRGm7h/sunL/zfPArAirZVIK9yLUHPc1dFGHutMxTqht8yBbh3xnEQ0AkWL8ZKEGVQuSfBh9hGP7UIa036ZHlHwGIlU4c2MCGdXtUMDrnMOFF41fkkEi9NBe4BENZbDGLqYFkbmg2DIRBZycH4AUJahkb19weNJMIPFRpMqDHNw261/PPdLRhUYKp9zLvzci5jXTTV6LQPcx/lu8kbM8JN74Vx34aJNEwt8ICrqK4XuRUB2RfcIZD+SW7aXNMVA2xOVPbonLEy0ciFGsb7/nx6br2o1ca99++oo0+MtyhKQG1759j4Bo1W/N4eo6+mDsg+/zgO0BGwgKk0ND8zqtl5Bp0tB+JAP3bRFn1QcWBVWXOK4JjQGCsbg7hncILIqn4aOSNJ2SOt+MQFu8ovD2dVVzOjqtYWbuuCgTPxyItwxxeaWADcmdAuPDZ9Fy+uRO/XUE3BCYypDUqSdmG72sd2uyrCPbvPGFKG6UjhwWagmux5HOP/+GCKFAeDPi4/Nc/LrgodZbRSdwL4EAiKPH4S6u9+lOWfciZhBAqsIAXfzeaEDwIZlnarmpcIFHnTiFHt+Lf8icEebldW2pCvnLoG+ralIS5durfutbLGz1l+wXOf8ZKTQf9Uh8qa7DBkGQYA0wLR+DbsJNuq4wd4kt7rhtkXC443gmvr7NdyJ8SajvUeia7jFYUdhANYMhv10blmIHRGHlnCtjesqJquyo/hQTsAL5gMsXcB7+81lZhzE6vfMcIuo8hfansNzVciIrgrG55wqk/CvS75mZS/A2znNhCaw9N5nTVMVfkix/JiQw7I0D38G0aVwvuGShYvur2kFHoIq6eBCIHjYCe1ESlWYinAbGzvUp7RS1wDYYsLgBN+6ofRLl+ItUTVzY8daXRgrIXfHwup1MzKsTJx91PKDhvqfoSWbcs54dXWQG2A7kIokscZ4gDJ49p2tmQn9cEAcCBRWZFHx2YbKWIYH5+ylBsEhG1e7ozVvyy97iTfVaEE+LqHVtrhzWjNVkS6ff9wDnSOfz1lvUyv7MNmcbx6N/VKeeTrpd093r27hKQAcOxQJ2suFsfR3XHLcDCBNuHI9HXU8wYBxcTtxtOMgRcfARVJ9KbMka+Xz2JIqOZcqAhCJBpUbRo3xkpxscwaRZFr7nJKZsQeezPlN8s8shX9+kowvMEI6ZFZRpwHhkwwm1OQwRQmxVI6zUCf80lvf/6ZbfqRawiWYXn/fxEprZRJw28TfVuvAcgN1rnJmjsGKAqmIQfGY8pbrcCS8yVFqBGeiruCUO7dkp+fmWRDXvFIxA+BqsFTbT8emiYaA6W4hyaRxJwD+xrSswM5fDWb5+m29Ietxxr7213T7UTiJ3STAz+F4Ryv4hvLk3KOqtGCxuKGCI8HA1X1f0hmnxg1eMnuh11eZwu55cKVhNU/+E/0K4SX39jCIrxgHbsGRBTVxvM7DeDT1T6uqNZbc0uoqnBdOo/30yzdh1oJcTOAh7SQrVBAvK1rK7so5G9vsHwlOT7f/1DK2PcE71nAqJCP8XcOGD5QyHbV5O8xW4qP8HIjTyJWLYbfcvGFF2Cgj6Rtu9TBXbWYHIUSJCV2KfVhYaI2Mh8vwkKZzbDUfDD/Oea4Uvk2PfSbRbp9zYY52Xm/NJAwRhCuGfVihu76rKWKqwxtBhHP+CVZPTel/RJ9wQ+hmqqRADhsqt4Zxl+GuEjVijnIb9csHPXfJcz0FX1CPkKhPYMDOOE9g1FKrEkLAJJrgGesEc53d1dWphjoM8gkq3PHHy95eWTayM+4MN0if9Ue71uoCxkEBT07jXHInxuOilRLrlX39J6Xf92WZCiZPu8QgDfjKICJ4RGo7hBtQWBiX+rEo1SDAYIZqeT5uEBmend7ct82eEBiHJBpOpOqOGD0zcbD4sqSiqdokL7is3YpPMTYqp2+eYrOBLR9wVMyGvnzr6mRl0YZxH3uFWiPrqNfHnro2DvZDA4Glq1GIrIpPtvFboPEUrJDTtiWliJ3YxlcdI/JU1pGuRTbcx6WVt0mtS8n0peY20kydYzzozdCk6dAClG6Bmf1NRJZKLHM8UrYs/IlRAy1+/w6opwN6+Qo3YbQye4s0N9WmP21fHcg4AUP0E0fAhkpXgWlnnTO9QZ4C89hzvtb80WN1fxPnQmbHujMD6lOH8K7A/ZNhSM2GoatOR2LYzcJYr1joitZhJwNlwy3KMCIa2DgT38cnjzQWr6DrWO5x3F3ujy4sATkLviDdFCrz2cdFBCqtavqIS+b5hq0dEevRrwfF1R1BCRv4Wxw+BaLw3heLij33djS4Qvz7GJOmwGR2kDAO90YPNOuvgcPdpEG9T2xNBGwIT38ZnNfoU+J4y2EHk6xobxgGG2ZPeobtstiSQFJiO9ZRJls5Hn5anVq2F42IHrI3uq5W8zpcYT00jGC0wNKn/DgrhNgk4xy8DPVIDj6csIEL9lOWXaWNuqUkYYmpWfnxJ7QKQeZEFOz74CzVGqnlK6rpjLHHQg75qneDJV23x6ojcYH2o1uLFWbeb0zXus3aCErR/H7ipHgS7Dd6C2KzRTK8tdjZYNqnqPpByh82q8FpOQUoSSJ0cHlUpujFDhXoc+d+am/kduph/DBo+MJiKINBi9Ethy+Xoydcy5tH1G38BuspZpIvs/zEeH5+08WB6JpwNyayvGTNGLE6oMeUXFAvNNA8vxxyrSYuVEFtM7fIZ2UErYw22yyOVyHZ32CBYOgNy3Pf2e1tzn/o5yaPIZMVmcQiZ5RHvzVMvPe5g+MDR6NY6LXocErbxxL/6FvOS9eY9LkwMU+cKwPy5OUOgAIo6dVztK4MFT6/qwecfhRkBK/THKqlPVx5smiLZq3KfoPEZyCJHe2TlrA1hVSG7VBzuRJM7+MOWgkjulT0jdYoXWQ553pHxWP5lkIpkiPaJGZCvq+Hfj570XLhRbKGCtn8k2JJQ2Fap21ZzRI6+o1fG+GyPB4xEfND7ZanmFtFPIIshepUR9anCJXdcO53w8W+YUg0Dmpgn/32KiVVyoMmBn9yQpTc7tybC4/CteQAKAXKz1ZoV58CLc7KOuOkEI0pR/GsM9WssMsR13tDe4dEWCWqgOQi1gP1LjA85jylRfZZz75d6fCYwZTiHVJcx7ZuBsBE142ody5XYprEt/HpYs7Sw8dJJE51drO6XxqClAUXw6rlAjuHuss6gfYwwxxa1bAUWWeLREm0s3QYBR19o4RQTbJrOD1vkhfS1atFmuBn1nQcUGYAw12z/MAMufDFNC77n/VDdRMFrrOmLlERwSNOFKgXCrfClW6XmoXkxOSrnywh5cYwz5v7vltNxychXf2ZAN33BhleZp7VrZ3Nul5ak//tZ4zX8Tp8Hdcop7AsxdUXRs64/6QSriZKvQSTjvYP1oO33DQE8X7q7mDktAi9sSbJwUaj2seiFmGH4t2nJffbakS2ZVk4YISaRLTf2OOaqHmPcKfoxfEiJ1C67m9rLvY1qjvryGkCF6/ug8WhBdkuwa9lcoHVqCZnpNnK4XHiJIQ6srCQJZJAr0WNykfX8AwX2qZJziUp8jnlbr38oRKCtm/VozJJSo1sTpBtxqnxQPajkOCHczcUOqgXVml3SdKeqsB7AtU53cLvnrbV7aLpt4g7zS+SkdcR7PhEPkR3X5VaXSlJFhsypeTTRGiyEKMuHANnbc9QsKTS4Kx6uQEbexFDlIYA8dR/xmjIKQluwSwq+baRESqCMW74l0acbH0CRjCYZEQl+FSZo+YyyvTihrjETVUiOPKLKsCAb2SAvLjTNuDtxb/vPTt2zyBT/09lh1JEsfLJiVD+u/sJgJyaMLKp+TZyZqsFZfTZxT+bJCSi+W4pnng8vLqeG94OqIanBPZf+phPWtQiUUjfhMJtNOdubPqFFZnFia+yow99qXaSZfSjcSXFGsxTTy3Tef+xroEMSrw2dHOOv7ulTRtCAjRIbMJvWvXqnHKl/F/vtVTJYfOd4WXzfjACNmtEjATpXNZb2dl3gZulrVziLWuVsPnR1ZQLdCBdQO3R4IHYvAon8zipUwFSVfydEtCBC3FnOBfRbXEH8qG2r2nmBdsRq2DQRwacGMxWH9lhzhJPzHb2xxejMK8cyW5GQXW6GIeyk7MaVrpBr7NsuqMsesxfZAbuP3/buJajC1Tf/1Vn3BcsmP2RHSxQow4ydbJmQql/KL2UUHXXy+kvAROPOXXcZ20VJj/X9IgrZJNdvxZ2sEBjdl9zJTzHNvDlaRl+EPwYx7QVkfbuaqWkAiygLur0HDPTICgpESGpCj5x39PP3uN0ebaV6lAO/vMJtB3tnQ7ZUOxR1D/2gkHgO15MudB5M+Tccl4TgFAgI3BEVJnAL0QavQlJhptE+Oyf4+HgxZIg+Mbe+Z5V21NEXQ65etIwy5EvIpDcUX2AVDam1P4hc7D7TRNE+owQwfBXwXpDo0eTJHmkz1NWsTdt4C9MgPt5cEUBn/eSSBtMAZViXlwPnfAc0YF4c2SohBbNL553lWyrAGVJYhE+9aKErTVtRURdAqBCCE7XwOQbcH9/Pjee75t+F7PPQFeXGJ5Ezl5p3ZtHrKaDnzX/n6/fK94wn3jKCf0cmXINqxJGh78gBdIZTym1RcrEI5YT1aAIHtEhgp1EbCduXuGb2pwoLgyrcJuCQa1LSZyYSEuavfz0ub252aUu9fCz5btW+6vk5jUty0W1NgE5xhNA6xbp0TRswEZqO6IkWdEbPVuK4AQDmKu2em0UbHwV9O8kUacTJ5bXwNEyR6kFf0oA+7enmRdCusVkidp5S1Ya4saFR839oSy/I+9tFsX3BVYWsXbNmZ9WJ3owcxGH+r8eHTE+KFST/v05ySDtpyR3UNX6BBp3ROzq3OuMHAc0Nc7TLmbyUDTdAzUh6WjgURWNqLq+Kfzlo6Td53TBtrwHjWp6sYSEiRG6W8PbXSXsZCIDdpm8NqCNjukej/1yUUrtjbnwZ4HkjPVqsl+LVFvT3tu7N3b42R7rB533TGWZ1/s4MHaWmiyPQT94ReyRQGb/kISabsxGGTSqkdOjZ7URaOMlB8lDxw05VuYjdj+MBT8RRufVfRrX+N1FptcMnkmqDv4CIWMR3ekNzv6dACovzM1SruTU38lDpl8cgxGbTGMsSA1b/Ww6rHqiGpIyvSN3FAYPcBB5F4jixceEsqPrQRpvy5yg/ofAq8AWpH1uaqlgTbd1mwmIb8aNnEG3MMbRoFWRJTZeUwVkNC2CLne6vzBKiPa/va0crtiBccK/3vVES7XvaK/onteu83Uz/zXZVkUVN3hcRG7pdQgKZR5TEC/3q10KCKHF/eAAwhWlbsKPJ8UFR9aXU7yCzjRyu8U610RMQ0q5PDwmz7MoK+8Mp8CaEjCOjiTxkIPRKzJudWYO0O+uKJfMLPraREGoxARGJOCwPT+ZD7eUm4KyA7SzljA5ywJjWExvGlr2KfeXwVnyhY6SPkq4MBVOmq63Os0ZauDFfSNQSlVt5ae8H1M5iK+R0hD29cb2CuYiRYhab7dmB4/d3HT0ybJN7O9zozo0vmqplnWlQ1zW+W01gtlUfq+oKpda3G4YpoXUQ2td+blGFBKv0QcL+YAo7AjrFQ0YWA0w/6ToV6B3/Ddal0h7pQxZXskpkov5QT2xKGPLsJtADKMUOFqYWT1vl1B6n2Yd7Uw5BGeHymqNK1NoaJJGnJHoVArKfo2RzJLjtKKMUBTHGJ0zhT/0yKmnzysmA83uunU1Q6Zc0jWYKUnGYhHS8E21WfS48z2cIkHXxyFPwx7WbQAmzvQZzgg2m4yrcm4zwsMwh5lrHpQ1rypYzu2GW2tiByq2ZAbbGyJBa5ZMJZRSTiU+i2hLpsjWGmso6nmWXZ5Wy+4LQFRqm0jGDcoyniNz5R43eSJKxLkuE+05to9C69yiVbkBDd57YMwGPjkX0X4Zba3gpXMP02z2aX2JQLoZp9AszWMRiY3/BSXFg6UaqEkZbqh48pS+NqvDoe0Teib7rO58CwFVy0FEoAKq5bw+MwDoYCtwXjFavq6ygnWMshu6NBXuBWyj3it3GvqXaxf1TKxUEyXhr0+IpQBBSlosrlkC3gDXyhDVygnYNMsaLWOYykP+iUiWdlC/1t2RGn/5FhSeSBO+4bocB2g7qvntuI3c1fKaZAWTauw8XCfdRqFNyTlpC5LqsIrhayqy8SRr6y8FXwb+qFKHuJRzaSB0U1KvAhkBCliZJFuI4zfZQ0JQ3YnR+sbRfPJcdkuW9A3sLrDwrp8LVWhKnEORtRfsG56eM8A9I5t1NGY2xsWBgfAXkdpx7cpJIaoSejEO467Kc5YqmpcjTOV+iOb9IS/eR7MblaG8K0+Dri8rBLTR7B1C4js2pZcjbwS2DKJiAUyowE1ziDMxdVYry5EAr06ddaU4x2OumjIL8GFIRkWPaE7dPvoNqs9DXqCWds/ZnQ+Z9yD4Q7cAzkYoJXx3alVjxZhnPHuTNTA49JlNrlMeCxBtolzDNe8ERWgB5OQYOrwa750zEfkt+NM/5Y7WIFuSyxEZmoYwEz7bma5sU8NrkepvWg0Nt+OIoBLXnyUsTk/ekS3PONCSBvS5fTyLrQ+33NKXeaV3Ik+Fld5O4hNS/ku6dsxFwRxnamiIjgfYlfJ9xkcJxMMVs9y/KbPfKSELEtHfKmBVMJDPWT58WZbRn+OQmVscKph38/jjqi6Ftl/W/Sn+rN61jF2RLBoPZxZ/2LzWB4lXis0XDZdoSOcOq5HfSSLTMe/OC7Aqr56LXSCLo/fT5Z6X/HUVcZvKyko+oT4ux/apmemMXU8tYt9oCaRTsHL0KXH4CMCm8xSJRFHxRiCV43Oo+kLWmLdZxf8UZQCcb594g7jnGo/wXMTQPqvZ33ZL9aWlLk05aDouit+TMJWFRE7XPjiLFGP5En8j5dqbHYauF05qAIPtNZ/Hpz6TpO044PpuN1SSQI2r234+xEA3L6I8T/YMms96nugnyj1iuuwc1uOcDPzIoaeati3Km5a9BAl+0D8fYU2YsSn4cRU3nV7Kz1doIw6+F0FbR7QpAwjxGbtpn2TtoCD+6ITycgoRoo5faquyDlE8u1AUOm1VurulWNwJhGF1dtMhHzPrstvjIBljpTgT/Tb41Ai1ywhwIMtLrxAQLCubj1pesMLlBpF80zwV/mskqY69sWRVcA5mCCZVgTiCsi7xOKeqVOhQRmgs8J3medtF4rsYgFH2AWbTmewXA9uQeyW4xxs/u3XRrmQ3Q7kuvkdV4OecEdYYFu1vd/NYVmbT0Z6b7UECjw8O/ouOQbcAb8a9cKj/SZovzqdT2tm/77IxAraCGgvHnIFcLdWr9Wg8zrUME+ok3AX35NW74VsCB74SM+XCiaHQt656lNYwQj+Z1TwOncBnS/EH2WbT5E+LXJ6bunvO5mPe7zxeKw1jSnta9KJvHYBFkQg95A4oergGMRqGqXdGbvqe5wkGEWOUVn4tkLtWt64BUttot0YB8dU5HXjSdg9iybVGvkhTXPmHcSliYsvHvnSopboqkDpKoUXlRoslsmOF0w5nuoEzx5QoOV5X0qAg6GuflLrfSnHD6P3+wzGULNHbh2YRoH/Hqx+3+rdOc7YbBvvigXEUISDp3SzRyGhqNEFwkQaUVw2Cj9OB5YYTzZMH8OCIouoTZqaCknRoD0ax6iUo6T0k6pNBo+sEoVM8nhZodzmIt+jmOadU2M4ocXO/qlkVfe0ftk7lKV1oDtpRbmD4NvtZqoqCkDA81utH2MZ4mrbD6G0mFfBNH5r8GvIf4F+WHA/nE/hFTw8ZL0PbWlHtA5mnxIsRKuhgu3NtHYe8qGXDnr2nmT7gwZZGzPBr3sHedW0anKP21+ejcYFI/xj11bURDOBDivQ78bNkH9WgfWI01qsLrBMpGHOjCvoTe4Jed4H836JVn9LHb8l1++cKN5S2NYlVbby9acdLXw2oRUQtNPD0NYLEOIKi/SMXoWIWjOqmDCZQfhqFvv4qY3lRtnnTsRniZbuLBQc472avDyI28CmYwwpkC5uismVBmWFkz7ZrpVvu9HX1GiusJ8KsV+20SPXWwu+u/ORLODYPoF+iRkdcHc6tW4f8QCQKLTYEU4jOY0NEuJlB6de + [3] => 00iv009zGKkK9rKWzgOhM4xx + [4] => HcbO5wFhZmyZVVPWpACGJkLLsdly81NHl2GnpepBFakB90LcofLaZBp1SOJyYZKW49/sBt0g0wyW4jgNTbzRDL5c1pAFVp8hKPH9RPB0HKdF8ySIOCYRf80rMfaqX/u1+o88keLPj623xrPc1YjTdHjO7c/QjRH3UAfFOH4uk9aFuYVoFoC+GwOFUkbGwjAi5GL9I8Sa6iX2lxyAmEcgtVDyKiWuLCGshFu9yTmSe7TMTJNKGaGBanTqKyndmbBllknxHAt1uHYu/ao9ZubWOhJ24FzkPP/de2xTvnoDeHTDMxZUxwN/VUnJfpKFvH9Cl4DXqnwMtC3hDkpxpiIJDspBDczEUj1KGzSY5Y8H6voZ5tciTz2XJwC+nHY+RUFvFGETfX2lu9Ax4oFq6rbpHv4elDlBdoAY8OTZx6Xd5nZJB6OafPHn71MNFrB8DwCezKKxEN3Wx1+rEE4O9LlMsDJPGCanalHGvdzLaAhjhmGeki43FKz+nq1C7TLe/ZtRBw77HY+W9V84/lgIIFg2F0PAPjnuvfKv2Px/pez66Ol1AfSdbcDM07DszElMsmbhjxrSEq2SvtVrljTXk8Jck+tcjjIYHovTEDce9Y0JN9Z9P3pgC0MdeHrxRv31cqXM8z62Ph6XDojGLoPpXJrpXVZf7ju/iMuaTA9qcxr33D+KWI/UlOlgbdQt7ulwm30cj/ma65VMJsTwF8PKxfTlwLw9gs3IrKD6Rio2aizg5AxlnL/ffLN+TSQ1UAHnWde1Yvca90Is1TAHKiehLr038JujSkWgZopU4Z4gzpo68jxceXMr7T7bOZ19cFMD911Xl1OvwoPJqh82ks6tYT+RT0cypy4SyR/oM05dZR6UVsGyAP4GrB/pdaB7Nd9jcOu6WU1FP1DmV0PfO0qX0/Gfmt83An8W3hegai5lzgQHD6OFjGpK2ykuWpgJG2fdo5SwOgOi4rAU8FCSnuvIIanBsFJlMCKAOxNo4YUvlXNB4XxffoekqjQc1Qw1ZJottlC7pfu3mAXOAoATmAUcdZJE2Rda5rDyeRfz6lX3SOB02CLIouuXiuYQ0DkUv174LnAhBG06hJkgoOs/z7+KZTPG9uiorw2EB3fSYjTMRRZzFnRy040hreMkrIkIEk13gXLjy50zRswBj9Z/IdWHM2yxvcNcNd99zLNLUPo3TLC41GGHePje0SCTzzTeyKDJk+o0eefyVuTZ+vcN4olAlRh/VTYezTqduohONY5bvH3TpdSm16FhKQXaDVmZE19GjOp6FQlIpFQX4BGlrboLsvzTJXKh/SvidiycWHCoDdvQ0pB1rgcLJwZsMzbRhk0TiEoHS00HYaAulyT1kJxXT5jqQdOK1sscsfx1zfVv7hu17hYGTcrqI7DGUhhbz/kHr5FIt3xpbvArSbVpToDsETSx/ydyO+R61NTJulpGoCwkGirzgVdMlAb5OknBZu5jO6j4Z0D0F4WuhcR2T+pKOGTgWjIvpd8992n/QeiDZkCENFwDGCeG1mXoZjd+TLuXkGLxGbJBaURJv+7cylDX4dsTCStFkdbTHcosicqU8qILeQSttkQDF9WCAO7ZDFyDAM+pCE/wQFp6QBs2gv/Ehb2QS4Bd0r6AiQHrfWpukM1LD8lK8uxEfgXDZBvcOQdFI4DyofKMRJ2yOK53TszBf0BFbhjOpzxUJoHAUQpVyzGZp2O3zNq+Hbn6TKUdnYJF6jkMDulegE05AQYiHFBowUkk8BQVYHRhGh9Ya8HzO2JYXA806He/G7CDVLG6qQOpqepCLS4JOPM89UQy1jyFFrfEHB3dszl8CzU5rmMhfDo8fWoVN9/SyqHzuVI74EedPu+A64YxDaIxeR8enck6MIPFZO4SAtj9TrhHrfYbcWI9+7kcwvoCoU42RQaATnCfBzvmssk98LvsjiBmpihQi+msbFXvxS3VKy8GgQXlZdpfwTQAH6x04+KjquGYxKO8xsZAhRVvJ1gEw+DlBZlX7XKq5tsMtVHfZ33W6BZkJBONoVMljL5WweQueSWaFDk85Zf5uVOiU2cJ/xS3cL+FTR3wIqAFelgvhbuW+MpFTcp6l5uYJeWyfhrI7q/kSYJ5aaxNh8zlNwxeBo8zaAmxlJe5isNJrFG0xMo2YbpYBan3rd8QQ11YISetZUJzEISno+Dev7+7buwC95RxkhMQKbsL9arA6hdWKztqM+aWHdX0G44Cs89Ux3GhbC8KorUZoeXD4pWeY2LGmuj1aGUQnGmVFk7gpO0K6Sa9PhN9K7oIFxKhmP4PGni8CCjI8FO6cOrR/jW4yeZ6+ePgTnQlxFYGLwc659NtJEkqqqapW52VzBPOMy3taFlfnL3MIvuCj/zA414d+XJyFl53fgM/JdzhPQd87ZtJJttq53mR6G9k4d8Rs15yeRVRVVmuNqWVp0fwL0yB4yu17dWiOxInwEU74OxHdKZm00OP/qKsJ1KvZzutUCo7WghiVOkmKhfHjVlu2QUDmrVhmT/enbHj7A7PkE3X/y8vqAqmVXwRhbw3T6jA4pJdNrXDYW8d719PCvg6bb18zcRIvg7WhN1hRVVGfJT0Xjg673wZCW/tV+Lxb/nkdRAjT0uoIDaFzXH+WweZWv+uyh06x5f/y1xzpZLKdjhD/hKXSjebqgn13SIV5rHiAu+H6uRGdpN+wYz0if44uuoKJKzfPvvv0FplBPsnKxn2sYVkTtBnk7VNJy6HISgOqSqISZrJhGysN2uJbDHcM3jORL2xu5i/322IysBCGV1fumYFcJbCB4Y8iEpujabTe7SzgoNDH8iWps5I7oNcW9iFHkdhLZX1flazKeUedwcVli56EOYgVYfuS2Fk/AX7Kh+XM456uMqJrtV6d0yA+PVK0Paym9IMHIysXWXCi4FZw9jePGHbKYjb4oAOhgdfcB+qqb3+zWpVVv6Grc7qmZKxFsVozty0+aqkhmiZZ7ADEvfaRBC9vviVbj/SOLFyKxDIYdWavjBsBL8f0f27Ys0xU2ysTPPJRFCZ7MRMfByK7PAvHx+mxqozVDVNoa1P3TrKN2a0Wbmm/T8JesvkYQ4hU7fgGE3iPPqkRoGjg+wM296tn5wPWJ3pmtYAUhaushomS3gutgq4rIijM1tN0fMW2hWV5eSuilxi0hNGbr8pP/MyvoFns2csfmPjT1a7aHVVZZxUHiTUy5xlfSX0k1+NPSsCvWjaUDNW3e3h6sAUTqik+aLCO91M1sTRijSAp5QFgr1tuqcKSGesssWdVTKH3ZmdNeYXIboqRYngT7Gzm67X1jhvQ7S4AxIlzFoAyM0Lmov0F7uzZ2kjrbTCPVAkWCHuJfovBB1aUML3OZiGIhEyeh1IRXPUeXnqAN8b9nHbbnPNXWhc+4n2RnVV62KMm0PKFEQ0cLwv83iv5jrJpZode96m7jrWzGmxtfCAYGjv483PX9LbjXg4Nk6xFA34Mp1Juk1eqs/4hMeiqyTicPUdTYvpQjo+ZIbdRc5GWQkZakf0iUOC2+k5dpUnMiybuYONragkty7JGQO3pnB1wZFklqqWzjFD5a0mWF/ZxPniUqZq2Tw/TEj+MGJ/xhGJP9ZFpD0iB6P+Q+NW/Y7sqY9x2io9R1MzWyFvH0B4lA+eQN7MF39JJqs4SP7JWui1w0VdwkT2BXE9otEKMMQtTejKdia6C7+Ex7VzsZdZ9Wo5LZZD2hGYUoORWrGu1uOhdfxjBCJUOGdbItP4hv2tAxR9I+jVXLk/G0bb1hdJv1pFqm9E/ReXikXI3iz2c8jNWC1dSlBVPNnC2wvnHLZ1zGm+CxQWFCKTLkrrAVRSLnPWsOvRYVA20koWshvwPBz0pmV2x+Mu8FXOcABluAFsLeAjMqIymPee/YPjXRSyTX3Sr6jf7AERpw1zlViRafX+rQV7HZ8jt9tb+Tlbdk8t7sXS3cR3++1YkqEmnftJjipeMVUl3fcHYT8bfTZ0bwNZaaoQG9HHngNDrN7GJEo1eGMtzp+915CY+7FjRbD5cNutYXAqbYQtvresPhCAnMEDM6lmnDIFBcJQp+p4Ap87wdEDbStphIwT3KdQVkjou5vvPfPWE8xDMQzTua1rnwGyPbKfXBrQ5561ZiVEdka2OFUfg9o+kxxny3XyxPSYZtn0bYa+cVX9tKyCajKK4fROf85c9R8m3sZfzsRWlGjYpFJbAU6NqhkCezctbkiymMM6ZNgXTmlDYzoncBHN7Wte/9IAoqZKGbhDRBDxOQ4C8wnCAz5G6h1eZGbDoStWESQtrOCbjO4rl0ukqHkna9DZYEOzbroseE5HpfJTrGQLBEH9aEWjP2EwFlrV9sr6O8NGGGoeypC+tQAqDDvwXOPSdgcGFKt5qCHRYfVoj/TwUJtovL7on9PIXkqEQX9kQYZcirgUueWssNo+EwfvAW+3KqEuH9fD1+dSzcXrMF7eQZJhUbR1HmvYTrQh/GI1wQbDEdiDT7jKCnyKnTMXCR2i5Ip2pqE1AT04kycDktZtZcYzALVMuvtYXz5d9cIhFGBlo6zDoiWwkHwp2dlQ45YSTopVbpCabvHkHUez5JoAHeuGzBn4WJop3YmfSMGehDk09Kt4GblpmeECalaWT5Tp+UDRZSEAYfkxBm6Yw/krvbRiqrQzM336O6JbqjgepbOHgFbP4taQLx9nggSxvswUDGZ/e1H0XF1sKAqvC2gx+DsHrRzSjaXMyTOLOrXJ2aiE/k3LcWnrLIBmdjKAtL3YFP9Xj33pOyVwrvLbihx4t++Lk8TLu2LVHi5Di1x5wMZuUZy4jVUTOGO4v/Hlgo3yUVSDOlsbSucXCB43ymFW3kN0RP8B7XPWEMEC/RpN0DILcAf6N5kjg+94BS0c2anYFmuT0pGF6PFjzBrR6ImSMDOQ4ij2GhTj1GrXg+jaq7CNHDSiPFm5KlsqTqSmHhEgPAzfQHGtA3yG4/l+6rZ6EboFRYIk7M6mWJHM8+AsUiCjsclAPEkymgqgBu3F1H0fWKE+82wmhc36SucX5GdFlcPoS0BIqrXcoIruaxtTphtYfmJYX2beVrjcE5GBN/YwaKxLU3bwRjImHUDs8RZi83gA6zdOwFS0Nt8OemXOuU0lXUsdaOwUtRHA29FpCmWNFBDqcrX1KNKFm/MnlXMeFeunSGBrrSq2L4bD0Laa6IwkhOpkZJ/6qx01VBN5L2MTvLd7v13qbrUYz9XYxOI48qtPM5qas+srAeovl+umEOtELcJ6X7jqWTD9qaJvnsvpS1dKud7lA3Hh9IDgKFidQAWkXVIWWyrQ/8mBkWyjV8aZR1Sk6ioq0yIuECpaFTDgMuqPsYVd6JAbXq0IPqcCyDpscbIQj38a8UN/sgeT6MRU34imB6sgfrfxaMZ0gDYGDOiXmD5ot/R+FK/0GgqVG4rME7QvTL571IDxo6u4K1AoVR/NUnx9WM0tYwK0AisDcFOyLDS0Hd0LSglKUjSnaQWJrDHwV1PMSY0D2KFls/6QqbIrB4eDTe2crjdQq4nWxHu4B2jKunDi2Pf7R5cTSb9IEAF85w4uQPOLHMLxjIJ/W6zr5PagNaTcRIKV67knT77LB1xILfmBbG2oLCX2tmkAgrueOBGrUTXmVt/tWXCyTJIfF9taYRhKWg8ug0qaka6h6CtCJqeL6W07Rm7wd77Gc0UOSiao4VbBykA5jhuguWsZZaMUHxExpWDGu2SllORgTn7HCb5MY3RJrffDviEolq90KacR5EwUw2WPTT0vRbwfdXMrv7LgoV2VJBHtbVGX4HHdDTZXAUQ9gCPYQfk7VI8CQ3Ldyne7DVJDy7qrQpFCMc09aRI4aso5F5g5/BXm6h1X5M+MGhPykz/3jf5NOZH/bVOby3gbIJoe/R/uIpGEsbslVlldIs69CO+S/m6NVFgNfegfRLFrYYSVEcLSRcKEiElFUH+wn62F74o261XwUpobD3N9dRxpLB2lU8RAyYYS7kuy1WXnk+rru+Dk8MhqPUJ8PuSVxQIMkXPY5S3C9avMY08PT+DTgLlez2V2KsYnjnWa2s04ta6xzUkz7u0j8d6pr1ZELPyC8Ajhil6/ZI2tn1M74vV83CEihv1E/2HR7ohOjijOGX8HzBj28zOkCuh9nqZ3w04Ch3PGzbI1URC7L01RGur48xbmSNzFOPBcKs+g8UaL8KqdMbkpCvCM9nVzimSyudDxCYEae+16KOgnHlaAnJAPZNs0G1jLVnt6j21flVdM0o7/ty6FIflry/9WNit7sgvGtMZKEe+iC0nhdMvyAhcx97rkQFV5WlZ5ytiPYAEVXvbkzWIT0qJd/OAbFpyTWkfg48FlIrs79QXYF0gHnzH35r2HBiqQI9oMg/SkazMZ+5DOKZ/EbNspVT6j3MFWpJSSNT/OSPDVzFHprphLgSffX5S++pTxgHGsPzdpFSFKUs8fPfT4+tVL9iqX51O/px6XYK/6obTojz7w43VNcrW9xoQG/WtDRl9U8yhjx/xAGTPliMRiVYzanVmIiVEXPc/hhFQgVwNboSIqrGSjEimFMlEzKChC1GRXh+lmFpeAE8PiG8DXxqvM7mPmeCkaK1l4tY6ivjjUmB+1OcRqRBv1NVUoPbMm9NWKZSDgM+4rMZZfvcoGB2CYDNzFcSXgwBV8F2flZ3C8X0EehwpZZIXnIk+4pvfV5b3KqV0v/j5IGbbQzw3eCHTctjQI1m3CWPIFTnKGeKyxjXK3QiWIcBu7/wOER8arL8aSSRIEkLnkCoN912U9yKsmKwyEEKJ7Z4Io5srmpwLy5ZnSCwI+kOApIcITd9+gnWppwKEfPZVPU7McER/TXcmKP4L1bGfDpeoQOEhwZbkB69Fq4SWr9TOfYxbFRqo508RVMgiNHiB3txIzcT/tBeG5luquQML7yKtzlGZYKYqPeOY0MnFUS9NGVjgilhGx6Pp6ajkoMqD05wYy/8NoMoJlz61OqlJGxkY76bdszhVYFVd0G5jGo/g44ZK3HSXeEg418Ljl6KIaM7kzWKsxWoTCV0rdTSBHYdrAXQ2lXRJ+9RyVDIq//f40E/Ul7OEPe0eRPprVf5pwClaV+OauacDFj30r+qV2yH6MMei8nP/nMLlsK4svXAW1pk4mkM6xzPNtQup+nvCvSfmVgJse7fNWp2HW/gI0kvguNEl86fIcQ3FNl20LjZfcq2VtOVxL7vQoAKWZ8HY9PwwhWd3nv4ZDySq/ArUxhWIi9doZAt6QEUPo2VNey7yJxSCNcJAV2LLTd6+6yI8QpsD+9SLfASH4uWSEBAl2BeWSOPnOeME0Vp1l1gEii34/Wx8ere0oGJ0U4ERHsuC6RjffSoVg7z5Zw3hJq8Rn1NaCpcJLNNORAlbf+1lTL/CVn07Zr1o5dqMT17iOE161KMef6J5+qiDBS9xAEGVujxqDf5TyVtiXQcAXqNx5ppSo+orWdkeLI4dNwGvvvVXJoAvtVEYmAEjlVzodbUeuG6i4K2FmuzwdPtK/ELiqyIEoOcLi/brVvyGyejNOotCg6QHbL3eQOkmefob4bEwZYSYCCayXjuNzad62yRDgxCyOYa83Qwuu9TCE6vy2eNUKnzpVgKNMOnnBz24TTrDV4jherhx8b53NzDxVqDLMsw7NgtXcpVdX/vrcpRZ12X2CvaJi3yJ2EWab5rsCDYOv/B2KbaCM65m32ebOPhDCInRJ4Gr6aIx98f/Lt7uRMWFauM7mnJvCT0X4IvAoNySxqzmOd7vB+bMcNKQB0oQy9qtELficaYI/OIE7aa/graLkSD/+e1xUKrU4HOcb7rAdC1Obn6RaPUaeBkK4U8hoPhG8THVYjjqHZ+kg1wbJuruOk0hHltK26LlLn5T/lJEOS8jvusmLgd6WKxDXDxc12brk4+fVIHgQIvGehpZ1TsRDOhlR7oAKCz/cmDkMFFUxQOuoyqnuB576vcFLs0Qtle5PuRkoU/Z7phpHjKf4XFUeYRBRAMnV8c0jb+DvY0aLdGxN+8VRIvWrgozm7M9IQWJutTNbkdkSNTt2k/M9r7cXfIvD8mXdRT4CB1txPSeumsh/OJ/gTIE0jKJptNWpOPFfAGP3CEqOv+nn9z9PdL3/b864nVxzO3UsyVw0xpMdbI2pyQLYPilG+jB47nuoHXbPf6uCxpnhw3jX/okJrldnqPcdlOPcXeQ25COl0qFF + [5] => 00iv00sbQ4oOpn7O1qZ/Wzxx + [6] => 8qBRm/MxQrRBbkF27qHgF5TfX+22Q9LmJqs25zI1ywAZk+UCPa3dNkcLpU6YQAkayLtpWi0Z3SETQv+RawwEhT0I7oj0zUXpRuRn1kZ8YZSUwmgEwZHR90twbhFMbkpMpwF6Hx/GoOMrG6TU8HbGjXi6hAEmU8vD1RRf8ksBSxeSQqhgCpQmzoH7gG/zeLQIhsLoB+lo0OZVJDWcadamt5j8/y3pI8Yyxv14GbVZsDQ9DL8fDCAb9VSnpH7Sv7S/75flG6JONlW/c/GZn4yNTIZ8yUfwvQFwqQCSAO497GvQkicKfqIj4+pO642Eru6XAUXTSiUquOKsVGg8oaCpTvXSda+ot72UIVbBJUTlX3ARbfNbJdeiSOmKwwrwbh34bMuZXaJa7nHPiI9YyMwCH7KC4bZhEcUnXNZEd7LBUuI7tDZxVYkZxsVdAZjGJLGYO8umCxUTMqsvEjaWtaEY38Noj/rgNAe9htELuNG/0q8dTMcImYuyQ5kYiEzRzaEsK1K3wLajSAY2nEt1JtGdiIrD+xzy/CP9N0JInwoLRlbCEQ/Ik3bbxA5lwnNjln+kIMDe+uXeWqFFUhOnu/ZNnam3uwPMEClmiV+knzB/MSAtw8zeyH1ousRZNy+cgwvs9vyFJammSCsFfLGAHjpdPKmeK5bLwR06QMLPQB4bixVda9odYj6G6Bp7WFIUyaiwf68RN8hTKnXhRaZWGP+cv1jn0j0a3VHIzIRqHqxB4xJNta8E4fXTesSwU2zTfa5T4IJDJhsF6mPZ8WqospxIRC/gK2LQon3frfgXTqz36lcuoYNZ4LssOT2cdYIEi2vcCJokb4Ae+teI5sEZxlKYxbfgktI0usCTeru5nFRjIGTZldS61h1+/jhBwV0yWGIYPT3K2mw6tnDZAU9bQDX2OtsValBRXNXxGjuvuNPO69vy8mI5Ed6/Oln+NwHhmW2RSNfZEOqL5QRwiiqXqw+p1yZ3CgJr5Uwx8OSExedhPtINgRagygM/xxXi/amhnPxJsk/gbtx6zEAf/adKlF6PjEchOsYeBgo/vhY1Ycuo7l+e2/HNHo+wO+RlRt1AaSzZfIMOQv72gMsXhQIser05SGCS6OAEwJjsyfUFYxqWldOUP+v/q3raKX/elDHjuPQHsQRX1n88fPqmx89N3wsirwHgefPX4Ah+85FvwS+tqr2kugVsmkkxGwvBXCW6tK0GV8T3BGBUYRG0wEgg8sOUhmxoDFHRnCw7IlCjRW/4m03hg0HY6fGo4JcV79Yq87VEFgAQmMkubop2zrwrdK7FE5ugvZgzqkUKZqgTqs62q/BQJjZwcUf80OF2GEDu9FeE9P7aD3ugb/1U0diC5QO6y8U7ywIfc6kwfqLIZ4Uwqlvawp2XV4qV2bx0cLiGjk96HyG7YLyIi0xGuCZbzRqDzefze4rDDsRH0fCx0Et/2KMdFA8V03V/sT6nDtaA1pf3bioxJ2w3xMNUEQI3vX06JlxJO2J3ZF4bLe2284FE/DZUl1NP5i9JHbExkWGrHEYUOe19JGd9ayHk9WmNudNoizZtqdjcKtyAEGDFXdaTy3GaW1NDQTnbdVA2Ih/WkRR4LLvyRp9IHSsm/9s6j+vnrPXaaqEoTwba6rRmgQaaBzjzkGbWJ1w0DbNU1c5tS+rlS/xmRDQFwQaFnWpr0CqrGV5pYLKa0Q4uHB2FuDJ/cKlSacv2P0WmWlWEwml7FKQVLi+nxysh5Banf4EJlOlerqZRao1vmr7QMJL0hA2WNFDOHISiJTMSbOsskVrd4144OJ6kEOh6xMUV0mZKVG+Zh1VS5YvIH9gDrB3tIuE9MxgpQvxzt2tq00TnsIPqICSB3lptwFow6Vg+iYscqpYHcZRzCZ99cm9ejYqgDxmodb3zy/H8TsQSPQBDsyI8XvN8kyo06ePX/iM4TQ6SjdskTh2J+lqK1l4gvgL3RQ05Cz3Z4+LMTG4v5T6VdBIYKGKIErVXF8OWl7SY40XSSiy6SI2mA+j/iGdNhdR8UyT28e6RNVqzvcAdRZqcsTK9xTlzkXtSNVm71bbibeRcTzJT6J+G721Nnq8J9VO8jxvTNIIxBn+R9zbPTfB0iCn+heu8qgOk2NVpU6Gmi9gdwhI4DDLfe9BLc5H6laPd1q8YE3j8+pfR/gCQUfst347/Bh22eGTbxP8cI2HdXCw2xKzXnyTrKj76ldFQxKX6dPMm7madCkWKxgVypzT0l4fZLaMxUOK/BczXOt2iLLdIZ52sX896Sd/Ngq4vPQu+EeRNlWLy23A5ldwbx8I8DZpm8/u3qdHCXHPyKMwNXK1dO1W0ycKC/poizoNADnKm9Bt6InJ7tex1mc5H0WKgqtRkl9bagQQp0kBsLdwOYYq6gU+dw/JQDw3B8nYQWz39k+HWZKAJc0GlYihKhFOkiBO77EG2gyS5kX73Uzq6l/xMpCTnbS8vhVjTiL6NbyVLy6t4WLyPk69BaR0H9xLXtVxx02YYog2SJPtdw2hdn0qIvhCJWRu10jJiPZVe+9qDZma7fZteCXomqtG1XcJv0shCBttuRdJzBwk8bzwOqENoDZnBctaTalv+28wHAglFPWvsQs/fpVchy3qIFFonbUo91GmPH6Oj74PVoJc0D1IsVDc0a68zFEKcqFZrlKHScm52iwTAm+cs7Eevb/d1cEJqDlq1WYtVl1ViNUGScuHGJBYv5swyEIper3VqpccNiZKeR296hTtOA2K5PP/COqdij7LNgzG17dML6Kf/9mJrwiG/fVScCw+iIu1tKGZ3msqyXTFwq78MBk1gc38V6EkUE1xD3Gv8Nki2w0/ITNzpwPThykJCB5Kn9LyH1WXlzuvEK7+/arpnNDh45ZB93KddERuY97N5oEt09hJ/klMy3EKm0zXpXrewE7I+fQBmm+4MKzuDm+n5js1O5DhZ44We4Qy8+ZkdTfMkl9ylC4/QsNYMjH0lrWQl04tCc7UpENOq3hkdQGCXLM/BFBdPQWaGG/nOoVvQi1oS45+KS9h7bkg3ten3k/TjLVtXHWUX/rttMsir9zWuUsq5r29MTMirqvSDLI5aXfGgZQW4oDdaZV4dS/+/+aVD/62FVKda05yZoeNYxm5cj9ZOAy6x5WEMYMzc0VP95izlutbI/dp73c/k9ifStt/dWLOh5nBE9HEnlbKXMDwPyhVLUz3QXtGphJHIuzYeYk8vtrTbHEIUhwQOe+iikQ/Z8q9IWS+O5cN2qbPonSm30dZhqQXicuQFa062LTjfz9KiJ7qKdggZSEcXa6caXX1uoUm0ow3JzAQbdcy0s1L0wGHuvubBOpiDMm0SLas1A0a/2TeBki49GD3/Ft56sMU5AaTlbI4BdpRE6Z+i34MAeWCy3cAgtrdiHVGODvjHGyxhAwWimcaujyTipRESBxquVmPHwrCL8hICB0YOhFsLIgPRpxkO0YtKUT1/gqQuzVNVxkyhXwUO46KWz44vr1u50abMlMDzBdz18CvOv+pL5v+cEgyqsEyqJEYhZH11c1RotmoCR53U4+0YL1PmoSC/4GrBb2HMl3DPT5axF3zIfqTEdRv/iFKzd9R7R0MgHJqmyM8n8Ut0szPpCFa9UW75LBsiLen4OruzMSDa3mhCs0nDqiIEtv++LlKlK8TlHdNc1OJ8BtQo2n/gyVfoAFsamcgXOK6PoRV+KMQdrlGsl7nUrXwu/1GuVEfqhVJWImEriC+PLFQM3ine7Yq+MtwMHY0EGF3MZ9uPvm4+PPlTHFjQscHtIvnrewFYJkc0DyYJh97EhewS2ULlJ40rgRLs+eN7Ym9/X5SMn/96kSlUDiqIEtf+L1HJlzwYmYCI97SP6aRZUW97wzOwMSc4I1fgtzZ3sa0d8utQQsACoDoue0cc5vfzMcJL10R4LtN1KcRAbGZ1uTtwdJ6zbvrwcafnmYeUR1smEQ1Eq3BhhBuj2MdLKRKwysqM2j+XCBf4Iaf2zFxCKUnbhQNMaEzHRocu2B0hUFRHJgnldWpb0AWQTSsdHNAEc7ZQg9zOTfeaHq8qD4TMTU4yNUBkXI8ICr9oiNYKsQrEQ8zZN4mKXyQwCJOW7EKYqj8jDDmbO1q6DLVEfVuzovbjw5wR8UhSfCIO/vm1llq/B8XiKwqbbKjIJ0Bm9lMpA6Lk8Td8ws97d/IKDK+qBLo6WpHoPQ0Wb9BJQWDd4eD+YKhChlH/o3LRTMnYvvDUs9U/DKjE8mQ0pafK9XW2207A8qO5FgexoFExCipWhtm7VLTr96cJz0Fp3rFVw2ZALKAOEWSpn87k78ag5e9pT9DQ6KeWSJRNFNEVQLYF0/WXQsCe5AGSUjtknCLiZnoaYR15xWsv2jMo+9hZdcmuC8Z3zUe3eU0pgWuciHaT42S/Etc+BxFEOMw8LOEZ8Juz27HYuemrABq4QluInLkNC41Jt/eOBvjR5Rh6oyBWEi2WfTLd6JoT8eWtriON7hTmLBzG9JanWdUXpghonEBSmoHmhhm2D10Rrsb21pq5AGMiKsSDM1kd0e1q7E6gn0o4IYy693y0NDvmQF2qPyGSzAa3Jqb8qYSC65faZzZfld6nlXUSF9oqW6CWSRwKyMWMxLDTobqIPRch/iVThXT/ge2qbSj1w8UjUSJCyu9jaQo1y3UzVm9rTH4KRdfgqO7HpRk7xQeEZ5jZ/aU/oDyioV+ZsYFEub62Sq6/SADwX+rvnC5CgG4R283TBCN4yFjVbIsJLwkRdzJxfbf3K0+7ADfBoI73K9vlLYk169cWtzWAW14GZ+6e17plMAIumH4nYES6DzPFNHT1LLVq1Nm2cD/oiXra8IPyrbQKzB43uu3r1arwF/apRmVgl1Dlu57UGVpJWXEvxDJr6oltqlYFBMggXMzX9TZ5YVo2ieuqrAs3dXHdns4etEGRfxLAC2Af9ZekY73E/j9qNTSY9biZJdFKhWye6fwCQUsxEggL3pBLXm3/FDRfSECPUNi1fkmVo7tZeIrXgE2qRMAupQlktmQ2pFsp7mygjvFRFUh6Lk/BT9QZ7blBbIr/aquPNg/EVE7xJ86EMLzvPSCm4k84GvLwaFitIZYi7veWN885KU2c7cRvtjDKXu0Uwd+aoUdjsL5O4bGOfyYIoezKI4UeYBnAGSPPgx9hUikNlGxlY+LBjX9reczhpDhVn5eH4vmPGnK3DTpyx1nT366qoVpspTik7RWPTu41fA9JSPP+CHLSobK14JYOVf7h8Boj389CGzL+oMyPgnoWOVVrdPKxRIbQ+sBNiKfkpl+rzo7uJQGgMyeLkvT8MeQu4fZDvnb42x0XfIGAr99eo/fxRIARcySpJM+cteiyT1H6/nUJxCRM9AD7w5zgJHtxbgwbXKWyA9/gaTk3yTcCmPM9eoszPnVYAmiSlxNWknDhluCQRS16nc6NOjvyC83QOqbQ9CxH+9Q1NZWYrZIIfbXjDvxfwHUQpnw20+g1FSwCj8Ws5YFE50iq8niRqHT3Zyn2I8SCf1M8Wj0qB3zkwkApzC6qH4z5DOMAzA7zNv5eoeYFusNlZ9sgAUsq7T57YvYes294koUX0VwzA0O8/0CRSVNyjErMvs3NEXff7OcgcxiH+F1nzshEynmhTTwbg40vTh+PFcNA+ofLCMze/W99mHqRzzfmgxdzh7LZjT41MUwPCUvU5vzdKbLRtA6D5o0O1kgQRNP0i0ixjJRC8XooCdpCtdSfbg5JfjBDCzdL41m61jvcVlFWIATx9BvTaAk7HoFDL3eD3Mfr4KR8GeOPp6HgbuD2WAroQb6NvqudjhUOQr8FaYySBYtfvjEBFPjXf2OLfyGhwvGCEZdIkqd1Q5YrJA9pM3ZyW8LomIzXNw5JFS+BxrS2GKcBeK2RLC1BqM6D8BLQCgiY05xc/pyzhbOGNagwlUPyWEHi22/7EW2P+XS3oyISxIj8UMX5DGcTmbYOq1K173z/TMpsOPSdZ7FDOyD3oTZGQzZig6L41/cGPIMHmeDeKuvyaNJ/AcwBejBbF5/GfKFJMUWD/N6MyphnCCPcTuBuIVay/aUgc9WgSmnH2jLWNZM4w5+p6GUdTN6PtXh6PArFOVHfN3uNRA5mnIFkuomenw/cbDRiYeMxBwN+JQ3MjhIO78jkaj8kIjG/F03Pp58oaLzzDGmNpUhNGl3x6dYMSDibLIHPoOp6DJKzuqmeP1lMXcpSkz/62mNXtysKkD3Wv+1t/IHreswW3IPsh8iGWsz6TvH5YrFJHeO6ZdgYH00i/l2Z3EkHJjgl7P1SygVxmQFF+82YgNWtG5RPu7IFvhpj0Tk0E7HwuPByqYrOR0FOzjg2zWQMkPUnurCtx4Wl9OknkwIwnGkqAUBjNo5KeCmBpOOdzstdIvAObuMCPXXl4mtKKk8ZcMiRNQp0VXfQIyoFc70bMgM5lD/7i40NPt9qc9voja0IVIkPqktwsSac/kx72gXFKLDnzxgHP2ZpIif8qSz1qZJAyKEhpiUcvlS3SR7YEeHQ1Ia+rmQTN3FIerN9NlGRli+9m2lS130aq5gw/Iw7FdYdsXZSHNe+YFrXXamOS5flx2x1ZwimfYp96BxuBdKdSUdp0Sj3fFJV82Up3gGmxfDn1QHbaNBe/rZZjUqZpGcAkZE4Jhkk73JELGNJbXysysrhEeQBzkOVEJH9PXD42Ww03aK31ipiEq26K4mQyPwTBDjtpj+69amPwkUwWjK5DLvxoQ9v+r8oxq7/K6O78dVxcAXdG3HfmSjZ3Sjz+18CDeLrdQg+na4hp22mshQGqv1XXVqPzkj5ceEj/EQMojr4dgdVtXoTnODuiUTUXJRyDa2Lh/h69aZcd0nKUI8eXyl0zz5TAyseTEm1BZ+9z6CUnhCUFzVPOAav+DPY+xeciUgFybBzsHvci+lK2af2Mn/CBepTGJLnM8Y3bQgseL3gmoNJXFaoKGnaKqpwgRxWfgQ3YDauk8UiwyEXNfnGYAlHPvC6oaiYdjbRU3M5G3euzXX8f1mF4UhHdlwVt4kEsLjXoqdbmTYQcuXT5JI0NCwJDeRqLXwePJKcRPDqr0Zu1SDbGKxBrbZjW/qYDN6y3WjpZyC8X2hJyv/gGQzitd0NXcG5kKTjMTkNoOLcBbnoWN9NzsLeC8RTHO0KJwFxgYP5ofbgcClPohRKBmtkSDixjS3mr8IuFWJqLCKz/WS8aaMyKx0/ov1Mp7B/DnoI730uSnshp31XRuPHXCq57I84lvXi2Unoh894lJc3V63g9S/guN99bOyQ0qzmuDQr+gGLEnKpuQpyzrmYjPBkRjUy28qi4Pgti9qegkDghNN+E61zoLDVQIUFfqiczf25bzkucPIxJQAAIVBfUrsJc5cbP+v+waFFsNshSwg8hihQHsfy7yBcPYP+7w2KybF/RxajcxL8STCo+VR4PcS9CaN07NqrLOaiSUDiLN7YjKIc2N4saOF6WGmCm7wc3JTTbDuJe6/72bLzih+ruZFpR3Yp46bayWKEbVw9PVHvhIHycFJoBI7mPU7IL0DESuOp1iFevdNI96ExlvIUkWtbT+vsM6bX8pRGGAoV2TsdvArUcZSjluNLg4ZT9wA3p5VaHHhu1JJmS+CCjlO14AnerRZpxdjOGg4SA6/Ncl+fmB/QqxQ7jdENn1FKGAIOj5vMK4Az+3azOrsKtS2EvTpsq9sNP1R84+7kdnu6JlEWqRbp2Vo/26+dJ0t7h8lgHsYDy+zp7nwdWDs5zZABq0jrJfylgDxr7gZ5KgRtjWhznYkcMhkLn7VL+xtyayZSfg7v0dnU5XRQsvAnj0pP+opBNiCk7WY+FBODjDT6DJgoElZY1BKOdXsu0sWaVfo/grHS5IDGQZt53/jDQajA0e653ZNjEx3Hc9+j1OO8ed6jQ9TMBDg/zm1G591u5uJQNwb75u/DjqCoxTRBmYSqp+8Lf30IN4Ph698sURfmKey0LBRqf4S6Gq40mUi90ApJTEFgxAeOj/mXbPci4siutXMtSUcpd4CNeoUGd4cLo63PFvUou7SkAJ0QQvPF2hdVb5jtviMxxA+QPtlmHz1/LH4f8VpWkfnBn7I46CxtXa4lMx5EMoQUrp9rufKDyjLVXSgZdLEy7C2XWDOGZrQYaGAs0nylRDfosfBH9KvtCJ/m7sVzzjGjXH877VtxSu9iUtbL14TJUnpF + [7] => 00iv00nIRclAfQYB7zKU8mxx + [8] => TXTxPDVlKISNVbPFrCp2D36nMXuNf5buckK7JXGTz4B0Wj3MICiN8ODDtxKCuju+fEWAePvRCPgnOcLQ6Y4YCwEyXu0Uhpz5w0VeuxLT7Htb++Ii9AxFyT8ljSfwXr53yJV28L8bicVSR/t7x/Jlfed/7IpgD2/BF3yoCA/2N/9Kr7EdN7Am/FTA6qN4D0WUcdCpnnC7KiGzINR2YtqH6PaNsKnYEqNlC24/cqLodyooyxhdleaJbrvIcA66A9R4ULYK9GGRpkqZ2qAb2+Pfy4PZfIqTBUCtnST36f2zF+E3s86tq1t1mHtQ2QyGq2Ev968EbLg+QgR1jqxOZ7lrTZeqvdgiu8tL6zjtAMLJArFwHaluMW2vcrC4gxmMfI6v+jSlT58WKQIa3DOvF7iHlG9mbivMuSW1gwTuPEEXBz4VQpQxtU0GlTBErWaiauqa2677WLBrHywrI8L5vGQskiXulo+uoW26n7ovWIXuuSBN35rZ7eBwpDrPAWJnqHJzDzZxNPX6IfB8NG/TLT24IBHqF2UuNYFq5Q0gDzngg9IwZgEU6TObfirTW8eieTZPqksqoVw1z4Erp1cyoaw1EZxjcnkLM4ncMwm1d8913Qhcj9POVIP0zTH7HKLZZQRogt+RLOyxoFGgXzqeZevTU/QPLI2H+DKDdJUXAEzr2Y1i+BByGn/bpQU1b0r7765KsaD2I2s/xeXSo5WhyA0k6PIylq6yJ+Pf+nEpZtDZ1vP0c0ecNtMEY6KVImlvTbPRMEjmQRRfQr5S2ORZGgJ/wYVXlYm74+xYd+pRPu3+V6O10db9nZs5IaJuJRkpFn4ffgR9tEoaPuHEiDwhQiIgvZhmIKMGMBiOBFr3GuLaBS9EaPouVywif1v4jR/pUKqS9trGYyuC5afStNR9PwThg0Y+Awt1l1abZGQt4lfxzj1enz4wI+HosK/27pw5esWkNQXnILVEMM78LLsSarMPLmoI4NLP1P3bbGWNS/wP9koNvP9uxBD0wLILeZOxQAv3HJNvy28KuO9GNgVOLXGxEDzJNlLd8ZDH/9qjPpUVTBotaNkBeRaE8wnf2UrEI5M8Hrm0xOwGAtIN7wVFy+Dck2sOyV5gWxrrW89HSpY6TW11UWZXOID2I4FZ9J5cZBwzyMiavtXKoPJUYd7D+GnCk1wfFmjXsV0NQa4Wd2xqPqnTkid9p3KAVrQOcDcaDPsOpMNH+uin5EQH5dwkZae2i3LWD99kqs+Ksqki7bLWBcUoMFuYMZ9foXHTWK40RH/Cgt6eH+Ed/Ny2c16xLO27C2W82sIlsQU6FW+usEjg+eE804Sd/05V+9DVZ+cDkvzKlKhJ21HXR8FjGYR+8X2blRESFgdeuydv4LBNICQb/hfXuqXtk4497ka7zhic39cKBgeUknScGrcQ2PgBHJXoqq3WO4WpKaZAvCAhBJs8EvRj1qXFZK7iYa6xxSZMIKirQU3quaoIDyJdfoHe1MFb8AzDJ0F9JYMUbyXgxaWrX8WjcJyN7Xh4UAEI5q4Qrg8eRV8vpiPJMdAYj2s8nhy6xbUjZxkTn9cxmtx0KmmdMq7WDYZsqFYyJnqsxgFXO5b3F1VnD7uY1dIW2RjNIciv9l8F0rBY1Iceh0HrsMi6PGXXr2A0xQPCt1ILNrRV2cqXINAxUXwUfdFCCPL3m7aXs2/0DEj8g9B5cBKb5Nu6SP0X90NE9csbaw+6VyZQW65ow+fXEzRqVG89U9agf0fc9p/Jfrwv9+otw2W9CgLgVGQ6illhin9c6AKVC6hvOx5KfO/EbY85m6bahHUNncY2SScT3U/Xl8fbOHHZ31hi7ve/NBmQV/k0oJolcFh4sonFyThXatQolRz6ZHuTbml3ZuW69Lqi3J4SxyNouuV+vd/8M4o4SVLECpbVldl34+qD17D+OqInHjHS5sas700m8yEp6nXUaQZJz/BZyxTk4S+6kYTnZG98CmS5qc2oo2dpxUuFIYSlRpFZz52aTBTFl1inNYNmRpgzaxbdQGjCNe/zjfT1odcjb0hRASAevyiMxO/buzy8Sx2TyunLDxVf4dIXNfaiZxiPNsOHB03KyjjIXEQHnCFL/bsNNVag2qUdV27i8+DZSIxdyXuVji0PjSANII35dP69rwGapLl/OscR0H0bcu1kmqPnCEomy6hgXdCdmCwYiKYuPUMH1L0qJU93V2yBrRwFz/86UYyHiLH+bIJoeYd39vZfYMhNPaPMDbiJOpZYSUZaGI4DaU9Rt/1n8jxVYuiH7h1Cvua80DjT1QdGJn64qAmFsuop/JCl0BQCG/fjqSfU8vMn1dqaCGKOlLxdPrOfZSYRUSK/xfBCDS+OZhVt4FXd55Sn+2AsByrBWw94m7Hgwgoqk3Voocl8Rp0u6gchar1EgdyoW+xvTjg7DiNBepokO/wFKZt/fuM1q9AwUbKiAxe9238TS3La4WIJ6hXW3wc8jeLotOhD82xm44ej6KsR93qDpOOn7E7ZTEz7YvBmoksDVyZ8KCJQKN0T+3bC1BcAfzrFsmqrhIO42mEjdyUa5Bv7vJpUxsd2J3Lgr0igwZAFyIfIRy//cGRs1s67jKx/YVpnikxMuKGrcdBR3Em/juGbVmNUoGEyR4cNnoLrE5ZvsZdsixmAeyjV2TBUPM0qZf6TkGU+GgHQdROp1qxghWUn7lWMpvYAPGS75WwzanK95Yef7uPU5ubhH3y2kq7Quqg2NzrwFYgnPoO4yvHdLWLjuNC7ieoNa8BaTU5t1lJl1FzdotHm2zypqqCFUKIdwugGxmdas8OHNzQEBwZXVOslFQ2aCvQdDYuD4ss7RzBdUtkf4qXPWPM0/bSXvKu796sl6EY2dh2ZkJUOXRuDhL4ycFKk6ySds9Vn0yGOvGA/kJGEkhaKEnvxVrf8CeSQjkC0jT4w4JiNpv9rqJ7HeaUxDnRL8ER9fYrWwocbFegXWa1OMV7Ys9T2n/PZeXJ7VjAvlevwrjlxDfa5GSo7GCIcex0e2GK2aRr7XufYuOXDx3l8iW80EnJQt2AXWZHfFTBJQttUSZvbj9yRkzMPCEb4CZfTARfFd+mE5bnUQZsSClJhjTPXLJVGdTKFAyt81VxVCjFgtdvGOIKJ2jKGMVebveL8PdTv1dTgzyOBys0ZLUcmxkocy29VGo1rjbgUE9Nm5kYzzfd8rFO2cbY1Ha0omRp36hsGFkDtzwiMTW8MAFeVZk/QaeytIxlZfjmtfx8asUbZYZvp7mXixna2KKPN0Oh5TVv8GyTzytoQ4RgQumBozPsnCTK3V924uy3DtjvIHrDVmHt3COw9uOMjK+DtcRdOWqWYLEv74GTAzJlP8pfsGyWjYhKyusyoCgZs2Wr1VPfQ/XXvEVSlu/nxEMwugvnL9BFbX4rwz/kcM9PFxL41PkTH9+i4PST2VaGt4DvhJ9OpNCSIDMr35/U0Dnx099lfdNj6PsslqJ+M9JLPHzgQAyv4coK1SduhnQtlMouC6+/N1tZyHSicYSw52bbd1V1pEWsMuqB116R8NQHl6gdOUYDX+FmIFmjgRErQTv5DvEBEvtxhUVjT1CTXpushejwkdaZFwdkoafpGNsoEzPU2tUnhPA9+/fy16YBe8lOcIBiftWmQlDmn5/f8uMJVkdfMd1Tn/p0djzQk1VTzayoP7sVEz0ZST5sbttKZMWqxqK4CvZ9Qkp3WFnzni6HIN8vxrJkIFDHaOGCXmRONnBZz+FORp9sPZfsWl5PDWMntiHSOrbJiQd7EHqmasZy+KLnh3Wy5ddy/pWuO3uXyttis/9z/IOi2HD56G2UsPZf1Vklo6k91uGtW2LwkJJhAYno6o0Uqz2lmq9yB+1BOuw0A/evXOH4xVl6r3fnmEbshWAPdrq2Ujwcl4To2I+HOSJ6XIOFp7zGKEeieXvWEhQatd3kY1e+vKhblPaPsmGqkvlQM7iUJkwTv86MFhTLlr4LVKKKfkYXHzW3tMytj2p9Q0eX0EDclTqafqUXhnfi5TcduA72X5Gworfr8h7AHJBZxf6Y= + [9] => 00iv00Mkl5TvkupI7ENPlrxx + [10] => +) + + +Time: 0 seconds, Memory: 5.50Mb + +OK (1 test, 3 assertions) diff --git a/apps/files_external/ajax/addRootCertificate.php b/apps/files_external/ajax/addRootCertificate.php index d28a7d24b2..72eb30009d 100644 --- a/apps/files_external/ajax/addRootCertificate.php +++ b/apps/files_external/ajax/addRootCertificate.php @@ -2,27 +2,35 @@ OCP\JSON::checkAppEnabled('files_external'); -$view = \OCP\Files::getStorage("files_external"); -$from = $_FILES['rootcert_import']['tmp_name']; -$path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/'; -if(!file_exists($path)) mkdir($path,0700,true); -$to = $path.$_FILES['rootcert_import']['name']; -move_uploaded_file($from, $to); - -//check if it is a PEM certificate, otherwise convert it if possible -$fh = fopen($to, 'r'); -$data = fread($fh, filesize($to)); -fclose($fh); -if (!strpos($data, 'BEGIN CERTIFICATE')) { - $pem = chunk_split(base64_encode($data), 64, "\n"); - $pem = "-----BEGIN CERTIFICATE-----\n".$pem."-----END CERTIFICATE-----\n"; - $fh = fopen($to, 'w'); - fwrite($fh, $pem); - fclose($fh); +if ( !($filename = $_FILES['rootcert_import']['name']) ) { + header("Location: settings/personal.php"); + exit; } -OC_Mount_Config::createCertificateBundle(); +$fh = fopen($_FILES['rootcert_import']['tmp_name'], 'r'); +$data = fread($fh, filesize($_FILES['rootcert_import']['tmp_name'])); +fclose($fh); +$filename = $_FILES['rootcert_import']['name']; + +$view = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files_external/uploads'); +if (!$view->file_exists('')) $view->mkdir(''); + +$isValid = openssl_pkey_get_public($data); + +//maybe it was just the wrong file format, try to convert it... +if ($isValid == false) { + $data = chunk_split(base64_encode($data), 64, "\n"); + $data = "-----BEGIN CERTIFICATE-----\n".$data."-----END CERTIFICATE-----\n"; + $isValid = openssl_pkey_get_public($data); +} + +// add the certificate if it could be verified +if ( $isValid ) { + $view->file_put_contents($filename, $data); + OC_Mount_Config::createCertificateBundle(); +} else { + OCP\Util::writeLog("files_external", "Couldn't import SSL root certificate ($filename), allowed formats: PEM and DER", OCP\Util::WARN); +} header("Location: settings/personal.php"); exit; -?> \ No newline at end of file diff --git a/apps/files_external/ajax/dropbox.php b/apps/files_external/ajax/dropbox.php index 5f2ff17e62..f5923940dc 100644 --- a/apps/files_external/ajax/dropbox.php +++ b/apps/files_external/ajax/dropbox.php @@ -37,5 +37,3 @@ if (isset($_POST['app_key']) && isset($_POST['app_secret'])) { } else { OCP\JSON::error(array('data' => array('message' => 'Please provide a valid Dropbox app key and secret.'))); } - -?> \ No newline at end of file diff --git a/apps/files_external/ajax/google.php b/apps/files_external/ajax/google.php index 23ecfc3708..4cd01c06cc 100644 --- a/apps/files_external/ajax/google.php +++ b/apps/files_external/ajax/google.php @@ -47,5 +47,3 @@ if (isset($_POST['step'])) { break; } } - -?> \ No newline at end of file diff --git a/apps/files_external/ajax/removeRootCertificate.php b/apps/files_external/ajax/removeRootCertificate.php index a00922f421..664b3937e9 100644 --- a/apps/files_external/ajax/removeRootCertificate.php +++ b/apps/files_external/ajax/removeRootCertificate.php @@ -1,10 +1,13 @@ getAbsolutePath("").'uploads/'.$cert; -unlink($file); -OC_Mount_Config::createCertificateBundle(); -?> \ No newline at end of file +$file = 'uploads/'.ltrim($_POST['cert'], "/\\."); + +if ( $view->file_exists($file) ) { + $view->unlink($file); + OC_Mount_Config::createCertificateBundle(); +} diff --git a/apps/files_external/appinfo/info.xml b/apps/files_external/appinfo/info.xml index e0301365d1..3da1913c5f 100644 --- a/apps/files_external/appinfo/info.xml +++ b/apps/files_external/appinfo/info.xml @@ -5,7 +5,7 @@ Mount external storage sources AGPL Robin Appelman, Michael Gapczynski - 4 + 4.9 true diff --git a/apps/files_external/css/settings.css b/apps/files_external/css/settings.css index d8575c49e3..ca4b1c3ba8 100644 --- a/apps/files_external/css/settings.css +++ b/apps/files_external/css/settings.css @@ -1,5 +1,7 @@ .error { color: #FF3B3B; } td.mountPoint, td.backend { width:10em; } +td.remove>img { visibility:hidden; padding-top:0.8em; } +tr:hover>td.remove>img { visibility:visible; cursor:pointer; } #addMountPoint>td { border:none; } #addMountPoint>td.applicable { visibility:hidden; } #selectBackend { margin-left:-10px; } \ No newline at end of file diff --git a/apps/files_external/js/dropbox.js b/apps/files_external/js/dropbox.js index 08796cbbdc..c1e3864070 100644 --- a/apps/files_external/js/dropbox.js +++ b/apps/files_external/js/dropbox.js @@ -1,13 +1,16 @@ $(document).ready(function() { - $('#externalStorage tbody tr').each(function() { - if ($(this).find('.backend').data('class') == 'OC_Filestorage_Dropbox') { + $('#externalStorage tbody tr.OC_Filestorage_Dropbox').each(function() { + var configured = $(this).find('[data-parameter="configured"]'); + if ($(configured).val() == 'true') { + $(this).find('.configuration input').attr('disabled', 'disabled'); + $(this).find('.configuration').append(''+t('files_external', 'Access granted')+''); + } else { var app_key = $(this).find('.configuration [data-parameter="app_key"]').val(); var app_secret = $(this).find('.configuration [data-parameter="app_secret"]').val(); - if (app_key == '' && app_secret == '') { - $(this).find('.configuration').append('Grant access'); - } else { - var pos = window.location.search.indexOf('oauth_token') + 12 + var config = $(this).find('.configuration'); + if (app_key != '' && app_secret != '') { + var pos = window.location.search.indexOf('oauth_token') + 12; var token = $(this).find('.configuration [data-parameter="token"]'); if (pos != -1 && window.location.search.substr(pos, $(token).val().length) == $(token).val()) { var token_secret = $(this).find('.configuration [data-parameter="token_secret"]'); @@ -16,12 +19,35 @@ $(document).ready(function() { if (result && result.status == 'success') { $(token).val(result.access_token); $(token_secret).val(result.access_token_secret); + $(configured).val('true'); OC.MountConfig.saveStorage(tr); + $(tr).find('.configuration input').attr('disabled', 'disabled'); + $(tr).find('.configuration').append(''+t('files_external', 'Access granted')+''); } else { - OC.dialogs.alert(result.data.message, 'Error configuring Dropbox storage'); + OC.dialogs.alert(result.data.message, + t('files_external', 'Error configuring Dropbox storage') + ); } }); } + } else if ($(this).find('.mountPoint input').val() != '' && $(config).find('[data-parameter="app_key"]').val() != '' && $(config).find('[data-parameter="app_secret"]').val() != '' && $(this).find('.dropbox').length == 0) { + $(this).find('.configuration').append(''+t('files_external', 'Grant access')+''); + } + } + }); + + $('#externalStorage tbody tr input').live('keyup', function() { + var tr = $(this).parent().parent(); + if ($(tr).hasClass('OC_Filestorage_Dropbox') && $(tr).find('[data-parameter="configured"]').val() != 'true') { + var config = $(tr).find('.configuration'); + if ($(tr).find('.mountPoint input').val() != '' && $(config).find('[data-parameter="app_key"]').val() != '' && $(config).find('[data-parameter="app_secret"]').val() != '') { + if ($(tr).find('.dropbox').length == 0) { + $(config).append(''+t('files_external', 'Grant access')+''); + } else { + $(tr).find('.dropbox').show(); + } + } else if ($(tr).find('.dropbox').length > 0) { + $(tr).find('.dropbox').hide(); } } }); @@ -32,20 +58,33 @@ $(document).ready(function() { var app_secret = $(this).parent().find('[data-parameter="app_secret"]').val(); if (app_key != '' && app_secret != '') { var tr = $(this).parent().parent(); + var configured = $(this).parent().find('[data-parameter="configured"]'); var token = $(this).parent().find('[data-parameter="token"]'); var token_secret = $(this).parent().find('[data-parameter="token_secret"]'); $.post(OC.filePath('files_external', 'ajax', 'dropbox.php'), { step: 1, app_key: app_key, app_secret: app_secret, callback: window.location.href }, function(result) { if (result && result.status == 'success') { + $(configured).val('false'); $(token).val(result.data.request_token); $(token_secret).val(result.data.request_token_secret); - OC.MountConfig.saveStorage(tr); - window.location = result.data.url; + if (OC.MountConfig.saveStorage(tr)) { + window.location = result.data.url; + } else { + OC.dialogs.alert( + t('files_external', 'Fill out all required fields'), + t('files_external', 'Error configuring Dropbox storage') + ); + } } else { - OC.dialogs.alert(result.data.message, 'Error configuring Dropbox storage'); + OC.dialogs.alert(result.data.message, + t('files_external', 'Error configuring Dropbox storage') + ); } }); } else { - OC.dialogs.alert('Please provide a valid Dropbox app key and secret.', 'Error configuring Dropbox storage') + OC.dialogs.alert( + t('files_external', 'Please provide a valid Dropbox app key and secret.'), + t('files_external', 'Error configuring Dropbox storage') + ); } }); diff --git a/apps/files_external/js/google.js b/apps/files_external/js/google.js index 55042194c7..0b3c314eb5 100644 --- a/apps/files_external/js/google.js +++ b/apps/files_external/js/google.js @@ -1,47 +1,84 @@ $(document).ready(function() { - - $('#externalStorage tbody tr').each(function() { - if ($(this).find('.backend').data('class') == 'OC_Filestorage_Google') { + + $('#externalStorage tbody tr.OC_Filestorage_Google').each(function() { + var configured = $(this).find('[data-parameter="configured"]'); + if ($(configured).val() == 'true') { + $(this).find('.configuration') + .append(''+t('files_external', 'Access granted')+''); + } else { var token = $(this).find('[data-parameter="token"]'); var token_secret = $(this).find('[data-parameter="token_secret"]'); - if ($(token).val() == '' && $(token).val() == '') { - $(this).find('.configuration').append('Grant access'); - } else { - var params = {}; - window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) { - params[key] = value; + var params = {}; + window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) { + params[key] = value; + }); + if (params['oauth_token'] !== undefined && params['oauth_verifier'] !== undefined && decodeURIComponent(params['oauth_token']) == $(token).val()) { + var tr = $(this); + $.post(OC.filePath('files_external', 'ajax', 'google.php'), { step: 2, oauth_verifier: params['oauth_verifier'], request_token: $(token).val(), request_token_secret: $(token_secret).val() }, function(result) { + if (result && result.status == 'success') { + $(token).val(result.access_token); + $(token_secret).val(result.access_token_secret); + $(configured).val('true'); + OC.MountConfig.saveStorage(tr); + $(tr).find('.configuration').append(''+t('files_external', 'Access granted')+''); + } else { + OC.dialogs.alert(result.data.message, + t('files_external', 'Error configuring Google Drive storage') + ); + } }); - if (params['oauth_token'] !== undefined && params['oauth_verifier'] !== undefined && decodeURIComponent(params['oauth_token']) == $(token).val()) { - var tr = $(this); - $.post(OC.filePath('files_external', 'ajax', 'google.php'), { step: 2, oauth_verifier: params['oauth_verifier'], request_token: $(token).val(), request_token_secret: $(token_secret).val() }, function(result) { - if (result && result.status == 'success') { - $(token).val(result.access_token); - $(token_secret).val(result.access_token_secret); - OC.MountConfig.saveStorage(tr); - } else { - OC.dialogs.alert(result.data.message, 'Error configuring Google Drive storage'); - } - }); + } else if ($(this).find('.google').length == 0) { + $(this).find('.configuration').append(''+t('files_external', 'Grant access')+''); + } + } + }); + + $('#externalStorage tbody tr').live('change', function() { + if ($(this).hasClass('OC_Filestorage_Google') && $(this).find('[data-parameter="configured"]').val() != 'true') { + if ($(this).find('.mountPoint input').val() != '') { + if ($(this).find('.google').length == 0) { + $(this).find('.configuration').append(''+t('files_external', 'Grant access')+''); } } } }); - + + $('#externalStorage tbody tr .mountPoint input').live('keyup', function() { + var tr = $(this).parent().parent(); + if ($(tr).hasClass('OC_Filestorage_Google') && $(tr).find('[data-parameter="configured"]').val() != 'true' && $(tr).find('.google').length > 0) { + if ($(this).val() != '') { + $(tr).find('.google').show(); + } else { + $(tr).find('.google').hide(); + } + } + }); + $('.google').live('click', function(event) { event.preventDefault(); var tr = $(this).parent().parent(); + var configured = $(this).parent().find('[data-parameter="configured"]'); var token = $(this).parent().find('[data-parameter="token"]'); var token_secret = $(this).parent().find('[data-parameter="token_secret"]'); $.post(OC.filePath('files_external', 'ajax', 'google.php'), { step: 1, callback: window.location.href }, function(result) { if (result && result.status == 'success') { + $(configured).val('false'); $(token).val(result.data.request_token); $(token_secret).val(result.data.request_token_secret); - OC.MountConfig.saveStorage(tr); - window.location = result.data.url; + if (OC.MountConfig.saveStorage(tr)) { + window.location = result.data.url; + } else { + OC.dialogs.alert( + t('files_external', 'Fill out all required fields'), + t('files_external', 'Error configuring Google Drive storage') + ); + } } else { - OC.dialogs.alert(result.data.message, 'Error configuring Google Drive storage'); + OC.dialogs.alert(result.data.message, + t('files_external', 'Error configuring Google Drive storage') + ); } }); }); - + }); diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 0d942e7845..89f346574e 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -1,4 +1,4 @@ -OC.MountConfig={ +OC.MountConfig={ saveStorage:function(tr) { var mountPoint = $(tr).find('.mountPoint input').val(); if (mountPoint == '') { @@ -63,13 +63,14 @@ OC.MountConfig={ var applicable = OC.currentUser; $.post(OC.filePath('files_external', 'ajax', 'addMountPoint.php'), { mountPoint: mountPoint, class: backendClass, classOptions: classOptions, mountType: mountType, applicable: applicable, isPersonal: isPersonal }); } + return true; } } -} +}; $(document).ready(function() { $('.chzn-select').chosen(); - + $('#selectBackend').live('change', function() { var tr = $(this).parent().parent(); $('#externalStorage tbody').append($(tr).clone()); @@ -77,6 +78,10 @@ $(document).ready(function() { var selected = $(this).find('option:selected').text(); var backendClass = $(this).val(); $(this).parent().text(selected); + if ($(tr).find('.mountPoint input').val() == '') { + $(tr).find('.mountPoint input').val(suggestMountPoint(selected.replace(/\s+/g, ''))); + } + $(tr).addClass(backendClass); $(tr).find('.backend').data('class', backendClass); var configurations = $(this).data('configurations'); var td = $(tr).find('td.configuration'); @@ -95,7 +100,7 @@ $(document).ready(function() { td.append(''); } }); - if (parameters['custom']) { + if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass).length == 1) { OC.addScript('files_external', parameters['custom']); } return false; @@ -108,6 +113,28 @@ $(document).ready(function() { $(this).remove(); }); + function suggestMountPoint(defaultMountPoint) { + var i = 1; + var append = ''; + var match = true; + while (match && i < 20) { + match = false; + $('#externalStorage tbody td.mountPoint input').each(function(index, mountPoint) { + if ($(mountPoint).val() == defaultMountPoint+append) { + match = true; + return false; + } + }); + if (match) { + append = i; + i++; + } else { + break; + } + } + return defaultMountPoint+append; + } + $('#externalStorage td').live('change', function() { OC.MountConfig.saveStorage($(this).parent()); }); @@ -152,4 +179,4 @@ $(document).ready(function() { } }); -}); \ No newline at end of file +}); diff --git a/apps/files_texteditor/js/aceeditor/mode-text-uncompressed.js b/apps/files_external/l10n/.gitkeep similarity index 100% rename from apps/files_texteditor/js/aceeditor/mode-text-uncompressed.js rename to apps/files_external/l10n/.gitkeep diff --git a/apps/files_external/l10n/ca.php b/apps/files_external/l10n/ca.php new file mode 100644 index 0000000000..fc6706381b --- /dev/null +++ b/apps/files_external/l10n/ca.php @@ -0,0 +1,24 @@ + "S'ha concedit l'accés", +"Error configuring Dropbox storage" => "Error en configurar l'emmagatzemament Dropbox", +"Grant access" => "Concedeix accés", +"Fill out all required fields" => "Ompliu els camps requerits", +"Please provide a valid Dropbox app key and secret." => "Proporcioneu una clau d'aplicació i secret vàlids per a Dropbox", +"Error configuring Google Drive storage" => "Error en configurar l'emmagatzemament Google Drive", +"External Storage" => "Emmagatzemament extern", +"Mount point" => "Punt de muntatge", +"Backend" => "Dorsal", +"Configuration" => "Configuració", +"Options" => "Options", +"Applicable" => "Aplicable", +"Add mount point" => "Afegeix punt de muntatge", +"None set" => "Cap d'establert", +"All Users" => "Tots els usuaris", +"Groups" => "Grups", +"Users" => "Usuaris", +"Delete" => "Elimina", +"Enable User External Storage" => "Habilita l'emmagatzemament extern d'usuari", +"Allow users to mount their own external storage" => "Permet als usuaris muntar el seu emmagatzemament extern propi", +"SSL root certificates" => "Certificats SSL root", +"Import Root Certificate" => "Importa certificat root" +); diff --git a/apps/files_external/l10n/cs_CZ.php b/apps/files_external/l10n/cs_CZ.php new file mode 100644 index 0000000000..51951c19bf --- /dev/null +++ b/apps/files_external/l10n/cs_CZ.php @@ -0,0 +1,24 @@ + "Přístup povolen", +"Error configuring Dropbox storage" => "Chyba při nastavení úložiště Dropbox", +"Grant access" => "Povolit přístup", +"Fill out all required fields" => "Vyplňte všechna povinná pole", +"Please provide a valid Dropbox app key and secret." => "Zadejte, prosím, platný klíč a bezpečnostní frázi aplikace Dropbox.", +"Error configuring Google Drive storage" => "Chyba při nastavení úložiště Google Drive", +"External Storage" => "Externí úložiště", +"Mount point" => "Přípojný bod", +"Backend" => "Podpůrná vrstva", +"Configuration" => "Nastavení", +"Options" => "Možnosti", +"Applicable" => "Platný", +"Add mount point" => "Přidat bod připojení", +"None set" => "Nenastaveno", +"All Users" => "Všichni uživatelé", +"Groups" => "Skupiny", +"Users" => "Uživatelé", +"Delete" => "Smazat", +"Enable User External Storage" => "Zapnout externí uživatelské úložiště", +"Allow users to mount their own external storage" => "Povolit uživatelům připojení jejich vlastních externích úložišť", +"SSL root certificates" => "Kořenové certifikáty SSL", +"Import Root Certificate" => "Importovat kořenového certifikátu" +); diff --git a/apps/files_external/l10n/da.php b/apps/files_external/l10n/da.php new file mode 100644 index 0000000000..00a81f3da1 --- /dev/null +++ b/apps/files_external/l10n/da.php @@ -0,0 +1,24 @@ + "Adgang godkendt", +"Error configuring Dropbox storage" => "Fejl ved konfiguration af Dropbox plads", +"Grant access" => "Godkend adgang", +"Fill out all required fields" => "Udfyld alle nødvendige felter", +"Please provide a valid Dropbox app key and secret." => "Angiv venligst en valid Dropbox app nøgle og hemmelighed", +"Error configuring Google Drive storage" => "Fejl ved konfiguration af Google Drive plads", +"External Storage" => "Ekstern opbevaring", +"Mount point" => "Monteringspunkt", +"Backend" => "Backend", +"Configuration" => "Opsætning", +"Options" => "Valgmuligheder", +"Applicable" => "Kan anvendes", +"Add mount point" => "Tilføj monteringspunkt", +"None set" => "Ingen sat", +"All Users" => "Alle brugere", +"Groups" => "Grupper", +"Users" => "Brugere", +"Delete" => "Slet", +"Enable User External Storage" => "Aktiver ekstern opbevaring for brugere", +"Allow users to mount their own external storage" => "Tillad brugere at montere deres egne eksterne opbevaring", +"SSL root certificates" => "SSL-rodcertifikater", +"Import Root Certificate" => "Importer rodcertifikat" +); diff --git a/apps/files_external/l10n/de.php b/apps/files_external/l10n/de.php new file mode 100644 index 0000000000..5d57e5e459 --- /dev/null +++ b/apps/files_external/l10n/de.php @@ -0,0 +1,24 @@ + "Zugriff gestattet", +"Error configuring Dropbox storage" => "Fehler beim Einrichten von Dropbox", +"Grant access" => "Zugriff gestatten", +"Fill out all required fields" => "Bitte alle notwendigen Felder füllen", +"Please provide a valid Dropbox app key and secret." => "Bitte trage einen gültigen Dropbox-App-Key mit Secret ein.", +"Error configuring Google Drive storage" => "Fehler beim Einrichten von Google Drive", +"External Storage" => "Externer Speicher", +"Mount point" => "Mount-Point", +"Backend" => "Backend", +"Configuration" => "Konfiguration", +"Options" => "Optionen", +"Applicable" => "Zutreffend", +"Add mount point" => "Mount-Point hinzufügen", +"None set" => "Nicht definiert", +"All Users" => "Alle Benutzer", +"Groups" => "Gruppen", +"Users" => "Benutzer", +"Delete" => "Löschen", +"Enable User External Storage" => "Externen Speicher für Benutzer aktivieren", +"Allow users to mount their own external storage" => "Erlaubt Benutzern ihre eigenen externen Speicher einzubinden", +"SSL root certificates" => "SSL-Root-Zertifikate", +"Import Root Certificate" => "Root-Zertifikate importieren" +); diff --git a/apps/files_external/l10n/el.php b/apps/files_external/l10n/el.php new file mode 100644 index 0000000000..a1dae9d488 --- /dev/null +++ b/apps/files_external/l10n/el.php @@ -0,0 +1,24 @@ + "Προσβαση παρασχέθηκε", +"Error configuring Dropbox storage" => "Σφάλμα ρυθμίζωντας αποθήκευση Dropbox ", +"Grant access" => "Παροχή πρόσβασης", +"Fill out all required fields" => "Συμπληρώστε όλα τα απαιτούμενα πεδία", +"Please provide a valid Dropbox app key and secret." => "Παρακαλούμε δώστε έγκυρο κλειδί Dropbox και μυστικό.", +"Error configuring Google Drive storage" => "Σφάλμα ρυθμίζωντας αποθήκευση Google Drive ", +"External Storage" => "Εξωτερικό Αποθηκευτικό Μέσο", +"Mount point" => "Σημείο προσάρτησης", +"Backend" => "Σύστημα υποστήριξης", +"Configuration" => "Ρυθμίσεις", +"Options" => "Επιλογές", +"Applicable" => "Εφαρμόσιμο", +"Add mount point" => "Προσθήκη σημείου προσάρτησης", +"None set" => "Κανένα επιλεγμένο", +"All Users" => "Όλοι οι Χρήστες", +"Groups" => "Ομάδες", +"Users" => "Χρήστες", +"Delete" => "Διαγραφή", +"Enable User External Storage" => "Ενεργοποίηση Εξωτερικού Αποθηκευτικού Χώρου Χρήστη", +"Allow users to mount their own external storage" => "Να επιτρέπεται στους χρήστες να προσαρτούν δικό τους εξωτερικό αποθηκευτικό χώρο", +"SSL root certificates" => "Πιστοποιητικά SSL root", +"Import Root Certificate" => "Εισαγωγή Πιστοποιητικού Root" +); diff --git a/apps/files_external/l10n/eo.php b/apps/files_external/l10n/eo.php new file mode 100644 index 0000000000..97453aafed --- /dev/null +++ b/apps/files_external/l10n/eo.php @@ -0,0 +1,24 @@ + "Alirpermeso donita", +"Error configuring Dropbox storage" => "Eraro dum agordado de la memorservo Dropbox", +"Grant access" => "Doni alirpermeson", +"Fill out all required fields" => "Plenigu ĉiujn neprajn kampojn", +"Please provide a valid Dropbox app key and secret." => "Bonvolu provizi ŝlosilon de la aplikaĵo Dropbox validan kaj sekretan.", +"Error configuring Google Drive storage" => "Eraro dum agordado de la memorservo Google Drive", +"External Storage" => "Malena memorilo", +"Mount point" => "Surmetingo", +"Backend" => "Motoro", +"Configuration" => "Agordo", +"Options" => "Malneproj", +"Applicable" => "Aplikebla", +"Add mount point" => "Aldoni surmetingon", +"None set" => "Nenio agordita", +"All Users" => "Ĉiuj uzantoj", +"Groups" => "Grupoj", +"Users" => "Uzantoj", +"Delete" => "Forigi", +"Enable User External Storage" => "Kapabligi malenan memorilon de uzanto", +"Allow users to mount their own external storage" => "Permesi al uzantoj surmeti siajn proprajn malenajn memorilojn", +"SSL root certificates" => "Radikaj SSL-atestoj", +"Import Root Certificate" => "Enporti radikan ateston" +); diff --git a/apps/files_external/l10n/es.php b/apps/files_external/l10n/es.php new file mode 100644 index 0000000000..32a0d89687 --- /dev/null +++ b/apps/files_external/l10n/es.php @@ -0,0 +1,24 @@ + "Acceso garantizado", +"Error configuring Dropbox storage" => "Error configurando el almacenamiento de Dropbox", +"Grant access" => "Garantizar acceso", +"Fill out all required fields" => "Rellenar todos los campos requeridos", +"Please provide a valid Dropbox app key and secret." => "Por favor , proporcione un secreto y una contraseña válida de la app Dropbox.", +"Error configuring Google Drive storage" => "Error configurando el almacenamiento de Google Drive", +"External Storage" => "Almacenamiento externo", +"Mount point" => "Punto de montaje", +"Backend" => "Motor", +"Configuration" => "Configuración", +"Options" => "Opciones", +"Applicable" => "Aplicable", +"Add mount point" => "Añadir punto de montaje", +"None set" => "No se ha configurado", +"All Users" => "Todos los usuarios", +"Groups" => "Grupos", +"Users" => "Usuarios", +"Delete" => "Eliiminar", +"Enable User External Storage" => "Habilitar almacenamiento de usuario externo", +"Allow users to mount their own external storage" => "Permitir a los usuarios montar su propio almacenamiento externo", +"SSL root certificates" => "Raíz de certificados SSL ", +"Import Root Certificate" => "Importar certificado raíz" +); diff --git a/apps/files_external/l10n/es_AR.php b/apps/files_external/l10n/es_AR.php new file mode 100644 index 0000000000..055fbe782e --- /dev/null +++ b/apps/files_external/l10n/es_AR.php @@ -0,0 +1,24 @@ + "Acceso permitido", +"Error configuring Dropbox storage" => "Error al configurar el almacenamiento de Dropbox", +"Grant access" => "Permitir acceso", +"Fill out all required fields" => "Rellenar todos los campos requeridos", +"Please provide a valid Dropbox app key and secret." => "Por favor, proporcioná un secreto y una contraseña válida para la aplicación Dropbox.", +"Error configuring Google Drive storage" => "Error al configurar el almacenamiento de Google Drive", +"External Storage" => "Almacenamiento externo", +"Mount point" => "Punto de montaje", +"Backend" => "Motor", +"Configuration" => "Configuración", +"Options" => "Opciones", +"Applicable" => "Aplicable", +"Add mount point" => "Añadir punto de montaje", +"None set" => "No fue configurado", +"All Users" => "Todos los usuarios", +"Groups" => "Grupos", +"Users" => "Usuarios", +"Delete" => "Borrar", +"Enable User External Storage" => "Habilitar almacenamiento de usuario externo", +"Allow users to mount their own external storage" => "Permitir a los usuarios montar su propio almacenamiento externo", +"SSL root certificates" => "certificados SSL raíz", +"Import Root Certificate" => "Importar certificado raíz" +); diff --git a/apps/files_external/l10n/et_EE.php b/apps/files_external/l10n/et_EE.php new file mode 100644 index 0000000000..280e266433 --- /dev/null +++ b/apps/files_external/l10n/et_EE.php @@ -0,0 +1,18 @@ + "Väline salvestuskoht", +"Mount point" => "Ühenduspunkt", +"Backend" => "Admin", +"Configuration" => "Seadistamine", +"Options" => "Valikud", +"Applicable" => "Rakendatav", +"Add mount point" => "Lisa ühenduspunkt", +"None set" => "Pole määratud", +"All Users" => "Kõik kasutajad", +"Groups" => "Grupid", +"Users" => "Kasutajad", +"Delete" => "Kustuta", +"Enable User External Storage" => "Luba kasutajatele väline salvestamine", +"Allow users to mount their own external storage" => "Luba kasutajatel ühendada külge nende enda välised salvestusseadmed", +"SSL root certificates" => "SSL root sertifikaadid", +"Import Root Certificate" => "Impordi root sertifikaadid" +); diff --git a/apps/files_external/l10n/eu.php b/apps/files_external/l10n/eu.php new file mode 100644 index 0000000000..dccd377b11 --- /dev/null +++ b/apps/files_external/l10n/eu.php @@ -0,0 +1,24 @@ + "Sarrera baimendua", +"Error configuring Dropbox storage" => "Errore bat egon da Dropbox biltegiratzea konfiguratzean", +"Grant access" => "Baimendu sarrera", +"Fill out all required fields" => "Bete eskatutako eremu guztiak", +"Please provide a valid Dropbox app key and secret." => "Mesedez eman baliozkoa den Dropbox app giltza eta sekretua", +"Error configuring Google Drive storage" => "Errore bat egon da Google Drive biltegiratzea konfiguratzean", +"External Storage" => "Kanpoko Biltegiratzea", +"Mount point" => "Montatze puntua", +"Backend" => "Motorra", +"Configuration" => "Konfigurazioa", +"Options" => "Aukerak", +"Applicable" => "Aplikagarria", +"Add mount point" => "Gehitu muntatze puntua", +"None set" => "Ezarri gabe", +"All Users" => "Erabiltzaile guztiak", +"Groups" => "Taldeak", +"Users" => "Erabiltzaileak", +"Delete" => "Ezabatu", +"Enable User External Storage" => "Gaitu erabiltzaileentzako Kanpo Biltegiratzea", +"Allow users to mount their own external storage" => "Baimendu erabiltzaileak bere kanpo biltegiratzeak muntatzen", +"SSL root certificates" => "SSL erro ziurtagiriak", +"Import Root Certificate" => "Inportatu Erro Ziurtagiria" +); diff --git a/apps/files_external/l10n/fi_FI.php b/apps/files_external/l10n/fi_FI.php new file mode 100644 index 0000000000..d7b16e0d3e --- /dev/null +++ b/apps/files_external/l10n/fi_FI.php @@ -0,0 +1,23 @@ + "Pääsy sallittu", +"Error configuring Dropbox storage" => "Virhe Dropbox levyn asetuksia tehtäessä", +"Grant access" => "Salli pääsy", +"Fill out all required fields" => "Täytä kaikki vaaditut kentät", +"Error configuring Google Drive storage" => "Virhe Google Drive levyn asetuksia tehtäessä", +"External Storage" => "Erillinen tallennusväline", +"Mount point" => "Liitospiste", +"Backend" => "Taustaosa", +"Configuration" => "Asetukset", +"Options" => "Valinnat", +"Applicable" => "Sovellettavissa", +"Add mount point" => "Lisää liitospiste", +"None set" => "Ei asetettu", +"All Users" => "Kaikki käyttäjät", +"Groups" => "Ryhmät", +"Users" => "Käyttäjät", +"Delete" => "Poista", +"Enable User External Storage" => "Ota käyttöön ulkopuoliset tallennuspaikat", +"Allow users to mount their own external storage" => "Salli käyttäjien liittää omia erillisiä tallennusvälineitä", +"SSL root certificates" => "SSL-juurivarmenteet", +"Import Root Certificate" => "Tuo juurivarmenne" +); diff --git a/apps/files_external/l10n/fr.php b/apps/files_external/l10n/fr.php new file mode 100644 index 0000000000..90007aafaa --- /dev/null +++ b/apps/files_external/l10n/fr.php @@ -0,0 +1,24 @@ + "Accès autorisé", +"Error configuring Dropbox storage" => "Erreur lors de la configuration du support de stockage Dropbox", +"Grant access" => "Autoriser l'accès", +"Fill out all required fields" => "Veuillez remplir tous les champs requis", +"Please provide a valid Dropbox app key and secret." => "Veuillez fournir une clé d'application (app key) ainsi qu'un mot de passe valides.", +"Error configuring Google Drive storage" => "Erreur lors de la configuration du support de stockage Google Drive", +"External Storage" => "Stockage externe", +"Mount point" => "Point de montage", +"Backend" => "Infrastructure", +"Configuration" => "Configuration", +"Options" => "Options", +"Applicable" => "Disponible", +"Add mount point" => "Ajouter un point de montage", +"None set" => "Aucun spécifié", +"All Users" => "Tous les utilisateurs", +"Groups" => "Groupes", +"Users" => "Utilisateurs", +"Delete" => "Supprimer", +"Enable User External Storage" => "Activer le stockage externe pour les utilisateurs", +"Allow users to mount their own external storage" => "Autoriser les utilisateurs à monter leur propre stockage externe", +"SSL root certificates" => "Certificats racine SSL", +"Import Root Certificate" => "Importer un certificat racine" +); diff --git a/apps/files_external/l10n/gl.php b/apps/files_external/l10n/gl.php new file mode 100644 index 0000000000..3830efb70b --- /dev/null +++ b/apps/files_external/l10n/gl.php @@ -0,0 +1,18 @@ + "Almacenamento externo", +"Mount point" => "Punto de montaxe", +"Backend" => "Almacén", +"Configuration" => "Configuración", +"Options" => "Opcións", +"Applicable" => "Aplicable", +"Add mount point" => "Engadir punto de montaxe", +"None set" => "Non establecido", +"All Users" => "Tódolos usuarios", +"Groups" => "Grupos", +"Users" => "Usuarios", +"Delete" => "Eliminar", +"Enable User External Storage" => "Habilitar almacenamento externo do usuario", +"Allow users to mount their own external storage" => "Permitir aos usuarios montar os seus propios almacenamentos externos", +"SSL root certificates" => "Certificados raíz SSL", +"Import Root Certificate" => "Importar Certificado Raíz" +); diff --git a/apps/files_external/l10n/he.php b/apps/files_external/l10n/he.php new file mode 100644 index 0000000000..12dfa62e7c --- /dev/null +++ b/apps/files_external/l10n/he.php @@ -0,0 +1,13 @@ + "אחסון חיצוני", +"Configuration" => "הגדרות", +"Options" => "אפשרויות", +"All Users" => "כל המשתמשים", +"Groups" => "קבוצות", +"Users" => "משתמשים", +"Delete" => "מחיקה", +"Enable User External Storage" => "הפעלת אחסון חיצוני למשתמשים", +"Allow users to mount their own external storage" => "יאפשר למשתמשים לעגן את האחסון החיצוני שלהם", +"SSL root certificates" => "שורש אישורי אבטחת SSL ", +"Import Root Certificate" => "ייבוא אישור אבטחת שורש" +); diff --git a/apps/files_external/l10n/it.php b/apps/files_external/l10n/it.php new file mode 100644 index 0000000000..49effebdfc --- /dev/null +++ b/apps/files_external/l10n/it.php @@ -0,0 +1,24 @@ + "Accesso consentito", +"Error configuring Dropbox storage" => "Errore durante la configurazione dell'archivio Dropbox", +"Grant access" => "Concedi l'accesso", +"Fill out all required fields" => "Compila tutti i campi richiesti", +"Please provide a valid Dropbox app key and secret." => "Fornisci chiave di applicazione e segreto di Dropbox validi.", +"Error configuring Google Drive storage" => "Errore durante la configurazione dell'archivio Google Drive", +"External Storage" => "Archiviazione esterna", +"Mount point" => "Punto di mount", +"Backend" => "Motore", +"Configuration" => "Configurazione", +"Options" => "Opzioni", +"Applicable" => "Applicabile", +"Add mount point" => "Aggiungi punto di mount", +"None set" => "Nessuna impostazione", +"All Users" => "Tutti gli utenti", +"Groups" => "Gruppi", +"Users" => "Utenti", +"Delete" => "Elimina", +"Enable User External Storage" => "Abilita la memoria esterna dell'utente", +"Allow users to mount their own external storage" => "Consenti agli utenti di montare la propria memoria esterna", +"SSL root certificates" => "Certificati SSL radice", +"Import Root Certificate" => "Importa certificato radice" +); diff --git a/apps/files_external/l10n/ja_JP.php b/apps/files_external/l10n/ja_JP.php new file mode 100644 index 0000000000..92f74ce9f7 --- /dev/null +++ b/apps/files_external/l10n/ja_JP.php @@ -0,0 +1,24 @@ + "アクセスは許可されました", +"Error configuring Dropbox storage" => "Dropboxストレージの設定エラー", +"Grant access" => "アクセスを許可", +"Fill out all required fields" => "すべての必須フィールドを埋めて下さい", +"Please provide a valid Dropbox app key and secret." => "有効なDropboxアプリのキーとパスワードを入力して下さい。", +"Error configuring Google Drive storage" => "Googleドライブストレージの設定エラー", +"External Storage" => "外部ストレージ", +"Mount point" => "マウントポイント", +"Backend" => "バックエンド", +"Configuration" => "設定", +"Options" => "オプション", +"Applicable" => "適用範囲", +"Add mount point" => "マウントポイントを追加", +"None set" => "未設定", +"All Users" => "すべてのユーザ", +"Groups" => "グループ", +"Users" => "ユーザ", +"Delete" => "削除", +"Enable User External Storage" => "ユーザの外部ストレージを有効にする", +"Allow users to mount their own external storage" => "ユーザに外部ストレージのマウントを許可する", +"SSL root certificates" => "SSLルート証明書", +"Import Root Certificate" => "ルート証明書をインポート" +); diff --git a/apps/files_external/l10n/lt_LT.php b/apps/files_external/l10n/lt_LT.php new file mode 100644 index 0000000000..00022aa3d3 --- /dev/null +++ b/apps/files_external/l10n/lt_LT.php @@ -0,0 +1,9 @@ + "Konfigūracija", +"Options" => "Nustatymai", +"None set" => "Nieko nepasirinkta", +"All Users" => "Visi vartotojai", +"Groups" => "Grupės", +"Users" => "Vartotojai", +"Delete" => "Ištrinti" +); diff --git a/apps/files_external/l10n/nb_NO.php b/apps/files_external/l10n/nb_NO.php new file mode 100644 index 0000000000..273b40cf8e --- /dev/null +++ b/apps/files_external/l10n/nb_NO.php @@ -0,0 +1,8 @@ + "Konfigurasjon", +"Options" => "Innstillinger", +"All Users" => "Alle brukere", +"Groups" => "Grupper", +"Users" => "Brukere", +"Delete" => "Slett" +); diff --git a/apps/files_external/l10n/nl.php b/apps/files_external/l10n/nl.php new file mode 100644 index 0000000000..87ab87cfc9 --- /dev/null +++ b/apps/files_external/l10n/nl.php @@ -0,0 +1,24 @@ + "Toegang toegestaan", +"Error configuring Dropbox storage" => "Fout tijdens het configureren van Dropbox opslag", +"Grant access" => "Sta toegang toe", +"Fill out all required fields" => "Vul alle verplichte in", +"Please provide a valid Dropbox app key and secret." => "Geef een geldige Dropbox key en secret.", +"Error configuring Google Drive storage" => "Fout tijdens het configureren van Google Drive opslag", +"External Storage" => "Externe opslag", +"Mount point" => "Aankoppelpunt", +"Backend" => "Backend", +"Configuration" => "Configuratie", +"Options" => "Opties", +"Applicable" => "Van toepassing", +"Add mount point" => "Voeg aankoppelpunt toe", +"None set" => "Niets ingesteld", +"All Users" => "Alle gebruikers", +"Groups" => "Groepen", +"Users" => "Gebruikers", +"Delete" => "Verwijder", +"Enable User External Storage" => "Zet gebruiker's externe opslag aan", +"Allow users to mount their own external storage" => "Sta gebruikers toe om hun eigen externe opslag aan te koppelen", +"SSL root certificates" => "SSL root certificaten", +"Import Root Certificate" => "Importeer root certificaat" +); diff --git a/apps/files_external/l10n/pl.php b/apps/files_external/l10n/pl.php new file mode 100644 index 0000000000..00514e59a5 --- /dev/null +++ b/apps/files_external/l10n/pl.php @@ -0,0 +1,24 @@ + "Dostęp do", +"Error configuring Dropbox storage" => "Wystąpił błąd podczas konfigurowania zasobu Dropbox", +"Grant access" => "Udziel dostępu", +"Fill out all required fields" => "Wypełnij wszystkie wymagane pola", +"Please provide a valid Dropbox app key and secret." => "Proszę podać prawidłowy klucz aplikacji Dropbox i klucz sekretny.", +"Error configuring Google Drive storage" => "Wystąpił błąd podczas konfigurowania zasobu Google Drive", +"External Storage" => "Zewnętrzna zasoby dyskowe", +"Mount point" => "Punkt montowania", +"Backend" => "Zaplecze", +"Configuration" => "Konfiguracja", +"Options" => "Opcje", +"Applicable" => "Zastosowanie", +"Add mount point" => "Dodaj punkt montowania", +"None set" => "Nie ustawione", +"All Users" => "Wszyscy uzytkownicy", +"Groups" => "Grupy", +"Users" => "Użytkownicy", +"Delete" => "Usuń", +"Enable User External Storage" => "Włącz zewnętrzne zasoby dyskowe użytkownika", +"Allow users to mount their own external storage" => "Zezwalaj użytkownikom na montowanie ich własnych zewnętrznych zasobów dyskowych", +"SSL root certificates" => "Główny certyfikat SSL", +"Import Root Certificate" => "Importuj główny certyfikat" +); diff --git a/apps/files_external/l10n/pt_BR.php b/apps/files_external/l10n/pt_BR.php new file mode 100644 index 0000000000..26e927a423 --- /dev/null +++ b/apps/files_external/l10n/pt_BR.php @@ -0,0 +1,24 @@ + "Acesso concedido", +"Error configuring Dropbox storage" => "Erro ao configurar armazenamento do Dropbox", +"Grant access" => "Permitir acesso", +"Fill out all required fields" => "Preencha todos os campos obrigatórios", +"Please provide a valid Dropbox app key and secret." => "Por favor forneça um app key e secret válido do Dropbox", +"Error configuring Google Drive storage" => "Erro ao configurar armazenamento do Google Drive", +"External Storage" => "Armazenamento Externo", +"Mount point" => "Ponto de montagem", +"Backend" => "Backend", +"Configuration" => "Configuração", +"Options" => "Opções", +"Applicable" => "Aplicável", +"Add mount point" => "Adicionar ponto de montagem", +"None set" => "Nenhum definido", +"All Users" => "Todos os Usuários", +"Groups" => "Grupos", +"Users" => "Usuários", +"Delete" => "Remover", +"Enable User External Storage" => "Habilitar Armazenamento Externo do Usuário", +"Allow users to mount their own external storage" => "Permitir usuários a montar seus próprios armazenamentos externos", +"SSL root certificates" => "Certificados SSL raíz", +"Import Root Certificate" => "Importar Certificado Raíz" +); diff --git a/apps/files_external/l10n/pt_PT.php b/apps/files_external/l10n/pt_PT.php new file mode 100644 index 0000000000..4795a51a6b --- /dev/null +++ b/apps/files_external/l10n/pt_PT.php @@ -0,0 +1,24 @@ + "Acesso autorizado", +"Error configuring Dropbox storage" => "Erro ao configurar o armazenamento do Dropbox", +"Grant access" => "Conceder acesso", +"Fill out all required fields" => "Preencha todos os campos obrigatórios", +"Please provide a valid Dropbox app key and secret." => "Por favor forneça uma \"app key\" e \"secret\" do Dropbox válidas.", +"Error configuring Google Drive storage" => "Erro ao configurar o armazenamento do Google Drive", +"External Storage" => "Armazenamento Externo", +"Mount point" => "Ponto de montagem", +"Backend" => "Backend", +"Configuration" => "Configuração", +"Options" => "Opções", +"Applicable" => "Aplicável", +"Add mount point" => "Adicionar ponto de montagem", +"None set" => "Nenhum configurado", +"All Users" => "Todos os utilizadores", +"Groups" => "Grupos", +"Users" => "Utilizadores", +"Delete" => "Apagar", +"Enable User External Storage" => "Activar Armazenamento Externo para o Utilizador", +"Allow users to mount their own external storage" => "Permitir que os utilizadores montem o seu próprio armazenamento externo", +"SSL root certificates" => "Certificados SSL de raiz", +"Import Root Certificate" => "Importar Certificado Root" +); diff --git a/apps/files_external/l10n/ro.php b/apps/files_external/l10n/ro.php new file mode 100644 index 0000000000..6a15278680 --- /dev/null +++ b/apps/files_external/l10n/ro.php @@ -0,0 +1,18 @@ + "Stocare externă", +"Mount point" => "Punctul de montare", +"Backend" => "Backend", +"Configuration" => "Configurație", +"Options" => "Opțiuni", +"Applicable" => "Aplicabil", +"Add mount point" => "Adaugă punct de montare", +"None set" => "Niciunul", +"All Users" => "Toți utilizatorii", +"Groups" => "Grupuri", +"Users" => "Utilizatori", +"Delete" => "Șterge", +"Enable User External Storage" => "Permite stocare externă pentru utilizatori", +"Allow users to mount their own external storage" => "Permite utilizatorilor să monteze stocare externă proprie", +"SSL root certificates" => "Certificate SSL root", +"Import Root Certificate" => "Importă certificat root" +); diff --git a/apps/files_external/l10n/ru.php b/apps/files_external/l10n/ru.php new file mode 100644 index 0000000000..eeef416a84 --- /dev/null +++ b/apps/files_external/l10n/ru.php @@ -0,0 +1,18 @@ + "Внешний носитель", +"Mount point" => "Точка монтирования", +"Backend" => "Подсистема", +"Configuration" => "Конфигурация", +"Options" => "Опции", +"Applicable" => "Применимый", +"Add mount point" => "Добавить точку монтирования", +"None set" => "Не установлено", +"All Users" => "Все пользователи", +"Groups" => "Группы", +"Users" => "Пользователи", +"Delete" => "Удалить", +"Enable User External Storage" => "Включить пользовательские внешние носители", +"Allow users to mount their own external storage" => "Разрешить пользователям монтировать их собственные внешние носители", +"SSL root certificates" => "Корневые сертификаты SSL", +"Import Root Certificate" => "Импортировать корневые сертификаты" +); diff --git a/apps/files_external/l10n/ru_RU.php b/apps/files_external/l10n/ru_RU.php new file mode 100644 index 0000000000..493e3f5bee --- /dev/null +++ b/apps/files_external/l10n/ru_RU.php @@ -0,0 +1,24 @@ + "Доступ разрешен", +"Error configuring Dropbox storage" => "Ошибка при конфигурировании хранилища Dropbox", +"Grant access" => "Предоставить доступ", +"Fill out all required fields" => "Заполните все требуемые поля", +"Please provide a valid Dropbox app key and secret." => "Пожалуйста представьте допустимый ключ приложения Dropbox и пароль.", +"Error configuring Google Drive storage" => "Ошибка настройки хранилища Google Drive", +"External Storage" => "Внешние системы хранения данных", +"Mount point" => "Точка монтирования", +"Backend" => "Бэкэнд", +"Configuration" => "Конфигурация", +"Options" => "Опции", +"Applicable" => "Применимый", +"Add mount point" => "Добавить точку монтирования", +"None set" => "Не задан", +"All Users" => "Все пользователи", +"Groups" => "Группы", +"Users" => "Пользователи", +"Delete" => "Удалить", +"Enable User External Storage" => "Включить пользовательскую внешнюю систему хранения данных", +"Allow users to mount their own external storage" => "Разрешить пользователям монтировать их собственную внешнюю систему хранения данных", +"SSL root certificates" => "Корневые сертификаты SSL", +"Import Root Certificate" => "Импортировать корневые сертификаты" +); diff --git a/apps/files_external/l10n/sk_SK.php b/apps/files_external/l10n/sk_SK.php new file mode 100644 index 0000000000..04257a8014 --- /dev/null +++ b/apps/files_external/l10n/sk_SK.php @@ -0,0 +1,23 @@ + "Prístup povolený", +"Grant access" => "Povoliť prístup", +"Fill out all required fields" => "Vyplňte všetky vyžadované kolónky", +"Please provide a valid Dropbox app key and secret." => "Zadajte platný kľúč aplikácie a heslo Dropbox", +"Error configuring Google Drive storage" => "Chyba pri konfigurácii úložiska Google drive", +"External Storage" => "Externé úložisko", +"Mount point" => "Prípojný bod", +"Backend" => "Backend", +"Configuration" => "Nastavenia", +"Options" => "Možnosti", +"Applicable" => "Aplikovateľné", +"Add mount point" => "Pridať prípojný bod", +"None set" => "Žiadne nastavené", +"All Users" => "Všetci užívatelia", +"Groups" => "Skupiny", +"Users" => "Užívatelia", +"Delete" => "Odstrániť", +"Enable User External Storage" => "Povoliť externé úložisko", +"Allow users to mount their own external storage" => "Povoliť užívateľom pripojiť ich vlastné externé úložisko", +"SSL root certificates" => "Koreňové SSL certifikáty", +"Import Root Certificate" => "Importovať koreňový certifikát" +); diff --git a/apps/files_external/l10n/sl.php b/apps/files_external/l10n/sl.php new file mode 100644 index 0000000000..f455f8c56f --- /dev/null +++ b/apps/files_external/l10n/sl.php @@ -0,0 +1,18 @@ + "Zunanja podatkovna shramba", +"Mount point" => "Priklopna točka", +"Backend" => "Zaledje", +"Configuration" => "Nastavitve", +"Options" => "Možnosti", +"Applicable" => "Se uporablja", +"Add mount point" => "Dodaj priklopno točko", +"None set" => "Ni nastavljeno", +"All Users" => "Vsi uporabniki", +"Groups" => "Skupine", +"Users" => "Uporabniki", +"Delete" => "Izbriši", +"Enable User External Storage" => "Omogoči uporabo zunanje podatkovne shrambe za uporabnike", +"Allow users to mount their own external storage" => "Dovoli uporabnikom priklop lastne zunanje podatkovne shrambe", +"SSL root certificates" => "SSL korenski certifikati", +"Import Root Certificate" => "Uvozi korenski certifikat" +); diff --git a/apps/files_external/l10n/sv.php b/apps/files_external/l10n/sv.php new file mode 100644 index 0000000000..0a5e1c66d9 --- /dev/null +++ b/apps/files_external/l10n/sv.php @@ -0,0 +1,24 @@ + "Åtkomst beviljad", +"Error configuring Dropbox storage" => "Fel vid konfigurering av Dropbox", +"Grant access" => "Bevilja åtkomst", +"Fill out all required fields" => "Fyll i alla obligatoriska fält", +"Please provide a valid Dropbox app key and secret." => "Ange en giltig Dropbox nyckel och hemlighet.", +"Error configuring Google Drive storage" => "Fel vid konfigurering av Google Drive", +"External Storage" => "Extern lagring", +"Mount point" => "Monteringspunkt", +"Backend" => "Källa", +"Configuration" => "Konfiguration", +"Options" => "Alternativ", +"Applicable" => "Tillämplig", +"Add mount point" => "Lägg till monteringspunkt", +"None set" => "Ingen angiven", +"All Users" => "Alla användare", +"Groups" => "Grupper", +"Users" => "Användare", +"Delete" => "Radera", +"Enable User External Storage" => "Aktivera extern lagring för användare", +"Allow users to mount their own external storage" => "Tillåt användare att montera egen extern lagring", +"SSL root certificates" => "SSL rotcertifikat", +"Import Root Certificate" => "Importera rotcertifikat" +); diff --git a/apps/files_external/l10n/th_TH.php b/apps/files_external/l10n/th_TH.php new file mode 100644 index 0000000000..70ab8d3348 --- /dev/null +++ b/apps/files_external/l10n/th_TH.php @@ -0,0 +1,24 @@ + "การเข้าถึงได้รับอนุญาตแล้ว", +"Error configuring Dropbox storage" => "เกิดข้อผิดพลาดในการกำหนดค่าพื้นที่จัดเก็บข้อมูล Dropbox", +"Grant access" => "อนุญาตให้เข้าถึงได้", +"Fill out all required fields" => "กรอกข้อมูลในช่องข้อมูลที่จำเป็นต้องกรอกทั้งหมด", +"Please provide a valid Dropbox app key and secret." => "กรุณากรอกรหัส app key ของ Dropbox และรหัสลับ", +"Error configuring Google Drive storage" => "เกิดข้อผิดพลาดในการกำหนดค่าการจัดเก็บข้อมูลในพื้นที่ของ Google Drive", +"External Storage" => "พื้นทีจัดเก็บข้อมูลจากภายนอก", +"Mount point" => "จุดชี้ตำแหน่ง", +"Backend" => "ด้านหลังระบบ", +"Configuration" => "การกำหนดค่า", +"Options" => "ตัวเลือก", +"Applicable" => "สามารถใช้งานได้", +"Add mount point" => "เพิ่มจุดชี้ตำแหน่ง", +"None set" => "ยังไม่มีการกำหนด", +"All Users" => "ผู้ใช้งานทั้งหมด", +"Groups" => "กลุ่ม", +"Users" => "ผู้ใช้งาน", +"Delete" => "ลบ", +"Enable User External Storage" => "เปิดให้มีการใช้พื้นที่จัดเก็บข้อมูลของผู้ใช้งานจากภายนอกได้", +"Allow users to mount their own external storage" => "อนุญาตให้ผู้ใช้งานสามารถชี้ตำแหน่งไปที่พื้นที่จัดเก็บข้อมูลภายนอกของตนเองได้", +"SSL root certificates" => "ใบรับรองความปลอดภัยด้วยระบบ SSL จาก Root", +"Import Root Certificate" => "นำเข้าข้อมูลใบรับรองความปลอดภัยจาก Root" +); diff --git a/apps/files_external/l10n/uk.php b/apps/files_external/l10n/uk.php new file mode 100644 index 0000000000..79920b9014 --- /dev/null +++ b/apps/files_external/l10n/uk.php @@ -0,0 +1,5 @@ + "Групи", +"Users" => "Користувачі", +"Delete" => "Видалити" +); diff --git a/apps/files_external/l10n/vi.php b/apps/files_external/l10n/vi.php new file mode 100644 index 0000000000..dd616e9115 --- /dev/null +++ b/apps/files_external/l10n/vi.php @@ -0,0 +1,18 @@ + "Lưu trữ ngoài", +"Mount point" => "Điểm gắn", +"Backend" => "phụ trợ", +"Configuration" => "Cấu hình", +"Options" => "Tùy chọn", +"Applicable" => "Áp dụng", +"Add mount point" => "Thêm điểm lắp", +"None set" => "không", +"All Users" => "Tất cả người dùng", +"Groups" => "Nhóm", +"Users" => "Người dùng", +"Delete" => "Xóa", +"Enable User External Storage" => "Kích hoạt tính năng lưu trữ ngoài", +"Allow users to mount their own external storage" => "Cho phép người dùng kết nối với lưu trữ riêng bên ngoài của họ", +"SSL root certificates" => "Chứng chỉ SSL root", +"Import Root Certificate" => "Nhập Root Certificate" +); diff --git a/apps/files_external/l10n/zh_CN.GB2312.php b/apps/files_external/l10n/zh_CN.GB2312.php new file mode 100644 index 0000000000..47983d3d7d --- /dev/null +++ b/apps/files_external/l10n/zh_CN.GB2312.php @@ -0,0 +1,24 @@ + "已授予权限", +"Error configuring Dropbox storage" => "配置 Dropbox 存储出错", +"Grant access" => "授予权限", +"Fill out all required fields" => "填充全部必填字段", +"Please provide a valid Dropbox app key and secret." => "请提供一个有效的 Dropbox app key 和 secret。", +"Error configuring Google Drive storage" => "配置 Google Drive 存储失败", +"External Storage" => "外部存储", +"Mount point" => "挂载点", +"Backend" => "后端", +"Configuration" => "配置", +"Options" => "选项", +"Applicable" => "可应用", +"Add mount point" => "添加挂载点", +"None set" => "未设置", +"All Users" => "所有用户", +"Groups" => "群组", +"Users" => "用户", +"Delete" => "删除", +"Enable User External Storage" => "启用用户外部存储", +"Allow users to mount their own external storage" => "允许用户挂载他们的外部存储", +"SSL root certificates" => "SSL 根证书", +"Import Root Certificate" => "导入根证书" +); diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 9feb490dac..41ec3c70b4 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -29,7 +29,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { private $objects = array(); private static $tempFiles = array(); - + // TODO options: storage class, encryption server side, encrypt before upload? public function __construct($params) { @@ -134,12 +134,12 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { return false; } - public function is_readable($path) { + public function isReadable($path) { // TODO Check acl and determine who grantee is return true; } - public function is_writable($path) { + public function isUpdatable($path) { // TODO Check acl and determine who grantee is return true; } @@ -216,7 +216,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { } public function free_space($path) { - // Infinite? + // Infinite? return false; } @@ -232,5 +232,3 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { } } - -?> \ No newline at end of file diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 5630df77a9..068475783c 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -41,9 +41,9 @@ class OC_Mount_Config { return array( 'OC_Filestorage_Local' => array('backend' => 'Local', 'configuration' => array('datadir' => 'Location')), 'OC_Filestorage_AmazonS3' => array('backend' => 'Amazon S3', 'configuration' => array('key' => 'Key', 'secret' => '*Secret', 'bucket' => 'Bucket')), - 'OC_Filestorage_Dropbox' => array('backend' => 'Dropbox', 'configuration' => array('app_key' => 'App key', 'app_secret' => 'App secret', 'token' => '#token', 'token_secret' => '#token_secret'), 'custom' => 'dropbox'), + 'OC_Filestorage_Dropbox' => array('backend' => 'Dropbox', 'configuration' => array('configured' => '#configured','app_key' => 'App key', 'app_secret' => 'App secret', 'token' => '#token', 'token_secret' => '#token_secret'), 'custom' => 'dropbox'), 'OC_Filestorage_FTP' => array('backend' => 'FTP', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure ftps://')), - 'OC_Filestorage_Google' => array('backend' => 'Google Drive', 'configuration' => array('token' => '#token', 'token_secret' => '#token secret'), 'custom' => 'google'), + 'OC_Filestorage_Google' => array('backend' => 'Google Drive', 'configuration' => array('configured' => '#configured', 'token' => '#token', 'token_secret' => '#token secret'), 'custom' => 'google'), 'OC_Filestorage_SWIFT' => array('backend' => 'OpenStack Swift', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'token' => '*Token', 'root' => '&Root', 'secure' => '!Secure ftps://')), 'OC_Filestorage_SMB' => array('backend' => 'SMB', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'share' => 'Share', 'root' => '&Root')), 'OC_Filestorage_DAV' => array('backend' => 'WebDAV', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure https://')) @@ -109,7 +109,22 @@ class OC_Mount_Config { return $personal; } - + /** + * Add directory for mount point to the filesystem + * @param OC_Fileview instance $view + * @param string path to mount point + */ + private static function addMountPointDirectory($view, $path) { + $dir = ''; + foreach ( explode('/', $path) as $pathPart) { + $dir = $dir.'/'.$pathPart; + if ( !$view->file_exists($dir)) { + $view->mkdir($dir); + } + } + } + + /** * Add a mount point to the filesystem * @param string Mount point @@ -127,8 +142,33 @@ class OC_Mount_Config { if ($applicable != OCP\User::getUser() || $class == 'OC_Filestorage_Local') { return false; } + $view = new OC_FilesystemView('/'.OCP\User::getUser().'/files'); + self::addMountPointDirectory($view, ltrim($mountPoint, '/')); $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); } else { + $view = new OC_FilesystemView('/'); + switch ($mountType) { + case 'user': + if ($applicable == "all") { + $users = OCP\User::getUsers(); + foreach ( $users as $user ) { + $path = $user.'/files/'.ltrim($mountPoint, '/'); + self::addMountPointDirectory($view, $path); + } + } else { + $path = $applicable.'/files/'.ltrim($mountPoint, '/'); + self::addMountPointDirectory($view, $path); + } + break; + case 'group' : + $groupMembers = OC_Group::usersInGroups(array($applicable)); + foreach ( $groupMembers as $user ) { + $path = $user.'/files/'.ltrim($mountPoint, '/'); + self::addMountPointDirectory($view, $path); + } + break; + } + $mountPoint = '/$user/files/'.ltrim($mountPoint, '/'); } $mount = array($applicable => array($mountPoint => array('class' => $class, 'options' => $classOptions))); @@ -186,7 +226,7 @@ class OC_Mount_Config { */ private static function readData($isPersonal) { if ($isPersonal) { - $file = OC::$SERVERROOT.'/data/'.OCP\User::getUser().'/mount.php'; + $file = OC_User::getHome(OCP\User::getUser()).'/mount.php'; } else { $file = OC::$SERVERROOT.'/config/mount.php'; } @@ -206,7 +246,7 @@ class OC_Mount_Config { */ private static function writeData($isPersonal, $data) { if ($isPersonal) { - $file = OC::$SERVERROOT.'/data/'.OCP\User::getUser().'/mount.php'; + $file = OC_User::getHome(OCP\User::getUser()).'/mount.php'; } else { $file = OC::$SERVERROOT.'/config/mount.php'; } @@ -217,7 +257,7 @@ class OC_Mount_Config { $content .= "\t\t'".$group."' => array (\n"; foreach ($mounts as $mountPoint => $mount) { $content .= "\t\t\t'".$mountPoint."' => ".str_replace("\n", '', var_export($mount, true)).",\n"; - + } $content .= "\t\t),\n"; } @@ -237,47 +277,49 @@ class OC_Mount_Config { $content .= ");\n?>"; @file_put_contents($file, $content); } - - /** - * Returns all user uploaded ssl root certificates - * @return array - */ + + /** + * Returns all user uploaded ssl root certificates + * @return array + */ public static function getCertificates() { $view = \OCP\Files::getStorage('files_external'); $path=\OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/'; if (!is_dir($path)) mkdir($path); $result = array(); $handle = opendir($path); + if (!$handle) { + return array(); + } while (false !== ($file = readdir($handle))) { if($file != '.' && $file != '..') $result[] = $file; } return $result; } - + /** * creates certificate bundle */ public static function createCertificateBundle() { - $view = \OCP\Files::getStorage("files_external"); - $path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath(""); - - $certs = OC_Mount_Config::getCertificates(); - $fh_certs = fopen($path."/rootcerts.crt", 'w'); - foreach ($certs as $cert) { - $file=$path.'/uploads/'.$cert; - $fh = fopen($file, "r"); - $data = fread($fh, filesize($file)); + $view = \OCP\Files::getStorage("files_external"); + $path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath(""); + + $certs = OC_Mount_Config::getCertificates(); + $fh_certs = fopen($path."/rootcerts.crt", 'w'); + foreach ($certs as $cert) { + $file=$path.'/uploads/'.$cert; + $fh = fopen($file, "r"); + $data = fread($fh, filesize($file)); fclose($fh); - if (strpos($data, 'BEGIN CERTIFICATE')) { + if (strpos($data, 'BEGIN CERTIFICATE')) { fwrite($fh_certs, $data); - } - } - + fwrite($fh_certs, "\r\n"); + } + } + fclose($fh_certs); - + return true; - } + } } - -?> \ No newline at end of file diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 35663d431f..c822083270 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -25,17 +25,25 @@ require_once 'Dropbox/autoload.php'; class OC_Filestorage_Dropbox extends OC_Filestorage_Common { private $dropbox; + private $root; private $metaData = array(); private static $tempFiles = array(); public function __construct($params) { - $oauth = new Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']); - $oauth->setToken($params['token'], $params['token_secret']); - $this->dropbox = new Dropbox_API($oauth, 'dropbox'); + if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['app_key']) && isset($params['app_secret']) && isset($params['token']) && isset($params['token_secret'])) { + $this->root=isset($params['root'])?$params['root']:''; + $oauth = new Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']); + $oauth->setToken($params['token'], $params['token_secret']); + $this->dropbox = new Dropbox_API($oauth, 'dropbox'); + $this->mkdir(''); + } else { + throw new Exception('Creating OC_Filestorage_Dropbox storage failed'); + } } private function getMetaData($path, $list = false) { + $path = $this->root.$path; if (!$list && isset($this->metaData[$path])) { return $this->metaData[$path]; } else { @@ -43,6 +51,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { try { $response = $this->dropbox->getMetaData($path); } catch (Exception $exception) { + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); return false; } if ($response && isset($response['contents'])) { @@ -63,6 +72,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { $this->metaData[$path] = $response; return $response; } catch (Exception $exception) { + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); return false; } } @@ -70,10 +80,12 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { } public function mkdir($path) { + $path = $this->root.$path; try { $this->dropbox->createFolder($path); return true; } catch (Exception $exception) { + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); return false; } } @@ -118,11 +130,11 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { return false; } - public function is_readable($path) { + public function isReadable($path) { return $this->file_exists($path); } - public function is_writable($path) { + public function isUpdatable($path) { return $this->file_exists($path); } @@ -137,33 +149,42 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { } public function unlink($path) { + $path = $this->root.$path; try { $this->dropbox->delete($path); return true; } catch (Exception $exception) { + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); return false; } } public function rename($path1, $path2) { + $path1 = $this->root.$path1; + $path2 = $this->root.$path2; try { $this->dropbox->move($path1, $path2); return true; } catch (Exception $exception) { + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); return false; } } public function copy($path1, $path2) { + $path1 = $this->root.$path1; + $path2 = $this->root.$path2; try { $this->dropbox->copy($path1, $path2); return true; } catch (Exception $exception) { + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); return false; } } public function fopen($path, $mode) { + $path = $this->root.$path; switch ($mode) { case 'r': case 'rb': @@ -173,6 +194,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { file_put_contents($tmpFile, $data); return fopen($tmpFile, 'r'); } catch (Exception $exception) { + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); return false; } case 'w': @@ -208,10 +230,10 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { if (isset(self::$tempFiles[$tmpFile])) { $handle = fopen($tmpFile, 'r'); try { - $response = $this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle); + $this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle); unlink($tmpFile); } catch (Exception $exception) { - + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); } } } @@ -230,6 +252,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { $info = $this->dropbox->getAccountInfo(); return $info['quota_info']['quota'] - $info['quota_info']['normal']; } catch (Exception $exception) { + OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR); return false; } } @@ -239,5 +262,3 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { } } - -?> \ No newline at end of file diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 4d5ae670de..261141455c 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -14,19 +14,20 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{ private $root; private static $tempFiles=array(); - - public function __construct($params){ + + public function __construct($params) { $this->host=$params['host']; $this->user=$params['user']; $this->password=$params['password']; $this->secure=isset($params['secure'])?(bool)$params['secure']:false; $this->root=isset($params['root'])?$params['root']:'/'; - if(!$this->root || $this->root[0]!='/'){ + if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } - //create the root folder if necesary - mkdir($this->constructUrl('')); + if (!$this->is_dir('')) { + $this->mkdir(''); + } } /** @@ -34,16 +35,16 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{ * @param string path * @return string */ - public function constructUrl($path){ + public function constructUrl($path) { $url='ftp'; - if($this->secure){ + if($this->secure) { $url.='s'; } $url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path; return $url; } - public function fopen($path,$mode){ - switch($mode){ + public function fopen($path,$mode) { + switch($mode) { case 'r': case 'rb': case 'w': @@ -62,14 +63,14 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{ case 'c': case 'c+': //emulate these - if(strrpos($path,'.')!==false){ + if(strrpos($path,'.')!==false) { $ext=substr($path,strrpos($path,'.')); }else{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); - if($this->file_exists($path)){ + if($this->file_exists($path)) { $this->getFile($path,$tmpFile); } self::$tempFiles[$tmpFile]=$path; @@ -77,8 +78,8 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{ } } - public function writeBack($tmpFile){ - if(isset(self::$tempFiles[$tmpFile])){ + public function writeBack($tmpFile) { + if(isset(self::$tempFiles[$tmpFile])) { $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]); unlink($tmpFile); } diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 41b560ae84..9b83dcee53 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -31,13 +31,17 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { private static $tempFiles = array(); - public function __construct($arguments) { - $consumer_key = isset($arguments['consumer_key']) ? $arguments['consumer_key'] : 'anonymous'; - $consumer_secret = isset($arguments['consumer_secret']) ? $arguments['consumer_secret'] : 'anonymous'; - $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); - $this->oauth_token = new OAuthToken($arguments['token'], $arguments['token_secret']); - $this->sig_method = new OAuthSignatureMethod_HMAC_SHA1(); - $this->entries = array(); + public function __construct($params) { + if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['token']) && isset($params['token_secret'])) { + $consumer_key = isset($params['consumer_key']) ? $params['consumer_key'] : 'anonymous'; + $consumer_secret = isset($params['consumer_secret']) ? $params['consumer_secret'] : 'anonymous'; + $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); + $this->oauth_token = new OAuthToken($params['token'], $params['token_secret']); + $this->sig_method = new OAuthSignatureMethod_HMAC_SHA1(); + $this->entries = array(); + } else { + throw new Exception('Creating OC_Filestorage_Google storage failed'); + } } private function sendRequest($uri, $httpMethod, $postData = null, $extraHeaders = null, $isDownload = false, $returnHeaders = false, $isContentXML = true, $returnHTTPCode = false) { @@ -115,7 +119,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } } } - return false; + return false; } private function getFeed($feedUri, $httpMethod, $postData = null) { @@ -170,7 +174,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { return 'html'; } } - + public function mkdir($path) { $collection = dirname($path); @@ -178,7 +182,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { if ($collection == '/' || $collection == '\.' || $collection == '.') { $uri = 'https://docs.google.com/feeds/default/private/full'; // Get parent content link - } else if ($dom = $this->getResource(basename($dir))) { + } else if ($dom = $this->getResource(basename($collection))) { $uri = $dom->getElementsByTagName('content')->item(0)->getAttribute('src'); } if (isset($uri)) { @@ -250,7 +254,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } else if ($entry = $this->getResource($path)) { // NOTE: Native resources don't have a file size $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue; -// if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue)) +// if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue)) // $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue); $stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue); $stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue); @@ -280,11 +284,11 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { return false; } - public function is_readable($path) { + public function isReadable($path) { return true; } - public function is_writable($path) { + public function isUpdatable($path) { if ($path == '' || $path == '/') { return true; } else if ($entry = $this->getResource($path)) { @@ -300,7 +304,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } return false; } - + public function file_exists($path) { if ($path == '' || $path == '/') { return true; @@ -309,7 +313,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } return false; } - + public function unlink($path) { // Get resource self link to trash resource if ($entry = $this->getResource($path)) { @@ -341,7 +345,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { break; } } - $title = basename($path); + $title = basename($path2); // Construct post data $postData = ''; $postData .= ''; @@ -352,13 +356,13 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } else { // Move to different collection if ($collectionEntry = $this->getResource($collection)) { - $feedUri = $colelctionEntry->getElementsByTagName('content')->item(0)->getAttribute('src'); + $feedUri = $collectionEntry->getElementsByTagName('content')->item(0)->getAttribute('src'); // Construct post data $postData = ''; $postData .= ''; $postData .= ''.$entry->getElementsByTagName('id')->item(0).''; $postData .= ''; - $this->sendRequest($uri, 'POST', $postData); + $this->sendRequest($feedUri, 'POST', $postData); return true; } } @@ -424,7 +428,6 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } } if (!isset($uploadUri) && $entry) { - $etag = $entry->getAttribute('gd:etag'); $links = $entry->getElementsByTagName('link'); foreach ($links as $link) { if ($link->getAttribute('rel') == 'http://schemas.google.com/g/2005#resumable-create-media') { @@ -479,7 +482,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { // TODO Wait for resource entry } } - + public function getMimeType($path, $entry = null) { // Entry can be passed, because extension is required for opendir and the entry can't be cached without the extension if ($entry == null) { @@ -519,7 +522,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } return false; } - + public function free_space($path) { if ($dom = $this->getFeed('https://docs.google.com/feeds/metadata/default', 'GET')) { // NOTE: Native Google Docs resources don't count towards quota @@ -529,9 +532,9 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } return false; } - + public function touch($path, $mtime = null) { - + } } \ No newline at end of file diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index 5e34deb233..eed2582dc9 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -require_once('smb4php/smb.php'); +require_once 'smb4php/smb.php'; class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{ private $password; @@ -15,42 +15,40 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{ private $root; private $share; - private static $tempFiles=array(); - - public function __construct($params){ + public function __construct($params) { $this->host=$params['host']; $this->user=$params['user']; $this->password=$params['password']; $this->share=$params['share']; $this->root=isset($params['root'])?$params['root']:'/'; - if(!$this->root || $this->root[0]!='/'){ + if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } - if(substr($this->root,-1,1)!='/'){ + if(substr($this->root,-1,1)!='/') { $this->root.='/'; } - if(!$this->share || $this->share[0]!='/'){ + if(!$this->share || $this->share[0]!='/') { $this->share='/'.$this->share; } - if(substr($this->share,-1,1)=='/'){ + if(substr($this->share,-1,1)=='/') { $this->share=substr($this->share,0,-1); } //create the root folder if necesary - if(!$this->is_dir('')){ + if(!$this->is_dir('')) { $this->mkdir(''); } } - public function constructUrl($path){ - if(substr($path,-1)=='/'){ + public function constructUrl($path) { + if(substr($path,-1)=='/') { $path=substr($path,0,-1); } return 'smb://'.$this->user.':'.$this->password.'@'.$this->host.$this->share.$this->root.$path; } - public function stat($path){ - if(!$path and $this->root=='/'){//mtime doesn't work for shares + public function stat($path) { + if(!$path and $this->root=='/') {//mtime doesn't work for shares $mtime=$this->shareMTime(); $stat=stat($this->constructUrl($path)); $stat['mtime']=$mtime; @@ -60,8 +58,8 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{ } } - public function filetype($path){ - return (bool)@$this->opendir($path);//using opendir causes the same amount of requests and caches the content of the folder in one go + public function filetype($path) { + return (bool)@$this->opendir($path) ? 'dir' : 'file';//using opendir causes the same amount of requests and caches the content of the folder in one go } /** @@ -69,8 +67,8 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{ * @param int $time * @return bool */ - public function hasUpdated($path,$time){ - if(!$path and $this->root=='/'){ + public function hasUpdated($path,$time) { + if(!$path and $this->root=='/') { //mtime doesn't work for shares, but giving the nature of the backend, doing a full update is still just fast enough return true; }else{ @@ -82,13 +80,13 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{ /** * get the best guess for the modification time of the share */ - private function shareMTime(){ + private function shareMTime() { $dh=$this->opendir(''); $lastCtime=0; - while($file=readdir($dh)){ - if($file!='.' and $file!='..'){ + while($file=readdir($dh)) { + if($file!='.' and $file!='..') { $ctime=$this->filemtime($file); - if($ctime>$lastCtime){ + if($ctime>$lastCtime) { $lastCtime=$ctime; } } diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index 7d56445361..7263ef2325 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -10,12 +10,12 @@ abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{ abstract public function constructUrl($path); - public function mkdir($path){ + public function mkdir($path) { return mkdir($this->constructUrl($path)); } - public function rmdir($path){ - if($this->file_exists($path)){ + public function rmdir($path) { + if($this->file_exists($path)) { $succes=rmdir($this->constructUrl($path)); clearstatcache(); return $succes; @@ -24,42 +24,42 @@ abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{ } } - public function opendir($path){ + public function opendir($path) { return opendir($this->constructUrl($path)); } - public function filetype($path){ + public function filetype($path) { return filetype($this->constructUrl($path)); } - public function is_readable($path){ + public function isReadable($path) { return true;//not properly supported } - public function is_writable($path){ + public function isUpdatable($path) { return true;//not properly supported } - public function file_exists($path){ + public function file_exists($path) { return file_exists($this->constructUrl($path)); } - public function unlink($path){ + public function unlink($path) { $succes=unlink($this->constructUrl($path)); clearstatcache(); return $succes; } - public function fopen($path,$mode){ + public function fopen($path,$mode) { return fopen($this->constructUrl($path),$mode); } - public function free_space($path){ + public function free_space($path) { return 0; } - public function touch($path,$mtime=null){ - if(is_null($mtime)){ + public function touch($path,$mtime=null) { + if(is_null($mtime)) { $fh=$this->fopen($path,'a'); fwrite($fh,''); fclose($fh); @@ -68,19 +68,19 @@ abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{ } } - public function getFile($path,$target){ + public function getFile($path,$target) { return copy($this->constructUrl($path),$target); } - public function uploadFile($path,$target){ + public function uploadFile($path,$target) { return copy($path,$this->constructUrl($target)); } - public function rename($path1,$path2){ + public function rename($path1,$path2) { return rename($this->constructUrl($path1),$this->constructUrl($path2)); } - public function stat($path){ + public function stat($path) { return stat($this->constructUrl($path)); } diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index 58b95a6ae0..4b0b8c25fd 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -require_once('php-cloudfiles/cloudfiles.php'); +require_once 'php-cloudfiles/cloudfiles.php'; class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ private $host; @@ -38,8 +38,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string path * @return string */ - private function getContainerName($path){ - $path=trim($this->root.$path,'/'); + private function getContainerName($path) { + $path=trim(trim($this->root,'/')."/".$path,'/.'); return str_replace('/','\\',$path); } @@ -48,18 +48,18 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string path * @return CF_Container */ - private function getContainer($path){ - if($path=='' or $path=='/'){ + private function getContainer($path) { + if($path=='' or $path=='/') { return $this->rootContainer; } - if(isset($this->containers[$path])){ + if(isset($this->containers[$path])) { return $this->containers[$path]; } try{ $container=$this->conn->get_container($this->getContainerName($path)); $this->containers[$path]=$container; return $container; - }catch(NoSuchContainerException $e){ + }catch(NoSuchContainerException $e) { return null; } } @@ -69,15 +69,15 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string path * @return CF_Container */ - private function createContainer($path){ - if($path=='' or $path=='/'){ + private function createContainer($path) { + if($path=='' or $path=='/' or $path=='.') { return $this->conn->create_container($this->getContainerName($path)); } $parent=dirname($path); - if($parent=='' or $parent=='/'){ + if($parent=='' or $parent=='/' or $parent=='.') { $parentContainer=$this->rootContainer; }else{ - if(!$this->containerExists($parent)){ + if(!$this->containerExists($parent)) { $parentContainer=$this->createContainer($parent); }else{ $parentContainer=$this->getContainer($parent); @@ -92,19 +92,22 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string path * @return CF_Object */ - private function getObject($path){ - if(isset($this->objects[$path])){ + private function getObject($path) { + if(isset($this->objects[$path])) { return $this->objects[$path]; } $container=$this->getContainer(dirname($path)); - if(is_null($container)){ + if(is_null($container)) { return null; }else{ + if ($path=="/" or $path=='') { + return null; + } try{ $obj=$container->get_object(basename($path)); $this->objects[$path]=$obj; return $obj; - }catch(NoSuchObjectException $e){ + }catch(NoSuchObjectException $e) { return null; } } @@ -115,12 +118,12 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param CF_Container * @return array */ - private function getObjects($container){ - if(is_null($container)){ + private function getObjects($container) { + if(is_null($container)) { return array(); }else{ $files=$container->get_objects(); - foreach($files as &$file){ + foreach($files as &$file) { $file=$file->name; } return $files; @@ -132,10 +135,10 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string path * @return CF_Object */ - private function createObject($path){ + private function createObject($path) { $container=$this->getContainer(dirname($path)); - if(!is_null($container)){ - $container=$this->createContainer($path); + if(!is_null($container)) { + $container=$this->createContainer(dirname($path)); } return $container->create_object(basename($path)); } @@ -145,7 +148,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string * @return bool */ - private function objectExists($path){ + private function objectExists($path) { return !is_null($this->getObject($path)); } @@ -154,7 +157,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string path * @return bool */ - private function containerExists($path){ + private function containerExists($path) { return !is_null($this->getContainer($path)); } @@ -163,18 +166,18 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param CF_Container container * @return array */ - private function getSubContainers($container){ + private function getSubContainers($container) { $tmpFile=OCP\Files::tmpFile(); $obj=$this->getSubContainerFile($container); try{ $obj->save_to_filename($tmpFile); - }catch(Exception $e){ + }catch(Exception $e) { return array(); } $obj->save_to_filename($tmpFile); $containers=file($tmpFile); unlink($tmpFile); - foreach($containers as &$sub){ + foreach($containers as &$sub) { $sub=trim($sub); } return $containers; @@ -186,8 +189,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string name * @return bool */ - private function addSubContainer($container,$name){ - if(!$name){ + private function addSubContainer($container,$name) { + if(!$name) { return false; } $tmpFile=OCP\Files::tmpFile(); @@ -195,17 +198,17 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ try{ $obj->save_to_filename($tmpFile); $containers=file($tmpFile); - foreach($containers as &$sub){ + foreach($containers as &$sub) { $sub=trim($sub); } - if(array_search($name,$containers)!==false){ + if(array_search($name,$containers)!==false) { unlink($tmpFile); return false; }else{ $fh=fopen($tmpFile,'a'); fwrite($fh,$name."\n"); } - }catch(Exception $e){ + }catch(Exception $e) { $containers=array(); file_put_contents($tmpFile,$name."\n"); } @@ -221,8 +224,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param string name * @return bool */ - private function removeSubContainer($container,$name){ - if(!$name){ + private function removeSubContainer($container,$name) { + if(!$name) { return false; } $tmpFile=OCP\Files::tmpFile(); @@ -230,14 +233,14 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ try{ $obj->save_to_filename($tmpFile); $containers=file($tmpFile); - }catch(Exception $e){ + }catch(Exception $e) { return false; } - foreach($containers as &$sub){ + foreach($containers as &$sub) { $sub=trim($sub); } $i=array_search($name,$containers); - if($i===false){ + if($i===false) { unlink($tmpFile); return false; }else{ @@ -255,29 +258,29 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * @param CF_Container container * @return CF_Object */ - private function getSubContainerFile($container){ + private function getSubContainerFile($container) { try{ return $container->get_object(self::SUBCONTAINER_FILE); - }catch(NoSuchObjectException $e){ + }catch(NoSuchObjectException $e) { return $container->create_object(self::SUBCONTAINER_FILE); } } - public function __construct($params){ + public function __construct($params) { $this->token=$params['token']; $this->host=$params['host']; $this->user=$params['user']; $this->root=isset($params['root'])?$params['root']:'/'; $this->secure=isset($params['secure'])?(bool)$params['secure']:true; - if(!$this->root || $this->root[0]!='/'){ + if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } $this->auth = new CF_Authentication($this->user, $this->token, null, $this->host); $this->auth->authenticate(); - + $this->conn = new CF_Connection($this->auth); - if(!$this->containerExists($this->root)){ + if(!$this->containerExists('/')) { $this->rootContainer=$this->createContainer('/'); }else{ $this->rootContainer=$this->getContainer('/'); @@ -285,8 +288,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ } - public function mkdir($path){ - if($this->containerExists($path)){ + public function mkdir($path) { + if($this->containerExists($path)) { return false; }else{ $this->createContainer($path); @@ -294,30 +297,30 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ } } - public function rmdir($path){ - if(!$this->containerExists($path)){ + public function rmdir($path) { + if(!$this->containerExists($path)) { return false; }else{ $this->emptyContainer($path); - if($path!='' and $path!='/'){ + if($path!='' and $path!='/') { $parentContainer=$this->getContainer(dirname($path)); $this->removeSubContainer($parentContainer,basename($path)); } - + $this->conn->delete_container($this->getContainerName($path)); unset($this->containers[$path]); return true; } } - private function emptyContainer($path){ + private function emptyContainer($path) { $container=$this->getContainer($path); - if(is_null($container)){ + if(is_null($container)) { return; } $subContainers=$this->getSubContainers($container); - foreach($subContainers as $sub){ - if($sub){ + foreach($subContainers as $sub) { + if($sub) { $this->emptyContainer($path.'/'.$sub); $this->conn->delete_container($this->getContainerName($path.'/'.$sub)); unset($this->containers[$path.'/'.$sub]); @@ -325,17 +328,17 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ } $objects=$this->getObjects($container); - foreach($objects as $object){ + foreach($objects as $object) { $container->delete_object($object); unset($this->objects[$path.'/'.$object]); } } - public function opendir($path){ + public function opendir($path) { $container=$this->getContainer($path); $files=$this->getObjects($container); $i=array_search(self::SUBCONTAINER_FILE,$files); - if($i!==false){ + if($i!==false) { unset($files[$i]); } $subContainers=$this->getSubContainers($container); @@ -345,43 +348,43 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ return opendir('fakedir://'.$id); } - public function filetype($path){ - if($this->containerExists($path)){ + public function filetype($path) { + if($this->containerExists($path)) { return 'dir'; }else{ return 'file'; } } - public function is_readable($path){ + public function isReadable($path) { return true; } - public function is_writable($path){ + public function isUpdatable($path) { return true; } - public function file_exists($path){ - if($this->is_dir($path)){ + public function file_exists($path) { + if($this->is_dir($path)) { return true; }else{ return $this->objectExists($path); } } - public function file_get_contents($path){ + public function file_get_contents($path) { $obj=$this->getObject($path); - if(is_null($obj)){ + if(is_null($obj)) { return false; } return $obj->read(); } - public function file_put_contents($path,$content){ + public function file_put_contents($path,$content) { $obj=$this->getObject($path); - if(is_null($obj)){ + if(is_null($obj)) { $container=$this->getContainer(dirname($path)); - if(is_null($container)){ + if(is_null($container)) { return false; } $obj=$container->create_object(basename($path)); @@ -390,8 +393,11 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ return $obj->write($content); } - public function unlink($path){ - if($this->objectExists($path)){ + public function unlink($path) { + if($this->containerExists($path)) { + return $this->rmdir($path); + } + if($this->objectExists($path)) { $container=$this->getContainer(dirname($path)); $container->delete_object(basename($path)); unset($this->objects[$path]); @@ -400,17 +406,17 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ } } - public function fopen($path,$mode){ - $obj=$this->getObject($path); - if(is_null($obj)){ - return false; - } - switch($mode){ + public function fopen($path,$mode) { + switch($mode) { case 'r': case 'rb': + $obj=$this->getObject($path); + if (is_null($obj)) { + return false; + } $fp = fopen('php://temp', 'r+'); $obj->stream($fp); - + rewind($fp); return $fp; case 'w': @@ -432,61 +438,71 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ } } - public function writeBack($tmpFile){ - if(isset(self::$tempFiles[$tmpFile])){ + public function writeBack($tmpFile) { + if(isset(self::$tempFiles[$tmpFile])) { $this->fromTmpFile($tmpFile,self::$tempFiles[$tmpFile]); unlink($tmpFile); } } - public function free_space($path){ - return 0; + public function free_space($path) { + return 1024*1024*1024*8; } - public function touch($path,$mtime=null){ + public function touch($path,$mtime=null) { $obj=$this->getObject($path); - if(is_null($obj)){ + if(is_null($obj)) { return false; } - if(is_null($mtime)){ + if(is_null($mtime)) { $mtime=time(); } - + //emulate setting mtime with metadata $obj->metadata['Mtime']=$mtime; $obj->sync_metadata(); } - public function rename($path1,$path2){ + public function rename($path1,$path2) { $sourceContainer=$this->getContainer(dirname($path1)); $targetContainer=$this->getContainer(dirname($path2)); $result=$sourceContainer->move_object_to(basename($path1),$targetContainer,basename($path2)); unset($this->objects[$path1]); - if($result){ + if($result) { $targetObj=$this->getObject($path2); $this->resetMTime($targetObj); } return $result; } - public function copy($path1,$path2){ + public function copy($path1,$path2) { $sourceContainer=$this->getContainer(dirname($path1)); $targetContainer=$this->getContainer(dirname($path2)); $result=$sourceContainer->copy_object_to(basename($path1),$targetContainer,basename($path2)); - if($result){ + if($result) { $targetObj=$this->getObject($path2); $this->resetMTime($targetObj); } return $result; } - public function stat($path){ + public function stat($path) { + $container=$this->getContainer($path); + if (!is_null($container)) { + return array( + 'mtime'=>-1, + 'size'=>$container->bytes_used, + 'ctime'=>-1 + ); + } + $obj=$this->getObject($path); - if(is_null($obj)){ + + if(is_null($obj)) { return false; } - if(isset($obj->metadata['Mtime']) and $obj->metadata['Mtime']>-1){ + if(isset($obj->metadata['Mtime']) and $obj->metadata['Mtime']>-1) { $mtime=$obj->metadata['Mtime']; }else{ $mtime=strtotime($obj->last_modified); @@ -498,20 +514,20 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ ); } - private function getTmpFile($path){ + private function getTmpFile($path) { $obj=$this->getObject($path); - if(!is_null($obj)){ + if(!is_null($obj)) { $tmpFile=OCP\Files::tmpFile(); $obj->save_to_filename($tmpFile); return $tmpFile; }else{ - return false; + return OCP\Files::tmpFile(); } } - private function fromTmpFile($tmpFile,$path){ + private function fromTmpFile($tmpFile,$path) { $obj=$this->getObject($path); - if(is_null($obj)){ + if(is_null($obj)) { $obj=$this->createObject($path); } $obj->load_from_filename($tmpFile); @@ -522,8 +538,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ * remove custom mtime metadata * @param CF_Object obj */ - private function resetMTime($obj){ - if(isset($obj->metadata['Mtime'])){ + private function resetMTime($obj) { + if(isset($obj->metadata['Mtime'])) { $obj->metadata['Mtime']=-1; $obj->sync_metadata(); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 3d13518f57..5e18583915 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -18,8 +18,8 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ private $client; private static $tempFiles=array(); - - public function __construct($params){ + + public function __construct($params) { $host = $params['host']; //remove leading http[s], will be generated in createBaseUri() if (substr($host,0,8) == "https://") $host = substr($host, 8); @@ -29,13 +29,13 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ $this->password=$params['password']; $this->secure=(isset($params['secure']) && $params['secure'] == 'true')?true:false; $this->root=isset($params['root'])?$params['root']:'/'; - if(!$this->root || $this->root[0]!='/'){ + if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } - if(substr($this->root,-1,1)!='/'){ + if(substr($this->root,-1,1)!='/') { $this->root.='/'; } - + $settings = array( 'baseUri' => $this->createBaseUri(), 'userName' => $this->user, @@ -43,7 +43,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ ); $this->client = new OC_Connector_Sabre_Client($settings); - + if($caview = \OCP\Files::getStorage('files_external')) { $certPath=\OCP\Config::getSystemValue('datadirectory').$caview->getAbsolutePath("").'rootcerts.crt'; if (file_exists($certPath)) { @@ -54,88 +54,86 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ $this->mkdir(''); } - private function createBaseUri(){ + private function createBaseUri() { $baseUri='http'; - if($this->secure){ + if($this->secure) { $baseUri.='s'; } $baseUri.='://'.$this->host.$this->root; return $baseUri; } - public function mkdir($path){ + public function mkdir($path) { $path=$this->cleanPath($path); return $this->simpleResponse('MKCOL',$path,null,201); } - public function rmdir($path){ + public function rmdir($path) { $path=$this->cleanPath($path); return $this->simpleResponse('DELETE',$path,null,204); } - public function opendir($path){ + public function opendir($path) { $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array(),1); - $stripLength=strlen($this->root)+strlen($path); $id=md5('webdav'.$this->root.$path); OC_FakeDirStream::$dirs[$id]=array(); - $skip = true; - foreach($response as $file=>$data){ - // Skip the first file, because it is the current directory - if ($skip) { - $skip = false; - continue; - } + $files=array_keys($response); + array_shift($files);//the first entry is the current directory + foreach($files as $file) { $file = urldecode(basename($file)); OC_FakeDirStream::$dirs[$id][]=$file; } return opendir('fakedir://'.$id); - }catch(Exception $e){ + }catch(Exception $e) { return false; } } - public function filetype($path){ + public function filetype($path) { $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}resourcetype')); $responseType=$response["{DAV:}resourcetype"]->resourceType; return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file'; - }catch(Exception $e){ + }catch(Exception $e) { error_log($e->getMessage()); \OCP\Util::writeLog("webdav client", \OCP\Util::sanitizeHTML($e->getMessage()), \OCP\Util::ERROR); return false; } } - public function is_readable($path){ + public function isReadable($path) { return true;//not properly supported } - public function is_writable($path){ + public function isUpdatable($path) { return true;//not properly supported } - public function file_exists($path){ + public function file_exists($path) { $path=$this->cleanPath($path); try{ - $response=$this->client->propfind($path, array('{DAV:}resourcetype')); + $this->client->propfind($path, array('{DAV:}resourcetype')); return true;//no 404 exception - }catch(Exception $e){ + }catch(Exception $e) { return false; } } - public function unlink($path){ + public function unlink($path) { return $this->simpleResponse('DELETE',$path,null,204); } - public function fopen($path,$mode){ + public function fopen($path,$mode) { $path=$this->cleanPath($path); - switch($mode){ + switch($mode) { case 'r': case 'rb': + if(!$this->file_exists($path)) { + return false; + } //straight up curl instead of sabredav here, sabredav put's the entire get result in memory $curl = curl_init(); $fp = fopen('php://temp', 'r+'); @@ -160,14 +158,14 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ case 'c': case 'c+': //emulate these - if(strrpos($path,'.')!==false){ + if(strrpos($path,'.')!==false) { $ext=substr($path,strrpos($path,'.')); }else{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); - if($this->file_exists($path)){ + if($this->file_exists($path)) { $this->getFile($path,$tmpFile); } self::$tempFiles[$tmpFile]=$path; @@ -175,41 +173,41 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ } } - public function writeBack($tmpFile){ - if(isset(self::$tempFiles[$tmpFile])){ + public function writeBack($tmpFile) { + if(isset(self::$tempFiles[$tmpFile])) { $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]); unlink($tmpFile); } } - public function free_space($path){ + public function free_space($path) { $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}quota-available-bytes')); - if(isset($response['{DAV:}quota-available-bytes'])){ + if(isset($response['{DAV:}quota-available-bytes'])) { return (int)$response['{DAV:}quota-available-bytes']; }else{ return 0; } - }catch(Exception $e){ + }catch(Exception $e) { return 0; } } - public function touch($path,$mtime=null){ - if(is_null($mtime)){ + public function touch($path,$mtime=null) { + if(is_null($mtime)) { $mtime=time(); } $path=$this->cleanPath($path); - $this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime,)); + $this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime)); } - public function getFile($path,$target){ + public function getFile($path,$target) { $source=$this->fopen($path,'r'); file_put_contents($target,$source); } - public function uploadFile($path,$target){ + public function uploadFile($path,$target) { $source=fopen($path,'r'); $curl = curl_init(); @@ -223,13 +221,13 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ curl_close ($curl); } - public function rename($path1,$path2){ + public function rename($path1,$path2) { $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ $response=$this->client->request('MOVE',$path1,null,array('Destination'=>$path2)); return true; - }catch(Exception $e){ + }catch(Exception $e) { echo $e; echo 'fail'; var_dump($response); @@ -237,13 +235,13 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ } } - public function copy($path1,$path2){ + public function copy($path1,$path2) { $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ $response=$this->client->request('COPY',$path1,null,array('Destination'=>$path2)); return true; - }catch(Exception $e){ + }catch(Exception $e) { echo $e; echo 'fail'; var_dump($response); @@ -251,7 +249,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ } } - public function stat($path){ + public function stat($path) { $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}getlastmodified','{DAV:}getcontentlength')); @@ -260,45 +258,44 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0, 'ctime'=>-1, ); - }catch(Exception $e){ + }catch(Exception $e) { return array(); } } - public function getMimeType($path){ + public function getMimeType($path) { $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}getcontenttype','{DAV:}resourcetype')); $responseType=$response["{DAV:}resourcetype"]->resourceType; $type=(count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file'; - if($type=='dir'){ + if($type=='dir') { return 'httpd/unix-directory'; - }elseif(isset($response['{DAV:}getcontenttype'])){ + }elseif(isset($response['{DAV:}getcontenttype'])) { return $response['{DAV:}getcontenttype']; }else{ return false; } - }catch(Exception $e){ + }catch(Exception $e) { return false; } } - private function cleanPath($path){ - if(!$path || $path[0]=='/'){ + private function cleanPath($path) { + if(!$path || $path[0]=='/') { return substr($path,1); }else{ return $path; } } - private function simpleResponse($method,$path,$body,$expected){ + private function simpleResponse($method,$path,$body,$expected) { $path=$this->cleanPath($path); try{ $response=$this->client->request($method,$path,$body); return $response['statusCode']==$expected; - }catch(Exception $e){ + }catch(Exception $e) { return false; } } } - diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php index dec501741b..f0d76460f5 100755 --- a/apps/files_external/personal.php +++ b/apps/files_external/personal.php @@ -31,5 +31,3 @@ $tmpl->assign('mounts', OC_Mount_Config::getPersonalMountPoints()); $tmpl->assign('certs', OC_Mount_Config::getCertificates()); $tmpl->assign('backends', $backends); return $tmpl->fetchPage(); - -?> \ No newline at end of file diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php index acc9036b29..d2be21b711 100644 --- a/apps/files_external/settings.php +++ b/apps/files_external/settings.php @@ -21,7 +21,9 @@ */ OCP\Util::addScript('files_external', 'settings'); +OCP\Util::addscript('3rdparty', 'chosen/chosen.jquery.min'); OCP\Util::addStyle('files_external', 'settings'); +OCP\Util::addStyle('3rdparty', 'chosen/chosen'); $tmpl = new OCP\Template('files_external', 'settings'); $tmpl->assign('isAdminPage', true, false); $tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints()); @@ -30,5 +32,3 @@ $tmpl->assign('groups', OC_Group::getGroups()); $tmpl->assign('users', OCP\User::getUsers()); $tmpl->assign('allowUserMounting', OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes')); return $tmpl->fetchPage(); - -?> \ No newline at end of file diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php index e8bc94790d..367ce2bc03 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -1,4 +1,4 @@ -
                +
                t('External Storage'); ?> '> @@ -15,7 +15,7 @@ array())); ?> $mount): ?> - > + >
                @@ -80,28 +80,7 @@

                - - - '> - - - - - - - - - - - - - - -
                t('SSL root certificates'); ?> 
                ><?php echo $l->t('Delete'); ?>
                - - - - +
                /> @@ -110,3 +89,28 @@
                + +
                +
                + + '> + + + + + + + + + + + + + + +
                t('SSL root certificates'); ?> 
                ><?php echo $l->t('Delete'); ?>
                + + + +
                +
                \ No newline at end of file diff --git a/apps/files_external/tests/amazons3.php b/apps/files_external/tests/amazons3.php index b9b4cf65bd..725f4ba05d 100644 --- a/apps/files_external/tests/amazons3.php +++ b/apps/files_external/tests/amazons3.php @@ -1,43 +1,42 @@ . -*/ + * ownCloud + * + * @author Michael Gapczynski + * @copyright 2012 Michael Gapczynski mtgap@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + */ -$config = include('apps/files_external/tests/config.php'); -if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['run']) { - abstract class Test_Filestorage_AmazonS3 extends Test_FileStorage{} - return; -} else { - class Test_Filestorage_AmazonS3 extends Test_FileStorage { +class Test_Filestorage_AmazonS3 extends Test_FileStorage { - private $config; - private $id; + private $config; + private $id; - public function setUp() { - $id = uniqid(); - $this->config = include('apps/files_external/tests/config.php'); - $this->config['amazons3']['bucket'] = $id; // Make sure we have a new empty bucket to work in - $this->instance = new OC_Filestorage_AmazonS3($this->config['amazons3']); + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if (!is_array($this->config) or !isset($this->config['amazons3']) or !$this->config['amazons3']['run']) { + $this->markTestSkipped('AmazonS3 backend not configured'); } + $this->config['amazons3']['bucket'] = $id; // Make sure we have a new empty bucket to work in + $this->instance = new OC_Filestorage_AmazonS3($this->config['amazons3']); + } - public function tearDown() { + public function tearDown() { + if ($this->instance) { $s3 = new AmazonS3(array('key' => $this->config['amazons3']['key'], 'secret' => $this->config['amazons3']['secret'])); if ($s3->delete_all_objects($this->id)) { $s3->delete_bucket($this->id); diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index e58a87fabd..ff16b1c1d8 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -26,7 +26,7 @@ return array( 'run'=>false, 'user'=>'test:tester', 'token'=>'testing', - 'host'=>'localhost:8080/auth', + 'host'=>'localhost.local:8080/auth', 'root'=>'/', ), 'smb'=>array( @@ -43,4 +43,13 @@ return array( 'secret'=>'test', 'bucket'=>'bucket', ), + 'dropbox' => array ( + 'run'=>false, + 'root'=>'owncloud', + 'configured' => 'true', + 'app_key' => '', + 'app_secret' => '', + 'token' => '', + 'token_secret' => '' + ) ); diff --git a/apps/files_external/tests/dropbox.php b/apps/files_external/tests/dropbox.php new file mode 100644 index 0000000000..56319b9f5d --- /dev/null +++ b/apps/files_external/tests/dropbox.php @@ -0,0 +1,27 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Filestorage_Dropbox extends Test_FileStorage { + private $config; + + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if (!is_array($this->config) or !isset($this->config['dropbox']) or !$this->config['dropbox']['run']) { + $this->markTestSkipped('Dropbox backend not configured'); + } + $this->config['dropbox']['root'] .= '/' . $id; //make sure we have an new empty folder to work in + $this->instance = new OC_Filestorage_Dropbox($this->config['dropbox']); + } + + public function tearDown() { + if ($this->instance) { + $this->instance->unlink('/'); + } + } +} diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php index 68481b4e66..4549c42041 100644 --- a/apps/files_external/tests/ftp.php +++ b/apps/files_external/tests/ftp.php @@ -5,26 +5,23 @@ * later. * See the COPYING-README file. */ - -$config=include('apps/files_external/tests/config.php'); -if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']){ - abstract class Test_Filestorage_FTP extends Test_FileStorage{} - return; -}else{ - class Test_Filestorage_FTP extends Test_FileStorage { - private $config; - private $id; - public function setUp(){ - $id=uniqid(); - $this->config=include('apps/files_external/tests/config.php'); - $this->config['ftp']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_FTP($this->config['ftp']); +class Test_Filestorage_FTP extends Test_FileStorage { + private $config; + + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if (!is_array($this->config) or !isset($this->config['ftp']) or !$this->config['ftp']['run']) { + $this->markTestSkipped('FTP backend not configured'); } + $this->config['ftp']['root'] .= '/' . $id; //make sure we have an new empty folder to work in + $this->instance = new OC_Filestorage_FTP($this->config['ftp']); + } - public function tearDown(){ + public function tearDown() { + if ($this->instance) { OCP\Files::rmdirr($this->instance->constructUrl('')); } } } - diff --git a/apps/files_external/tests/google.php b/apps/files_external/tests/google.php index 08116f0e74..46e622cc18 100644 --- a/apps/files_external/tests/google.php +++ b/apps/files_external/tests/google.php @@ -1,45 +1,42 @@ . -*/ + * ownCloud + * + * @author Michael Gapczynski + * @copyright 2012 Michael Gapczynski mtgap@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + */ -$config=include('apps/files_external/tests/config.php'); -if(!is_array($config) or !isset($config['google']) or !$config['google']['run']){ - abstract class Test_Filestorage_Google extends Test_FileStorage{} - return; -}else{ - class Test_Filestorage_Google extends Test_FileStorage { - - private $config; - private $id; +class Test_Filestorage_Google extends Test_FileStorage { - public function setUp(){ - $id=uniqid(); - $this->config=include('apps/files_external/tests/config.php'); - $this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_Google($this->config['google']); + private $config; + + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if (!is_array($this->config) or !isset($this->config['google']) or !$this->config['google']['run']) { + $this->markTestSkipped('Google backend not configured'); } + $this->config['google']['root'] .= '/' . $id; //make sure we have an new empty folder to work in + $this->instance = new OC_Filestorage_Google($this->config['google']); + } - public function tearDown(){ + public function tearDown() { + if ($this->instance) { $this->instance->rmdir('/'); } } } - diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index e1495b7480..2c03ef5dbd 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -6,24 +6,21 @@ * See the COPYING-README file. */ -$config=include('apps/files_external/tests/config.php'); +class Test_Filestorage_SMB extends Test_FileStorage { + private $config; -if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']){ - abstract class Test_Filestorage_SMB extends Test_FileStorage{} - return; -}else{ - class Test_Filestorage_SMB extends Test_FileStorage { - private $config; - private $id; - - public function setUp(){ - $id=uniqid(); - $this->config=include('apps/files_external/tests/config.php'); - $this->config['smb']['root'].=$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_SMB($this->config['smb']); + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if (!is_array($this->config) or !isset($this->config['smb']) or !$this->config['smb']['run']) { + $this->markTestSkipped('Samba backend not configured'); } + $this->config['smb']['root'] .= $id; //make sure we have an new empty folder to work in + $this->instance = new OC_Filestorage_SMB($this->config['smb']); + } - public function tearDown(){ + public function tearDown() { + if ($this->instance) { OCP\Files::rmdirr($this->instance->constructUrl('')); } } diff --git a/apps/files_external/tests/swift.php b/apps/files_external/tests/swift.php index f0bde6ed60..8cf2a3abc7 100644 --- a/apps/files_external/tests/swift.php +++ b/apps/files_external/tests/swift.php @@ -6,27 +6,23 @@ * See the COPYING-README file. */ -$config=include('apps/files_external/tests/config.php'); -if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']){ - abstract class Test_Filestorage_SWIFT extends Test_FileStorage{} - return; -}else{ - class Test_Filestorage_SWIFT extends Test_FileStorage { - private $config; - private $id; +class Test_Filestorage_SWIFT extends Test_FileStorage { + private $config; - public function setUp(){ - $id=uniqid(); - $this->config=include('apps/files_external/tests/config.php'); - $this->config['swift']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_SWIFT($this->config['swift']); + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if (!is_array($this->config) or !isset($this->config['swift']) or !$this->config['swift']['run']) { + $this->markTestSkipped('OpenStack SWIFT backend not configured'); } + $this->config['swift']['root'] .= '/' . $id; //make sure we have an new empty folder to work in + $this->instance = new OC_Filestorage_SWIFT($this->config['swift']); + } - - public function tearDown(){ - $this->instance->rmdir(''); + + public function tearDown() { + if ($this->instance) { + $this->instance->rmdir(''); } - } } - diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php index 144659819b..2da88f63ed 100644 --- a/apps/files_external/tests/webdav.php +++ b/apps/files_external/tests/webdav.php @@ -6,25 +6,22 @@ * See the COPYING-README file. */ -$config=include('apps/files_external/tests/config.php'); -if(!is_array($config) or !isset($config['webdav']) or !$config['webdav']['run']){ - abstract class Test_Filestorage_DAV extends Test_FileStorage{} - return; -}else{ - class Test_Filestorage_DAV extends Test_FileStorage { - private $config; - private $id; +class Test_Filestorage_DAV extends Test_FileStorage { + private $config; - public function setUp(){ - $id=uniqid(); - $this->config=include('apps/files_external/tests/config.php'); - $this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_DAV($this->config['webdav']); + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if (!is_array($this->config) or !isset($this->config['webdav']) or !$this->config['webdav']['run']) { + $this->markTestSkipped('WebDAV backend not configured'); } + $this->config['webdav']['root'] .= '/' . $id; //make sure we have an new empty folder to work in + $this->instance = new OC_Filestorage_DAV($this->config['webdav']); + } - public function tearDown(){ + public function tearDown() { + if ($this->instance) { $this->instance->rmdir('/'); } } } - diff --git a/apps/files_imageviewer/appinfo/app.php b/apps/files_imageviewer/appinfo/app.php deleted file mode 100644 index 6184585cff..0000000000 --- a/apps/files_imageviewer/appinfo/app.php +++ /dev/null @@ -1,6 +0,0 @@ - - - files_imageviewer - Image Viewer - Simple image viewer for owncloud - AGPL - Robin Appelman - 4 - true - - diff --git a/apps/files_imageviewer/appinfo/version b/apps/files_imageviewer/appinfo/version deleted file mode 100644 index 9f8e9b69a3..0000000000 --- a/apps/files_imageviewer/appinfo/version +++ /dev/null @@ -1 +0,0 @@ -1.0 \ No newline at end of file diff --git a/apps/files_imageviewer/css/jquery.fancybox-1.3.4.css b/apps/files_imageviewer/css/jquery.fancybox-1.3.4.css deleted file mode 100644 index 6e982805a4..0000000000 --- a/apps/files_imageviewer/css/jquery.fancybox-1.3.4.css +++ /dev/null @@ -1,359 +0,0 @@ -/* - * FancyBox - jQuery Plugin - * Simple and fancy lightbox alternative - * - * Examples and documentation at: http://fancybox.net - * - * Copyright (c) 2008 - 2010 Janis Skarnelis - * That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated. - * - * Version: 1.3.4 (11/11/2010) - * Requires: jQuery v1.3+ - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ - -#fancybox-loading { - position: fixed; - top: 50%; - left: 50%; - width: 40px; - height: 40px; - margin-top: -20px; - margin-left: -20px; - cursor: pointer; - overflow: hidden; - z-index: 1104; - display: none; -} - -#fancybox-loading div { - position: absolute; - top: 0; - left: 0; - width: 40px; - height: 480px; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox.png'); -} - -#fancybox-overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - z-index: 1100; - display: none; -} - -#fancybox-tmp { - padding: 0; - margin: 0; - border: 0; - overflow: auto; - display: none; -} - -#fancybox-wrap { - position: absolute; - top: 0; - left: 0; - padding: 20px; - z-index: 1101; - outline: none; - display: none; -} - -#fancybox-outer { - position: relative; - width: 100%; - height: 100%; - background: #fff; -} - -#fancybox-content { - width: 0; - height: 0; - padding: 0; - outline: none; - position: relative; - overflow: hidden; - z-index: 1102; - border: 0px solid #fff; -} - -#fancybox-hide-sel-frame { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: transparent; - z-index: 1101; -} - -#fancybox-close { - position: absolute; - top: -15px; - right: -15px; - width: 30px; - height: 30px; - background: transparent url('%appswebroot%/files_imageviewer/img/fancybox.png') -40px 0px; - cursor: pointer; - z-index: 1103; - display: none; -} - -#fancybox-error { - color: #444; - font: normal 12px/20px Arial; - padding: 14px; - margin: 0; -} - -#fancybox-img { - width: 100%; - height: 100%; - padding: 0; - margin: 0; - border: none; - outline: none; - line-height: 0; - vertical-align: top; -} - -#fancybox-frame { - width: 100%; - height: 100%; - border: none; - display: block; -} - -#fancybox-left, #fancybox-right { - position: absolute; - bottom: 0px; - height: 100%; - width: 35%; - cursor: pointer; - outline: none; - background: transparent url('%appswebroot%/files_imageviewer/img/blank.gif'); - z-index: 1102; - display: none; -} - -#fancybox-left { - left: 0px; -} - -#fancybox-right { - right: 0px; -} - -#fancybox-left-ico, #fancybox-right-ico { - position: absolute; - top: 50%; - left: -9999px; - width: 30px; - height: 30px; - margin-top: -15px; - cursor: pointer; - z-index: 1102; - display: block; -} - -#fancybox-left-ico { - background-image: url('%appswebroot%/files_imageviewer/img/fancybox.png'); - background-position: -40px -30px; -} - -#fancybox-right-ico { - background-image: url('%appswebroot%/files_imageviewer/img/fancybox.png'); - background-position: -40px -60px; -} - -#fancybox-left:hover, #fancybox-right:hover { - visibility: visible; /* IE6 */ -} - -#fancybox-left:hover span { - left: 20px; -} - -#fancybox-right:hover span { - left: auto; - right: 20px; -} - -.fancybox-bg { - position: absolute; - padding: 0; - margin: 0; - border: 0; - width: 20px; - height: 20px; - z-index: 1001; -} - -#fancybox-bg-n { - top: -20px; - left: 0; - width: 100%; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox-x.png'); -} - -#fancybox-bg-ne { - top: -20px; - right: -20px; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox.png'); - background-position: -40px -162px; -} - -#fancybox-bg-e { - top: 0; - right: -20px; - height: 100%; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox-y.png'); - background-position: -20px 0px; -} - -#fancybox-bg-se { - bottom: -20px; - right: -20px; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox.png'); - background-position: -40px -182px; -} - -#fancybox-bg-s { - bottom: -20px; - left: 0; - width: 100%; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox-x.png'); - background-position: 0px -20px; -} - -#fancybox-bg-sw { - bottom: -20px; - left: -20px; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox.png'); - background-position: -40px -142px; -} - -#fancybox-bg-w { - top: 0; - left: -20px; - height: 100%; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox-y.png'); -} - -#fancybox-bg-nw { - top: -20px; - left: -20px; - background-image: url('%appswebroot%/files_imageviewer/img/fancybox.png'); - background-position: -40px -122px; -} - -#fancybox-title { - font-family: Helvetica; - font-size: 12px; - z-index: 1102; -} - -.fancybox-title-inside { - padding-bottom: 10px; - text-align: center; - color: #333; - background: #fff; - position: relative; -} - -.fancybox-title-outside { - padding-top: 10px; - color: #fff; -} - -.fancybox-title-over { - position: absolute; - bottom: 0; - left: 0; - color: #FFF; - text-align: left; -} - -#fancybox-title-over { - padding: 10px; - background-image: url('%appswebroot%/files_imageviewer/img/fancy_title_over.png'); - display: block; -} - -.fancybox-title-float { - position: absolute; - left: 0; - bottom: -20px; - height: 32px; -} - -#fancybox-title-float-wrap { - border: none; - border-collapse: collapse; - width: auto; -} - -#fancybox-title-float-wrap td { - border: none; - white-space: nowrap; -} - -#fancybox-title-float-left { - padding: 0 0 0 15px; - background: url('%appswebroot%/files_imageviewer/img/fancybox.png') -40px -90px no-repeat; -} - -#fancybox-title-float-main { - color: #FFF; - line-height: 29px; - font-weight: bold; - padding: 0 0 3px 0; - background: url('%appswebroot%/files_imageviewer/img/fancybox-x.png') 0px -40px; -} - -#fancybox-title-float-right { - padding: 0 0 0 15px; - background: url('%appswebroot%/files_imageviewer/img/fancybox.png') -55px -90px no-repeat; -} - -/* IE6 */ - -.fancybox-ie6 #fancybox-close { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_close.png', sizingMethod='scale'); } - -.fancybox-ie6 #fancybox-left-ico { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_nav_left.png', sizingMethod='scale'); } -.fancybox-ie6 #fancybox-right-ico { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_nav_right.png', sizingMethod='scale'); } - -.fancybox-ie6 #fancybox-title-over { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_title_over.png', sizingMethod='scale'); zoom: 1; } -.fancybox-ie6 #fancybox-title-float-left { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_title_left.png', sizingMethod='scale'); } -.fancybox-ie6 #fancybox-title-float-main { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_title_main.png', sizingMethod='scale'); } -.fancybox-ie6 #fancybox-title-float-right { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_title_right.png', sizingMethod='scale'); } - -.fancybox-ie6 #fancybox-bg-w, .fancybox-ie6 #fancybox-bg-e, .fancybox-ie6 #fancybox-left, .fancybox-ie6 #fancybox-right, #fancybox-hide-sel-frame { - height: expression(this.parentNode.clientHeight + "px"); -} - -#fancybox-loading.fancybox-ie6 { - position: absolute; margin-top: 0; - top: expression( (-20 + (document.documentElement.clientHeight ? document.documentElement.clientHeight/2 : document.body.clientHeight/2 ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop )) + 'px'); -} - -#fancybox-loading.fancybox-ie6 div { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_loading.png', sizingMethod='scale'); } - -/* IE6, IE7, IE8 */ - -.fancybox-ie .fancybox-bg { background: transparent !important; } - -.fancybox-ie #fancybox-bg-n { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_shadow_n.png', sizingMethod='scale'); } -.fancybox-ie #fancybox-bg-ne { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_shadow_ne.png', sizingMethod='scale'); } -.fancybox-ie #fancybox-bg-e { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_shadow_e.png', sizingMethod='scale'); } -.fancybox-ie #fancybox-bg-se { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_shadow_se.png', sizingMethod='scale'); } -.fancybox-ie #fancybox-bg-s { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_shadow_s.png', sizingMethod='scale'); } -.fancybox-ie #fancybox-bg-sw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_shadow_sw.png', sizingMethod='scale'); } -.fancybox-ie #fancybox-bg-w { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_shadow_w.png', sizingMethod='scale'); } -.fancybox-ie #fancybox-bg-nw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%appswebroot%/files_imageviewer/img/fancy_shadow_nw.png', sizingMethod='scale'); } diff --git a/apps/files_imageviewer/img/blank.gif b/apps/files_imageviewer/img/blank.gif deleted file mode 100644 index 35d42e808f0a8017b8d52a06be2f8fec0b466a66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43 scmZ?wbhEHbWMp7uXkcLY|NlP&1B2pE7Dgb&paUX6G7L;iE{qJ;0LZEa`2YX_ diff --git a/apps/files_imageviewer/img/fancy_close.png b/apps/files_imageviewer/img/fancy_close.png deleted file mode 100644 index 07035307ad435f8f2f8eedf0bce50f7ec8a858c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1517 zcmV1To%f)hA(E>uTT$~N#GA0orBqo9-jKM;POccZrXJjTzge4|Sa0ca~7y<+{ z2m7~>41(Jqf9L`mBM6zAjf4;hkjP@@B~d6Xz385|dB5iCM=Ro&JZZmk-uHdZd2i=@ zK0a@Md;u9DFE7t8BO^nxckf<*yC?SckUFGmX^jwM@NV80+eiP zQ*s##s^a3}Ldwd@cHO*r^T5i=%Fj}=Cr_R@78e&C((#usU;YFS>C)2Dw4tG)YO=*P zWt;6ZfL46;=u!R1$jGM-hhvcpVyCa+S}Q!T2ALHx;BHe#M~BsHHos=s2iW})#C?}q ztqvud-gYjKsG$zHm2XhmYPB(Bn>kzw z=gS!w6cG`jJ$?H00VK+=!cMnBDn?IFkCkj7KmNq~hrkZvU@n=EP}|7Gxw*M}1_lPI zNx@_?IS^|%_ok<(o3gXBH^f+@(X7_g)K~%n0$gMM{{Ab=%gZ*hH99)_Eo>!VJd8_C zE)WMoNsBB#u&}W3BMEnPby>y64F-cra9>kX)4DJoA0KZ5fitNn`NTT4wY3%+fA;Lz zZ+K4ucJi+Mg!m%<>Ug8kSg^LX_JD-5va;NEM#+V_H)8UHgaj8UJ?LiZVx92t@KxlB zb1oz#Bo|{kAO!IDVfOII$VfwRad8C+y?XV^;VEu~g@tQka>%(zhlYl1p7P=0!-vj9 zYiMYw3l0uW##jWq+eZ-;6r@4F%{+PXGcz;xx78|Q_F7Eb+}ynGO@4TI*h!27r4#SzfR=K~ zhtpe&%-o-olT$}R&!0cHdm}}wbdd`2lO~)PlarHXnm>2$+(ng2^$EtJ+=vwl#Xg-* zSA%x<9|=lJ3CXuACMEY46&1O~{LGm%7HKm8lhZ|+Pv?nF1LcJswy+L%zshO4HzpR4skij zxq<8a{QPpl!oq4$R(*n7$-q`gsjcF2;NWZ?##l9wBW)lu_Bpk)RJgGO&Ey+2dDr3J z*x2~aJFl#)G^5U)q~qh`_b^ru6q9Xf%arlfse$W(T#z5f?cqE0>k)x`c6QcMUS4jN z#$B996B84z1O(|{7{3S{Bb#j7?T~OCi+pq$fP9eGqJ%Evk~i}B@#8tcAnk_QAg)9f z!qn81MJO5W0n6>}?Q|$y25QL`+uU$0x?KbSI<(UOBavf=wCW!^J3Ie)^yty-8!yk& z($YLG4fjwT{k&5mHL@*_7Xi1c4?x$HT^y5qc2zyPPCG3CUKl!f@Zj&~&!7K?fD>&z zDk^G(=74sN=`q$#Wm{gaK5myi7K~vRQ8s=CoB+NC8j<}iKpXzI(SMmt*2r@wST=`s zW7t-}X4hPqXy3W00000NkvXXu0mjftFGKG diff --git a/apps/files_imageviewer/img/fancy_loading.png b/apps/files_imageviewer/img/fancy_loading.png deleted file mode 100644 index 2503017960b3972499d3aa92f89953935ae40934..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10195 zcmZvCRa6{Z)GRK+A-I#l3GNJT8Egn7KyZS)ySwY)GC**5cXtmOAh^3rfXjE+eY*eu zvb$HWe&}AO&aSFmCtO)c7UKiS2N)O_4A2)TmG>(H3=HfB3ex-CA}8B>rB4S*iGOoj zIbB0`GB%#)yQsNe_Z(XHJVzvTksi>+`6l(%$`7%p5{2L+{tq=VJ?V0JL-5DetdIHF|rZRGiB+~M$cAs!3L4m1WqS5m4Uut{B{sus$nl}9N zp#?4R@YNv8YM{JrwP-Li8Ynr~UO3E8cBsK321T79L4oqq#7><+nH-uo4c3S zzbjdhtN2LE+Wk$ypLztVwTlowGQqng!^I&U`;KFsDxwwAwF4PR(`@g%I}B1@?aN<; z9cJzX7khkNkJG|u_OY88t2=a(9k|tRF|O^~620}B74q3{|Mu}rUKMRU=5i@t4rH}t zWMo)9&m6ObjvNsA;yz~`O>f^l&kjH&j=Aexy0cfmC&I>@QU7`Ql zPU3_q?7Cqi%{r7|wPeZc`_s9mfR2B_K39;>*-yWV=qR41Ls>bqydL@}bse|D>1|L> zSvMFEQ2vnWJKlHRcZAw{ZIfc@+_x^0qqpf`uaLP9OH$Mxyno5YuLvbooxn?EWW9?3 z!YB&gf0xHo{M%6#qA!QwrjFO!Dm~{w(pCL9Z1XeAf)Nj@AQGyB2^*KX+-VJJjiv1` z<4I`VooCdOm?}gf8PD(k+m)s!AE5Z?+0=PkK{!n$OKo*{K2N95Y`L?t*m<`z<@&zR zp~CHRl4dh@$sJ4b-?gm;KP++XcWjfN6N#Qw_o;QATHBKP9&7y-bUDZkt@PRB%5E8d zyIxSjYTf;8+p-~Y-!k=O$;kfFCPu};=7d4N%l)KG@8xK)nb+&}I$Q6pWy;&;g|G86 zI-2s|2J)g^1XG`LO53Wj0gJDEZw-Oyi2)Wft0k{z<}G%H3dQ>?Y(D?CDZ2o#2V1hj zM_=W)_N5IX(aMyXUqh1U_WG#TC%LuB%3bK~)3%|v<)+ah|2DDoR!5Ri1|w~KpZ~C> zj*1KZd%Z~(gdF2RFMx01Wj`AW>Y$yS`Ndy3rPZS*pr6~#`6Q{ z%20=uSgaS;|E%9NE(<&vHm9^dubopg^XZ9&z5b1D ztpelNuc?SSpElb&~gE~4TESBIw z4hXi+ap2YNx8^D{Y~U3Q@Y|(~)|YhqOBukuK1!NNCMG7sGZ6A#)2w8O6Kn zdChi*Bi4O9!Q85-l}W!%4SCss_ceWT5CR9)!>d)k=W(}t8zRG>zPaIpd-bRcl+8}< zyZAFh+)b7i2(xFGQ1NiT*Ss*nf$|V%2{)tO&r?qsL@GB0#g&?RJHuU!w|`-+L=^sL zBkr*m4+?S5Lim?WVQJ4G?3fKVc}Q*JmJmX3?v`M44RD$Chi8S>0a5i2&wbyXSv8dY zyfv7Z{pAwk7MSBUu@ z5G6tLJnE1!1UjyO1R`?s4&aNgugC^{U9o!idxxDc93pcZ7raY)Xn7Pw`)<#e)4& zcN7v?6cRi?#`bl9ECtBz_QVZ0guMA?CDv=_ljYyH*ZV4aa_^g&fXJni?@vAE{G+P77pVW4Tj}s-(;*& z1STX!WHYF!Btlft>2`qz&1ijPaSdm%!UIMua~VRnoET&%1AAf)#vSfWj=q$8;qo|vcK_;z1j(+l2X0@o7C&Rzg8!2h$XZGbenx^q2; zApAgMeMi;{fO?<|f=I--(6#z(IL}cC|D24*dg^rhIE3G^yTJFZF55a-#}tYH=P$~* zb}RzkLIDvK`;ZA4OnYPQQ?;ssg`Ml>vON8NVnk@fl0k&o2W`-r3Bg-8NJYuCo0$rb zAKi(Z+>hRKA>bjOr%LHS@;94B&obY#4yCecQ0pdAnSV&v!vLF&-`Mm?t?}6F z?PaX5mkzFp$i(YKsOTz58Zgc7q)IVxy5hYd;~k@a63_Ja7Z0!ycbH~U&Y;r17f{Z} zwhnd>Xve$Riey{w@OgRi9rKhkQO@>jj2#Py8_PSVvvwxp0HTR7DdE{>K_i9RL= zrPNU6SCAR*HU3BLhMV(aTn;NBJQziUp9-R3QkgnENmN9ZBlJCW?l9$81skWTmD&YK zJ%7bQFP*wlswyu56egGmr!KVx=+KneK+U;f>vSk#hKg0u(yv^fNk=GGdULDg_=itK zp3;*2U!wB8TA$o;k!;o@OA2zx*%c|y0#?BBp?nDDw5rBS_SB_Sbz$6-fYTvnj(ezNfL{$?uz9aa=HGSg$mLTxTf{7e`Oqr?7rp+0`lg6AQpk z9Nsxh5kt+I%$5|50=OZUzms%|OAS{5^$g0~djWjOVxYk^CLD{|njlM2ex}zn9yCa1 zXCSTHoM#Rjq25u6;*Ug2A+S~Y`_kh|<3C=w_~F{9JKTLW^z5D41V2cjL8y+L*0IQ_ z?L+y%E(_`Xj&MzngB*bEt_~znvHKiL&w-ytZ<@L~s{_sdoRaSXOA5{31d;sz#pvvv zgq9-MCupHYRhjX{g`7wlu9(YJkAO)+oP%bGYC{Q>2v4!wD(_QEQe5suxdx(SIXS!9 zV|=hm;s|y$aq8^~zssyzb{|fvQc!Cj#FNH1$?tLP+^0!rIS_gU*h1d?y;X7vm>l>a zwr^N0VzNQ_j$}0!F~;(iG9UmS=QO|XM%w%nK5uQHaLT2-I$_CRCbGr8ymE9J_k{YTcfRFh1nn)R6_X#W#Fg4I=2W=GD|J_UwPwIQsBklSR4`o0$A&X8xn-V`k#d|7nEr9kiD4Dx?q zJBBg6NsFLaJWHtZ+GQr~rb(+STSHpb`9UQ4BbXjmTjDz;@V0H}7=mOf+#fvH-crjF z@uztsU}U)L0`Q{D-mZfkuH|zPNNIKXy+C+QIrQ&23l%VJtwn!M0wNG>wEi_? z``=Fg-bBV*o!jNs*j0n^Sn^x-5T@n{us@koqBnB}HI+tGJ!*iBb=5xNu?gt0oYXmW z8+W9Aca$K535BsvBR3qs~{jn>MoPaD#Aa+9Thdjr^?c!Rm zd+L48(+PM55nZ#`>laDoAVlLUXKyJl;Rm?x@Vv6HMm5<-R6-Z-qq1C{(`EqabpBzG zj;4V!x`7^=;;cYNpRy+iPV>rQAJl)AhcD--7r9MjgEiiV#SR|%E*YZcCryW8uK0m8 zL*X&^7In#HoVp*5gKHN+#O5c>>55A?ba%a_dj$xtqeA|)Js2dMKsh{lLDK@0m9lYa zWh*#0TQ2T27j^N`(t+eEfPUoBbvH_Kxa-u1jcNIe2YA^XT=1{3*Wd)}tKRN&dun&* znJX0Gvn8K!-%j#7%+r_|9qIlzn!o^G{q2MJxsdbiTZx3rG2xVS7HXrp5s;0PD>=hY zBl<_TAVt^N>MxbO(@<=MbHrHR=MZIY*8L>tB_Jja#yQoQZ2U!66gIECXOtndOORap zIR~TG$;oHLIJfQd#!j_3_Qvmx`fn3O*zC1bYC_$3%GfsjXN1z3asw+xTs!lK0I3p~ z7+&tcZUsM&QuO)Rahedf=&&)d1_C6zma`x{C50fHF?zDa=ZblEB;H@x_ z*db{M-tS}6{hx>Au=h4<8bWA8WETt$$|~;BYStwE1pYq48aKuv)4zT2-le|_1FnV@ z&z3AIiy5J{V@~m(2Aps_b7@uMmeTM}Zrs1Cl&)1e*ht|I zj+H9o<}yH3ZLHkB*F?)hWh$+em0HTThaoLx6FA4~msa-#wQzbyJ7ZmQjr#_R2ho^; z^_`?dw}hUR_w8a@8*K8J-lhK2Ot+y`>+{`n0h_lu{26PzN8ov0&f4B@R&y6%I6s2# zaHh%b232N&`aa6F5}eHI$b&SYPEgsOw5r$FS9yGwbRGzrIvbyEgZ9&nFxs0*_O>EKspQWU0tWeX06p%_D|(!O+TmLQ=`cGc+aR*yqXicgOVfS-31*Vth9=M<`>TD z2ecu1@-;8F3cm{pGegNysh5>XjRo{+T&Ak)F?qQ`lGeFVEKm{O*Fh^hd&!`$*H zo5Oc&)hGQS+5HxkD6FQ8nebel#;ty}aAw`K(xh8I_#=)-z$e>p3&-I@Xi7DsewFYp z$O_YrvYr1N$2_XK@wwpD36YvYlkAWY{ImJ=ap?zi$l%xZ*=IqNes{oGZ_d&RUp#M>B0_e>rGRlDA!;QcB^(S{BAOFH9!5r^ucGvwr7zaBu z0nl8=Q**gw{nD9@q{NiDSWk(V7^!=lJ2pWMJjM<6vo&=apq;2<=R}w*8Y1=kz=PCQ z%)%vAD1wFG6WryVg@``Sirh@k%N803_$(=+!8Mvb9?1T!G85NtuNdZnEQyu#A?w`B z)F3b>f5ji+x}KM|Tj2^Y*G*7{b`Tfi5Vo1I10v&)jAXu~zp&^l9_6zJNyTM-8Umo1 z9&95H=Jn67@b=o@EulLxhu9I5NUWA}RT~7aM&6p*w#;#@t_WkoM=N611DP@^AO(5% z_O)wI8+=$Zu|&6GLOI$LM?5!R9z_jmV}oTTbo5w#im;QnduH`c$N zW{BAB52R%1;Rn5cODK_%Sd9)aoctB9zxfjVQ>(H0D(}uy@LHYyAgK3g(>S9( zPtYyFU)v324BQ;?fy(SYzzu)I?S5X)C%oy!_vo35qBl@iLxXeO0=c!$`taf&-nWfH z&;kAR#ny=d^p!J#(|f-;_JYU39P352-lqenf}$VP>n~VNP4fO z7WIbrhM-BLcG@K6C#AME+0)ar)&j3)4d;NqqtG&xvMIB$;{YjyD%@TxXDz(Gn^~Q$ z`{|#$49R1=uT?+cj-swXngY48cUNapbLV7E{z3w$^>d9@EA@w>HM^RNCa!C{AQXMm zpS_ccdl>Gl@TvUqk0?XIXoR{14Qy=kig!<*wYyEI!{IFM!!y{06q1<;ELY*y*mjQT zv-b*OcY}^&CpfUnzo^;VokcN($`aoxgOa2-iM%AbK5g=>;P?fEw9oVMKLygeXnM7D zPtexNCH+(J;~KzQ96%ZTw*j@q*9|u=z0Y-$-X6>%8rAx{yN1?B`D^BfVA-Q>P-Zwe z;|%7ZvMvfrLx6PA)1366l#K`VLUj=^JQGKQr;$;%1P{A3+amuyFpQjUjaj|r5k8@8&dKiV2D0a28K5jva= zscr^-stsDrbQN`~3V1XeM345Wu`L|$V2`1Pl`51 z!sHL}P{WSZ@>@dt0qCwF@)>_sDDUL@v?vgBJUvVtqIV{pdh9z%PiKh$SX?-VD2}@Z6HA6- zt@V4EnoebJo&k^RU@I_2;opR+}*c)nrCI`yn@ErJWz96(SbIVk1>cE!Tka7+3`tF#7q&mOS z`(vja3j^a6Q^nJG3SpdQm0wa<72`6^6xx!7k=(pVAT$qCygHU&2G^*HUT}^RwjJNp zVjsZ-`}x>d3-MAWGZ5r%sw4F*$o{=syLAd8Mu?DV4DF|;2*Jox zqVL%1j1#^%=iX>tz6Qjk3TO);M&rXtl%qgk9grE3>4MXk7Whlg72rmd9g!l$_+3&E z6*h-nCMPb4^T8$kZueK9(P+4T=;!doMXH%k2WDZ$>{4(7lz{?r+!{D2KSt$CV(H_H z09z`;*W-{JA{4V`;ct6^**HAhq-p$yC!Fv{xUAPqWOUMqgwdVO=ShY%=Zt@BDuAe`?$w6~HWQL{`llqWf6s}0s*z#HS;O3a z=ILyMmZ&A@kv(0D+vYjR5o^0XD5avMI0e%)%4(QMuouS5z3U;m`;cPc?0(9-y@U!e z8`cw(kspE<f=vKG@{6#xOuWYLU46A_{#wSGt9nrgw})%Z22yb0fhbwJaqq)%z$PaC_= z3ox7-F_lzT^9!i(CE6 zW<2&Wf2a{(QsxusH!M~2vW)|^uKs)OZ zmI^}fUwIueqDYM}Hp_|Vp>A79nJ8^LR5d1S;Q>w#hmAWb#T`r4AJ~Xv;6gnE-j*Qk zwNw7#)xPg>g$s)62xcF_l*sdm^_NrVX|dvZ&p>qY=srP47z1ewBWITjEe65;a(0E< zsKF5<#?0SAwMHrOG^N5~-08VWNK!`W|E7Jofg`@;V9vxN`V(KMQ7OQ50~f_DqPJi8 z6s(d7BHK|74FG*y=+P~=U{op#TT^k#OBsmpmz7R(n`tLDrm9z&lDKlR$rc{n&Wy_f}H^^xUb{sfU=4ICbJ`(9&;3Z3fCy0rvgB9M zYXJOzI!BVShvjpSRe=NmGVk>cdV`Q015u&=ITQ3#Gp7D;WU9-#Ty@{_tVkMAQNqTD z89X_&nz0hLSxzu+{iZ?fqt!=1tl;^;blU*(sJlZHnmNqp<|A?O8Yqeq>aY}@n1 zBd&ihKHMSw8p9mpUE#S1BM;d0J46}4d<00ZkaWga7oyiz?n2O$_km?HNrL+#l7`D1 zDt>O(bK^#^beJ$Dp;k3Q)+J?E0B-A4flwH2y@}{?;{_nm@P%QMps2J z#`ilc^%ORDrR0HkSAcEzL6MbEuv|s7a0Ar)gMbJT(!}yXkC_|qfJI;E22Fs6`>U2+ zV1&^n-1Dqhq~VvMo!jd|vkg^x@GPMw8SrLWQvGe4@@)xUShf-uDZ8HkE!_>b4{dqT z8096-(q!Ru;Ij<5@|jEX&B4JzS5AqWVG4h+OLc;we*kqEFMhlePe?Xo(mzk0QTAQb zpD2r0t+lznomct39G}wZEMuz0)=dgp3T>?BPsHbx^CB%dqpOboI~ogTn`N9K1hy>{ zDBae4+0e=;4Ed>107Xpg6!O@x>V~|>YdDrp^;g9CF{RNew0I&FVx}{X5%+2=zXe{D z)DMs9SjWl*_A?z_0KcjSCKJ!NP8N(+BX78sW+x%34{ePG(M^UYj%THt zxZ8TL#-|J$Ui@6z9;Yh}Z!tM%V>jJuIJ-?8kmCLBd^|wCgTzGsD_kLyfTJg|Cs%`+8tvvjHT@<@+c88YVruAnGHq;4A%KT z`@dcO=c%}~pTNFPbF|rymrfuW8#gW8GRQQEe8)QF8oAyYmLo%Jv;Y=7EHouB zJQ=5|h)@1}F#B{wX3e#`0jf@ocdnZ;E$5xtwD??6V3z;dPTQBe^HZq-b%{6VCF=FR zL>xf=$+cR=ko_y>!X9j&oZEAcOX#tMNcb;(xuU}kDM|P5mmN<5;map=HhG=w$|}(w z4F*XeZGLzBif3-phMaoKI`4adR)>&}aCKzXy<-RDAU(u_f-$(-Omb^%F>+tQyUWY- z98G`O5ncSRfQ;n3q=LbzbJNk}=XZs1__J63e;DEaOA!A=p#VP2rE}oOH-BMvLgYtc zoAcvckXV;~6fXD|`?DPrCnsupBsl^pc!s>84G60AQrQAUv~pvfJVGH*F3yd1!r-1e zi9&~F;796Dg(Wi1n4+u~#KD>ECTCUiM{t=D!kwPLM7V~k{HGdYq%u(>bX=z9#R zge?YcYjBNZvw0!CXZ)E}yiN$;?-`_vV=weI@%t6E>KQw$qZo?yP7%!-7D}&J;Rd^y z2L}gPL)GDF%_S8P%|t6;LU)8(vhxC{bue%1KQGKL{}`1SxM@5h3BqQW$1UJ=iHVKX z!>q&nVn}oCqRUI42H5o?zjm^4 zhTv#NSZ?tF^7J6}Ds4Id@g55ZMz$AERk7!_lo<;SCuZW33@e=0gl8*tD>!a0k^q_ViXjTmlOQizar{@TPjZ$e(u*)b zl&+l8$FXO3_IyDUh_4-QR3im{;hkU zv{vzd6YBp_9?y3`R?m*xel6XQdQ-D~W%obNJ?_u(^o)Wn2nbCAm5RjF3^UlDjNKOR z{-zm);7^zU^uJ~aeK0&5K7A zk!1|bDtR`F7u}LdQL>XuAiOL)$^!>_q!Rx_qE{et)MEwb@S{@W`+Z4Aw2az8N7*;j z28~WHm*L2qk_1^vZ{qCssnc0&vsCg(7oWohyP@9E!SL}lGkp5Mol&OL@SQWG!*9BR z0qAh(zMth9KCDMQT!@!?YhIMqNDF_IM(>}Gi}a7@vu~0@GO=V5?Pk#Sqt{UE%}PuM{~;(=J78A zSrs-=fTfW`08-7aQ5oi{Ll4And$a}6a7%A+l1f{j62K2!xMxo-1)`o$Id8iOER0N* zxIDeb$xtGU)+USD=qHDg(Y`X~J68tf`TqIO_Tn$%1NaeiYTKadL_2eajT1&)NB+^q2@D9b{MUY_>TNQpZi%SO_bqXjyXHB;Ui$Sf9@s+j;Wb z{id0A9C(t~>E@^vPF(@ScmscJxOc7zNXd^Oh>_aW(3u(xR)buk9$q9y|pmKaV!1QFxCztuHO}!PY}!G@y49mJ z0cZk6!rr+O$%3(;B?-}K84!e8{>9v~L;P_$0eQ4}M1oXBfsT{~ZTR)Ko%2eWMnbKn zb5q1ekkgw_RUy#!uXEEL9eB2&?El4NCZmw3r1hMX#a}lk-dBMCPR4OgqRj$-M;-^< hjOQhwL*8E5RB0mfPrR|R-jC_QfTWeADkby-{tw&r+hqU% diff --git a/apps/files_imageviewer/img/fancy_nav_left.png b/apps/files_imageviewer/img/fancy_nav_left.png deleted file mode 100644 index ebaa6a4fd34e51575a01da366312c20618985cbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1446 zcmV;X1zGxuP)R`@usIzf?P{x4#0gFqr~|(;IJySuwjr=+Ar78e&sHZ(Lu;P)*wKU%|U#jmpg5~Q6= zNl8{#mZGz>Q!_F$qJ8n=#Z9x>Jn_n|ZEtTsSzllOW_Wn`!@Rt_=!l4jAl`tKb-5%L zv7js_CMF<1KR>Fcr{|nbr~AR4Y-MG|y0EZdwI6@^^5yrikSZ}TQ5hH*C?{R4Q{?KT zKD6U2SFWfB2M0g0TCEGD5GUP%Y0a>J0W!M1fVuVU?d@ix(YV91PjUK7@OzY8E)OJ~ z&Q30n%8njA8kC)#t?uvd&xMXHQZzI)WQmTB-n1vQM_gQ-{_*3-7UA?*_bJ9=m|W(F zT+IHE$H&L3T3T8zSS*%BTHM>)YZi;eI#;9uNVch|X-go#ckf=VQmKq2-ORBYaGo52 zejyg&!SS;_ltMX3~N9_#ORsfn&tMTp}T$j*yAd)6-A(_4O6g z0=-^ug|9bVkxorbSsNQ0x9sPG&EF`laq6qgf=!d ztnQGKnVtDqz_Vx1Y=Kr=TU+Vx?;nS;5H`1m#Lv%9fqI)#T3Y%!3C+yRSpE-E!h;77 zwm7Z1{&Y;%TkkIqz&m9sAKBbnCkzsHry#@vbY{a-wI?zu7 zloV4Q9NtQWLUAT7Ev=G-*4EZ6|HZd^F*!MDB>C#<>PDGN_5sGi_Yq4ZlG7@css!ck z9};wyN`LrygSGPaaLVfqXl2Z+Nkm;ygvo12>(Bf+YwDwC`Hbwy5foiCI>(Z2*F z+nZVe;)K}P*aF#9Y8tUS3{lK|w(!NULrkdP#x17leSb zXU`h&IIwaw4`8eqNV6{>BDOh|vjhZ0E{e&QDDu0Pe|>%Zmb;{dg@s0w$z&rPA0K~+ zu^J$UblaCq5g(ljxEe?Y`8AmFYt-vOfqZ&;+Eh?bV07kp3Z#jN34Zfk3!OW_7k zM!Hz%fopN!Lja&lI}y+lIZjBszTeT&@!Ra|?DQ)q4Us*EN5ey8M=zh0NVTlX;X`2G z(+8kuN)-Dfn@v@Ns?$arfE9ks%*_0?uCDGc0&cYN@bK_KngiO{r&oDx0_$@6^x5~= zW5Gx^5k=$2z;)mYpdQiR47B2ZEBzOVMD;v(on_N_Z6xdRarMj=Ped`)=n zv4Dh?$k=SYcJSdjDa(58`F?t%ZzxBbaRs;9zaA#)un(S!5dZ)H07*qoM6N<$g4RXF AD*ylh diff --git a/apps/files_imageviewer/img/fancy_nav_right.png b/apps/files_imageviewer/img/fancy_nav_right.png deleted file mode 100644 index 873294e969db9160f5ddd4e1ab498ff60b080e3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1454 zcmV;f1yTBmP)Wa6`&Z+!IVkxf`V#(j>y7#5eg z5*PD+C=wGBwT+F9xi*_^fd=>X_FBba@wz8b0c3ma+OG#c&LYnSBp_4S(*6BG8m#QpsI))yBSw}|WBy?ft)>pk?VIMu|0u-xC@UxO$< zHa9o-0~vR8bXeVyB61x;@W6T@vgyO$TgWvPslhu zJ>BGvFeN3$D2UT9wO!c-2M2E;RvddB6cm(&J}nRg`1!DUaA;_#J})n?kc`&W*6f~w z$XoI8@o`6>)z;Ql1O^7iqc4Qr?IQ^Y2vDQmrd_^#`AagIo}RXO6Tw=o)=2K&OZ?8A zJDVKcH{^2p2j~ms)bf#Ff5Y^8{ZZ7~8Zw%koV0nHJ||9`FbS!%u(0sL`TfAafI}Du zN;}#qfQDkqhr?T=R;!O@W@c89(aOq-SHe5pO)Do4INRL6f8R{+tE;Q)Wir`E=nLN^ zERjf#VBjT`yZ^}0T`IW~brs!I17PDwDHNtJpz(@u7&_Ci&*x`nXGh4eva-_hHlhTo z>wKX6jrLg})!Ef*2q(qH#unh5y~V~`*!#E25W2>+0$@y%jAkE;d^% z7KiBQ=;#CV)c|?K?OZZNymTtyIv@+;=i$b0QLhID@u{gPOF=<_+1^cd)FbceJt|Pr3Z2#UW)pC9hbbpr%#_w3xu>9DucKZSqKjwKC}oa!!=;B zxw)ARh3h~maWUsB$KtMw06>R!GGHKatdM5?eS3TRA2TyEQ!m{-s9LkQG(13d^zuqc z)WBRWF9N%+J^)=)qIgeo*i|*CI?Xfzc;V-hCr|!<<;s9veooizpgD1ug<#0dV!Z diff --git a/apps/files_imageviewer/img/fancy_shadow_e.png b/apps/files_imageviewer/img/fancy_shadow_e.png deleted file mode 100644 index 2eda0893649371f8d92b92976d8542cdd1b601ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W@!3HGnP3ltxQbwLGjv*Y^lSRZuwe#}JO|p{EaWGAM`~zK|Yh zF7SQ+m+Ig>B0@o-N8?trihfzZ+Vp1~`{zf0o*#X0$hUAi%N$P)W1wCJ22WQ%mvv4F FO#q)zAp-ya diff --git a/apps/files_imageviewer/img/fancy_shadow_ne.png b/apps/files_imageviewer/img/fancy_shadow_ne.png deleted file mode 100644 index 79f6980a3ba5c43de120d963dbba2516b8f27ac7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 347 zcmV-h0i^zkP)dR9Yb&V8f!h)aDezHAsc|y@|hdQ zYJb}?8~~zFbQ)ku!Ey)KSukutuvdZ@MKMX|x|A3tPyx?YVhN^6z!Mi4Mj2f#%<;nh z2{>?YAzu|{u^;Oq!;f7Z4tPBpJEmZ+^GZ#$=9nz(K+UmK7}|u&EPi%aRt_C3qOFB_ zHc`~N>51%{?ijG?xsHt>MwRChgk=x_z0gh3O2xSL)-6?+2LKZL74~Q>MZjWtwukkA tvjRC=&j+0R$&bLyT7MhBcTXDISHC&xXU0&5CWHV0002ovPDHLkV1fX+la~Mh diff --git a/apps/files_imageviewer/img/fancy_shadow_nw.png b/apps/files_imageviewer/img/fancy_shadow_nw.png deleted file mode 100644 index 7182cd938ae98e7e28c65a0bc55df576042ff9f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 324 zcmV-K0lWT*P)2-&4CO{qhKP$XKD&mgeXEM77>~`RA}h@U^Z##eQZVtM>a-K?QT4 z&(8BFf(rD5V61)2I__wHYuRwoaDIqw5Vdr_JSDVr){#J@r;{vbDL|tRyCiirf~4OF zX-l=Ecm>@yR)1nSMt~dy90Zb`^`)TQbhf8jR@fA!l6V$musRyB9Y{p$SCW}!$3==V zk)fW)Xo{s^ez$t+XhmZj;ts)!kTokvmM>z)zt70000 diff --git a/apps/files_imageviewer/img/fancy_shadow_se.png b/apps/files_imageviewer/img/fancy_shadow_se.png deleted file mode 100644 index 541e3ffd3e88224b34a4d2097c66a780e6060aeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 352 zcmV-m0iXVfP){pM9=`y8<_IvWD02WY@RZ<9dgjNmAB|sYF}Xw>7Sq@O0000eMf9z;FC21=)67q_`W0*0KnS4AR00W2`RGn3i8UfsEegLO@ zPhds?2e1Tm)FK3=bymIAx?X=YFo3Mdh7W?@I#8s#svp!&PB> zwah@Ngd|l0N4SCfzvjtQnd$dZ0yM)N$X+lqdtN!Pt{Wn*_`0U}m1^#r1 mwpaW{;a?9KKt^WrpTAEd?0j1W(3L*`0000P{ho=rRL|66mGO)=r*Hk83F#~lnc)I$ztaD0e0sy?& B8X5oq diff --git a/apps/files_imageviewer/img/fancy_title_left.png b/apps/files_imageviewer/img/fancy_title_left.png deleted file mode 100644 index 6049223d1ec6af46e100499c01f6489c9e2c6240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 503 zcmV+)0005LNklqcp9&~$uJw{{rUub~E?-XJ#Upm4Fe%-Gl z!u%tb0N102a|s5;SPlQvJlFCTBbvYaK@wIW6Gjx@?i20AlVDJcHNfh25WRlbF6CIq zv9_ZnqOH`}ppaUR0@%ZcM9zpDt2uQM>f+Z#wIMmyuui3DeoYXWE|hQ{D$te=Yhgkq zIvyj+$t8T|S1wITzUftNOe(E+Qjn$kDotY;I5}1lRgwi=?K26ke)djLR5W2|!7CVH zJ-`tuAq|`lK978y+CnqGNCkUke_%Gig ukvFM-ftpWh!il7Wg7kz7Y?7xB@G*olNlgoj4E_Yv!rmdKI;Vst0Ha3^zyJUM diff --git a/apps/files_imageviewer/img/fancy_title_right.png b/apps/files_imageviewer/img/fancy_title_right.png deleted file mode 100644 index e36d9db2a7c6e570aec993d3665cbc13620115e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 506 zcmV+)0005ONklxjQB-g>5=x46nGBwseihc$zfzvTFh(=tCRj6cJ4M&ASrCAq-HbokPnRBAHVa2(-|l wYU(UxfYLN;KDSr z1<%~X^wgl##FWaylc_d9MY*0Xjv*Ddw)7kFH5l+P-xcE$W)3=fYI&uMKVzWNT*W|n zhqlRY)q0r(8Mg&Fu_zpISivgz+b7g)c6G&O{~njE??Y{u-MM!p^=9_W+X-j8mhfK? zj`H2Yy;kp%)!V-M3;EVThyB(Z@o88wpMja-vy^g)SgE!<&|(HpS3j3^P6|6H_V+Po~-c6$N>^IEGZ*^681?Yf#{6Zf~e!I`r4y-J+3m*Ue*gH=cNZ zzpU%p61aCO%jt%FHUKW&bEWLcUAGzK?;SYE)E{9#W9O8@uj{O@89qzNU(dkI YVCW(7-@(*!CeU;SPgg&ebxsLQ07`N|KL7v# diff --git a/apps/files_imageviewer/img/fancybox.png b/apps/files_imageviewer/img/fancybox.png deleted file mode 100644 index 65e14f68fd83b87f75c22c0c074e7b20bf20a133..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15287 zcmaKTWn3G5&@B{~;%>#=DG;={yF10TIJA^Ni@Q6dxD|J62@u>uaf*A8(n3=TLErSb z_x;^(_f!7a-E4NVIcLtyoQc=dQGJd}gNuTK@?2d_$pHDPf`Wp&gN=z?QPI&3p`b{G zsVm7Fy<0o~g!9hI>FTLkeXUCSdR`&CQ|`OGxubq*0?(JYNfXC5{*R2zWF6(Xx-T>T2>J&K|Eil&n6Lix zEi`275C{!+X!)7CS*e}=H>=RA%jh4XH)T6XDeap>QZ zuCvB3f1j3`!i;@?^<5L}xzP0QOB^9?Eo@W0)j~`y+S=c{by#*Uoo$DiKILjfWNDo7 zGyqd&{!#&d_P|oW`zcaEy@;d2w|y57JdXR@m44ad$Gcyz{_I2&GK4@SU`c&Hd(VQh zn#vD^;#Q75G(~U%V%iDZL@L=Tw9hMZzCDFM9j?16?PmU()egI=v!xGRv3`4gH%jYG z*XB5pVfpH2C-V9c_8xe%8@rGrVEZ`G|9I83-+!6xowV&cMz2~U_i)uGJ@S3*cKE#^ znI+w0?#cY$pob>5_bg~ZYi`wc9G?Q_yI;!^xaByQ6*CF-F7!LoI6}!W%HOm zn)78kmGgzB<<3%Ss~TX_waZ9m05q-1AFMtfR>_#;a^F#k^#p)TMJWuMY$%F z%=%jUAKs6$O@3rjj7b9g9%p$QdV5l>n-#J#o(%rG=J6u=#jCJnOQN^y{2O0)x&Yqprl%*#!!_|zCVEW-yaI3-X52yuJ!c9 zz6iUCoS&ax%2yIfhCSZHUTwP$BhI})gzWuY_kNXgz1*K3Fz$UQmp8oH;@~mz(&g{T z0*5JN@$_j~RW(h1-Lq}xFRb{(q)D{SX3WtO`gObC;WQ9!DO#{`WS)_(*3(jJ3Lmxc)?Yc*Af>4 zXe$gst9FHmyt#7KrhMt(-!b86SnN$#XDi-;E-tXxuPcS#V1!6;)8@e~HvOb#ByQ&M zcK?UuX`Ca?v*Y!yriExsd@4QoJ$zOm`&Ikyszd50kEry*&*@-WOMQL)1w}jVgR0J4 z{o{+}~L{4c-2cW8G<*T_5Qs0y+A@Nh*tb7dX$-KpW;Hf3Q%V!a9Rc-`M0ex{kr z|Il@RukPls=sp>NOZq~@c{)Hzjg^FF1czDSutYx6{UFoI%G9*$Xv+5SH(imbfq_9E z94fW)v+sKAibW+UZyC+*=Fjjeg3ZG`hZG6-&ECL;o_yU8w+oxRXfU4syJ9}5*O&7g zvgp|981c0xY6-ssnoDEoubAhwe~C1Ph{=UKRM=Dc2hC?qWyga7}FOlQ163X0-*oqNwC4Yek|~X5e^P*VcQF zkUhPwZc!iLY%3QJ2{Ho@I z%dr=>z!}k%0N@^JagB=^_|LrNx>w)TvQA5t8{oB96C=sH!(KuDB6Dd zQ~jz>|K~1IPiLg9-A#L4s^n>nME}i*z)>Q=T2~fvkfEN*E;={T9sKDFYe0s$@o-*( zoEh}zmtQ}znV$kaO$S!N?@O$4?1l{p$z5d4tKilfaUnH1{9i^XqJR3|Uyi+nOHf+* z3}Rk8>MrX*)A&fo;0NC5B%=VEvC=)mu&29i0Z0O`ytHlX;cF(qYo*pLff_-FgJM~; z`)Tu;nHg_i7E0>?{jNgCtlz)6Iu&!AhGYMFn3H~ zJ`xR}4KY&CDsFSI%$sALezXs*9+#c^b>%GE&f)276Jgv<&zGpyo3TDQ%pvJt+&`&! z{Shd!jqXoDjbjmZGxVY}3?{YhMhsiwHT=CS0NllEL&%itR?%i52HSB+*%#wyeQC#y zyVd6XT%3pt6!g3rD_gah3DtT()o>Rv4_d#VyNVK(HhUM8cE8n3B|E| zh}3;3MgAV}^Qx*Ui6_lVS8s3c9PNhg`}5c(1ENE!P=VRx+IEQGL91)lZX=qnPZ9q1 zw5yZO!no+NVgMz&qw6SP=(&e&;Z$>q9{zXi2*K8@yh{H9B^0|1%fk897`kfNUA1#u z!{IV-MMi{e(bIe`_|JA-W3M}=w#mV-ajYBW{>-4l+bof*j=QrEjP12y!e;c>Z&;;V zM^8p8Eobfr3B$fYlBk55<1%$+d-RJ$p7W&h#Y+@F{BUtO>E#R`VBQJ{x&;Dkx&$}H zhOSgb-6>zcMD(`*QoD<9_c&DiV!qaNaA$kj=NWEQ*MFBH`?d@mR1eODIlr^8TQ&6! z?Zu%cuPP3^JxSi%Ej-q-8cKc578ijX@M73*YmY660uq2%TywHd$$rc+JHxc=>e{aVhBM(C=M%@zXsoNWf$<@*&Si zfBaE0iEyQmu4#8O^y-Lkv9sT1-MYB#6SxX;Zup)VKSW5h^`mE2w@xP1CKEEQVqieE z-|qCmnZTox4%cD$#KBz8wr>J;jgQ;vP03?pziiiZf^9Ya9A+z3FRHlvj1|4zu(0z) zk!NHd77L4tsP$B}E)KJnWQ(xqc50Cd4qeLyo7NSYC(nUG-q(2o8G`N>r}!nR>VooB zgQ~`?w`)w4s9nI9q&{b&YrC(Q$Ybmtlea49Z8$%cgf)F5FpZ`{>nRg=iw*s=fI|x~ zs(Z3*nj?^gW{3$m)_kYV>2TDRihE(6$#=dJLrPn*^e2K-^tNl$r_6h8P?Ida`U7x3 zS=_602o@XE{9@RMKYg?j(ay&?`SPJK7pZm`;)Ul4eqxd^hX@u12smf1_zTYw*g(E^ zM>kZdJXPfif?ct?IE8t==XZliUxmmBke(C$Z9FIp@<~(>*En>z|3+X31BNaT$SY4M zNkx5vUujEG6+;x6sn725w@+MSoBhFHH>`f}h`>2f5Ojs|e21azA#TBNt+Y$R*0x%yhV(lOeN^%?TxVUzBBxe;St&eUh^Ev#1hE2>Fug5G zX0^DLvfguwUx&H2HtZ~8ygSPI>L&0uAoGh!j%9nnc2Cq}!FhthK>F_tp1{3$4vMKg z&#>U&p2+u9cG&k*{#!$}l9H0kukL=dX8|r7HIXq9h#IinounmdhBFKZqZ(xogX!ubN$md{4_8j{mQ2-|aUw4ZOE9DntRlBlZA$gv;G`P+hM&gLaJ zWH?F#8W%iq1I_poC(54AEv(1nYfRsk*%bleNu;9*L>Ou`FBBpuWk)I=cHcRX%htu> zoP@h!b-onASogDD5C4iX*0tkphDUA3I5@(^@qjz)0#*F^F*g#b`UY#EgjQIY+24A7 z@C0-HO_z0psDI#nETB7|@i%u8+$!cBZ%r)7`}NwOcb-^o2fg$I+KL&PkO&kFw(ilc z$Pd`|O7c#T*p_Qo)bpL6`-gnArJ&|QEv*&j1huMidI%JOS$n?YrAN37{#C`;uDB{; zyWOtHZi9)3tMHEtWzN2Rxhf*2*O&)7-)tCvtW;~KmwmZ%hb;U8DrV3KV zdtfrOdSFhq9-+a9j6eFPV+yUfr|TerITV2O=`OJg#4kzEg62zxF!xS_aG-5XOH~Ph zBsQi&)mfq6xujyijEGi$)3@y_|G@Ghobn{i3^-dSYmG9`2pZe1n%zFSvE`uUrBIaV zzXbKIyw@biKIOz>_^ar2;dpqe(DIya=(rwN`IoT-avuKeZr^=d$8Df(#4 zQx6RhoGc+FO>z+;V|&$8)7p>mH8pBo%xZ)Y?4=7jd&_3?KfbrE*aRPD!;PXec-5VY ztVuS6m%vD` zoFWnCLFAr|)tHdxa5LU%cnR&ZiDzEf^=`|CrdD4p#UQI?7Za&z^nDH^+;r^D3su@r znNEYJ)kW{!!(ADt52^N9LeqKWImiG2VNz=zL0mAJRx* z8p&o_w`Su}@UH6F+V;~J(5X~mftrXhiiHfeuD^`ZY<+loNH*~9wr-rga=%Z3<-y<< zn<#Z^Y$@Kb#19``Q4FH?rhOufTc3YpWm*cXIFeJ@ad^K2e52o)j-K)>zc7pZj~^G` zN}2}Q!aIUl(WZTwfU!nMU4Z;+DCMg%DBw*12}kmh8YrZ|cLN2*+$^atj*cm7sPq|r z!@1S7qXTZF#KqqJ+%T3`7D`^>7QKACwXhb%Il+maJ>}Dw5jUdMmERLj z^lV00V@9;Xs7jY1Ep8Y$fmYG^lDsBvI1vS?m0xgoY-$^Nh5gVju6}uVM$$eus+G0o{WIi^N?T&>ddhjX8|G3%UeA>(3)XB+rK zKDyDnGB0;#|Bf=;icdxo8S7+luH)X&^pZWQ_~Xo*G}_LhgSLh+9`{-v^!kk-(0dUyojhC0T| zD}}kjs(flk{NmN9fRNVyyKHy^dv>f69trQWB1iqI#6jx{`W#g|f`xve>0Chz%LT-6 z16?J6Am3OFW0`njr%oD6(|&DMv~nO5B*63L(=mob?(1$ZRh_Jh@d&H8Y+Ht1G91U- zr)RnFP0uj2WH*g@0|OG`0aJB4W%OnBA2X}U>TL(WFE}iWyCFS6;IA&P?Y_p?-q^5* znWg8?Fyl)FvOC2t(#ph^Z0U-Dwi{nMj3&kU%UHpS!oOswQfMTT2^J-H9ROFw-S;XpY4@f8S!Yi8jepr(*@yLuH$`62eH zs=Fa;YwJ&=?`ddhO&=~(KWKTq`7N`Olzm}kGvsk4^Y`r>!Ni+bg<Lw^6bY>kq~e zK=)vs&g}A91Lh< z+m;C)W8{Ihn^!PSgS>g80px2KK}N9PG)aRaRt|HjarO7-*rCv(TN+ZP<6N#M$$B6A zs*me>n>lpV{^<_^6d~Q6ihtG^Zb5StlnX1~-C{|grsBLSxxVjj0{%+cP)3pdxjVml z8x*(v7GJ6!{f$k7sd#QDuO>} zjCk;mXVWmC>n|fihn*Q_k(|}_nAGxdW!UQDM!>b1V!qV<(I@uw)o7;<*Lc9rFofpP z%S@Qp&tSpMhU_)0W+)Ph?=;TFR)G42h4ctdNEiA9D#dqL@?mF@H@9Ys<>%N#Dxt|g zAut#aXWs{Ga8VXsMoFU|(1^+dIpAX63*ceSA>&~)_(lp6jjmkXWOFvxwEdUX*?NW2 z=ZV{4N9%bQI0o5eZV`+Mn;Z?AP*zqeNNX2ZL7)4_+X;ZcHxz@joH>T)cM=9 z72M&=GuzfZU_9o)u0A0lG`Bm0IOc{Vi@l;6y}h?Yvf;Onxi6SOr*rsFF)5PIkV#9N zrX)vLEt>krTP0iwf<|vVo=;v{FQ42s-D9UQfbD_^r)hEW8ZTXjv{H4&_I>tlpVH9#F&N4Mx5=VwieJV!h6tl`gSKxTOwV`o(`2o(?@Ny=y zWz^8C>;9+Ep2eFt#`@gx77)~_urrdHT1G%!tarRQ!E!)xm`N9P&70;<;B^6}eqbG+z?~l!peI}w^v&MxDP*abNyuhW1CN~d{X#xgc z=F8VWJ!?Jp1<@~jb3YB8lOU|IMn&%YwcWZx8@m-Foy28C;if{OC||M9%}3}| z`oRb6TZ8=@mvzv-(9e9(YKZ? z-vm1-c%4+wWwBce+czuEsU7#ZolNZ~Qvpf*uRo`4-v4MbsahDfF7slbfEYv!G2GaA z?6Wc{QDP`iGbiLw}s_oFyv-?|ms6^HD1|!Dy9#g^T{c}?J5~f7vU(5GC zV17IMWmm@|el+7OV(#hAwdm10&Jc}t%V-J46$q=`^s33gtYB{V%vmKCn5E5>r!d|MS7TPrY{TqUH6$ zGgPk<$Lpg9B@a}pEw6^?p9UZCWkl@+>Jc6vebkQR{ zrI5U>EiY72u%2Z>utv};v4>8~{s+{g8rM0@@{-nnr0@sP8{q^ZM-LI?R^314!%h-j z+xtncjPhC~%0 zNpU>;J@(;LL4>Tr45BwJb^fJ&*1?)RvOp7&Ml3cV3iIGY*R;Y@Zld;5=Z~IHm$B6m z%V}kK^8^0g2W;+bWKOFW+F<c*}T=l;am@$VV6qC1M`w-a#xbePQi{EFHHjQom|`GY|TZRcV@5_-CB-B=5o_+RK=rIjVJpOT8sOyT5UG#uDp;6gl)` z913|no9~ZWf8{*flTYOy`!nVDc`PyTmT9%}GdAq&&GUM(l6@DHpwTo+X zZ#irZY^YSIpIxJ0ov_Ei*^D9tvsx<35zUZbhsHPf+7 zi&0cdDeWsq^18ZyT`hLYV^ByNKln>e^i4Ci}8GT3YQlH?U7Q$Xsu<#qDkoc6=U~ZFHB|&km$6 z-*oTp#N}ZX_Dj)t%s*MnW=N+-K#%4dFDKR zYPf|riI{wT-URu9@w-vh1!R$Y9v9n-Y;|Keheeg1$$9R%92=NyUKlkPEE_iX75#}d zAaHv?Bb08=OXp40KS2>RB6ktL5_hns5Lql(=~k_r|Ehg)Aqu?Rpo*jRr|HE8eWFwu z-H3UhwoxU?tvISr14caeJKk{j!*2guwT)BMLb2}=wA}boC3ITtTtku9?gv84&4&FQ z{(|6_`ZQv!?E%qcU9FvNm21c^L6##)5u5vj#-_c2B!l-2iYX2@ELZJf3Egea@K-|I zDc7u97JVg8+P=&&PWAukavlh#Zp?%e52NTVA>#I5tu{Dh&(OqqshoI3F^l6sb3HB8 zbgo#8f9wl7A0)gZG@-4VLCr8hDYIo^h1gRj3ZbR#>?xyym5z)Myk|UvI4m&*Jr?k1rD{3L+wq<+nC!Mv6&`Ic4+YM*Kz<5y=gZLWqT8)5FN)x0 z#J_fgUq`_^(5c@bvP(@UTRDQ98fzdF>uaD|^+TPb`21K#e1F;o9@!b2>^o@?(D1? zd#K{P?6#n$L(OR`rxK5+uIUb+ADPd%PqRN-ZUJn0e9IsSRNa~-tKgBk9UT*Eu0>Fj z2mDL1C~L0yW_6QlKx;*{Ec?HWZR>pmr)QID@jVbu8IpgSl;5q>ZrLObX9NgUdPd=h z!p`Q5Z{I1QXvhFHQ=|XA7edbsj@yk6|I^JAO{1fg{(3jtP%p#7hZFf}EdA`-B4?<6 z8w{>V1?r?f=$;|f)cyHc%hcd zPpR+0(au7hfvnhn(RkgB7>VJgSGwUMG~2%#9$%FMy$AADY^Zm&)X=& zfoU>Yb+R@=J>w-KE>iX;{UHtlnC6Vl=bF`uol?VtGmt;j4g7d}1{+*N9yak)K8sk1 zA!`~`M6eYe=-SZ+xN>3~>2bE#{*Jz(z=sb?`tisyB}j}zl;%nhjiybm%>Bt%4Imry zEdd>F8Aay30vS_>ilbPPhS^~^hBq2;Zu)?uG=|-2c0cT19`h^2O0juz>1l|%y5H02 zAKP!=ZCzV5e*HZeWXh~!hdXqEcg|?-BnII5Q~7y)>Uwc+xR_{ljArL|cMMAmcz*B9 zzp3Y_AlN8cMes^Hnh*b(kH4SD!mdLzW}1)+T_Z~z^(T9NXzuEjv8lD_uf{Jw719tl zv`RP-1Vt3Qa%#u0W;ub}DQ{YWfXaeYZjSD_&Pq!k+rb~KvjR!|7ApLSIUzHqTu5~k zZlNNS$SR;_M~4^gySor$QF19GPCJE9DfugWpS>qSB`n-=up_e2oV*lIm#PNSaEIz| zN_s5qGqgEFUSVASNv`Ub>VC?U-#HIRFN|^N1xmjLmE!K_$*>TC5_jwtCKUHv8d^_1 zs;1Q{D|ejt{D~+^C1`r{oWan8l<#~BPROc2kK>kbDn=DpRuD$}-tHq_3muSPQzKKs zFh$MNy{*XI)z$0{X;5fNTZn|AiBK%m91t1NJ)ccRWo@;nN^Hh*AT=5_7*?MJoYl7# zsG&Iq-5+G?@_(+awcx@U=FOyw5c4=US|ycM8ob=&k<&+w_5qtc_h9O!R7h`RSs|VF zIsAH?s?Jz>r}oT^kGjJzVdVGe>8WvnDz(5nJD+a38C(|0l@k*==(J-nfnvA%39?yt zd~EiFG(~-#Jv*>qQcZP)a&ksBZe))MP8-yQlOj4rqrrwD*ln zP|O<7jtX+3!JXt^M1rU4hvitgY48W)YMSr7ur+FbY_ZHqK32Ah=X_UsEIwo?x?f`5 z?4Pz2aEVh+&?_0;#=m-@UL%17-O;O-v=#VygX-}a;_ouc|AQa`J5XkOD@@79zCe}p z3=yNAr?&)8?nO4ORY2auh*4&!_#Ti2DvkwVo&KIS(tiHU0h*i4Rl+=3(mnjW7hwC1 zAi_DOVvnXn%EoQ()PtqtWt@3b&U-hqMYkfArT7a$@}~ zO1e%1uyy|n*`t=U!pne0%(E&?U;;R4>_{8Gb7YJrB*8zqn<5xV@ZOICA~tRLBSPtz-WCq`;lH&q;CHLS;k_ z&+tksI(dl8o1;tX^u$Sr(RicInuW6*AqCCMF`h#h`*AG{jfN?|H~eScV3bxjcH^9n z;(iMHcsMdAOk?-_B{#nB<{mIJEUppDRVjc3FC3Fnel3X**H6t`9$?EGSx8Imi&}O=D)3r}Mdq_BADjr22HfLfZ_yKoXDDvr`}xxW)WHPO7jgr`lKmh7b=wjb z@ok_#*2l7T0^GVbAg7TXh#%b)>+Kl!&~@BlHSKp3tm(L#f#j<1W3R>%qT!W1Oh)X` z+@Gonlml&G@O%(>1cKO8qlXeW+RVzRbL@p6Mb{tDhx`2(Q-kKEViU@7p`5M z&0X7p$-HSH$$aLDmM21-5#m&ky7QRcF49O50yET=SsFnVaw!USCMCB@w2z48G{dnT za_kDvMP;FhA~z!M&M(Z-$_&=l);?ox%USH#IFkKmrovOF_<)$Q&2cYswDSj7S+Q=8 z&mipO3k=hCZU_cV#hdBUeysHv<$ORg{Fl5jMgr^fuNs}q5k?;gI!3xBZ2g+@*I)Cs zQuvu{A&rl#d**G<4R+bqHa10!Z4Irher%O3n{Au+mL#mvkg;Y~!4Ls#_{9*RK#`Ec zD2+^9X+~ecKl|VmAhu+cbUrggXw*VW#uhA#v;d}zq_ud11YLU5r5Hm*l9dIL7#KvK zb9gLEn@zXP%6=hx;c&<<5uGw|v_i8x@`d`RigCj)QephA@g8eZtr*jq}#JboQWEKRLqUlV8Y+dy+&S)&E;Q&lgX*Q43-DzVC+kO{V-tg7w$ zfjxnRt=<;X5Nr`NV*GdG@Kx;Mmu?xQpA)1sh!%!~CEx`$EM+^U$R^P!pUy`7jc9Yb zi4Ly@w9BFnNM$uWXc|r?$}M{`J!aAU)xq4vdItgnen!&)S@c3* zA~EK|g1?ziSo!5bOjT|=Q=W1iz@E-2BsS~Rc1m+9>x=&ZpP0Yi*rEtwWL}Je!iJ>!TXxo z3cms%TXPJsy~k&4=OS?}<~_Xv##~Kga)=L3TVTe*t!p^Ye8BMT$be=Id@eN0C{?)wnjYzmbwnCf{uVL^VhXP|IDf8>g`gGQ|ssLZoNNi z_$1i(o=CB>{5p1mfBb}H~(@x%rE-{HE=-%(5ke}w95e>~LKh<_@SN*=x>{?<#X;K4c8PwA% zXPbZcp4xU^R_)cmXr~CFH2)V<+elz3|BFv5pr)(1o#B^A5X~@ZA>UhbJ+SNn4e?iq zVQ2qPMfPvcN~a?49&o`AEc%zrx}_l%-^*B6YwN`&EyPoQhc91xKj4nO>+HSY5e3NbT5>14lW zvH(!3VfDuE0#8)16}$GF<-gtJ@6ax@WShYlb8xyi5rT;sYgKp@(Sk8i5Zl+}R#?vm zarSlP%r0L|VyyVlNG_5sD=WV&OBZ~X)yRj7vKH_uokdmhkNC5>V`i)B!tc^WOd>r{ ze@+r?kXmWreq;iFO=>YJ7OKI^F^OuNZi&O|362sxH|5*CJ)m|>e14nYR3Lprfq@$D zFu+PAg1i?VD5o^^SHVU>@-U9-(1MBK0>Y3QNKS_0We5jM_5n9I6AKWG)sIqH^-D_uGJ>4%qA$!w2vKd&1%uDXv zhCgPE=93vk1-|@f4H7h&k>jF)iifw6IeKz!Y=R{Gmlbr=yOdZ6=SA@qqgEn7@&+xd z!((Z$wgwl+_Z5e0<7o8BN6GI zVsSp&4|T#AsSB3-{{=(c?~dx`5sNShg( zG#1q@Qj%K?q%%xzkL2U+dQc_TFZknbjji%plZ&gd!E$ZGg7ew+ST9&28u`mYTD;2c z^qgP7&fbSYTr_m;-WWY+kbcKKqOu(f`$TR}Ohn?ltdeW<{xb`{EXL)rMTXQ4NO6FK z*#z0$npSroAr=_=bquv4_a|5LiE2rp8M{;kxSs(^_qO0pn&F>%@op}SfPD)3cxm1br@0g4!H;1NpFvk(5T@A*kUm`Tz{x*gq;NnQ(n4u z3dtz2SYp96k0aGsMglyYF;!9xQyLV;blzZbhdY|zcVFl{pkXj|DrL9j&F7)7aX!bQ z9uyUPX|I(Pf=2uOKYSU`5@OHk83eFJp;E?k2?ii-rZY-%ln@JPkiaGuUh@YPY%iML z1P?QOK;7p|)t%?U8!E?%8SukVzP)(~8G5^t`gZIR(p6YUi4uxya-h^~ECu@6 zqqAC%xW;+t()4VM{|wJ6e$Ni7Xl}lj355EB0e141pK#~D=KRAS#y*f9n%n3*h(Xyd z@8`S&tQJN@p0;1yyyMk|xH0kL)DFj+{IgEZ{8L&PJ^rx9!ELjM;COT8jNB}US7ijV z+sA@%1LRXs{P`>F`irv9+orz1Yj@%sK8jfC)-NaI3l15UTe!Jfgqe38|O!;sI2JS^U`6FGzsESspo zJ67>9!9_8nklSSzoDnSp&(1%y>P3qusVclU!9(ebDy1zQ=T7II#d}B4wqMr-?xp9M zb4=*|Uhol>-Mf`D$~TbQCCnc=Rl{Gw+knJg)Y%*Tfb5P1qh7+YmKXa$2g>HNrW9#Q zhE-bm9OOk`nz2RjjzWl?!MMgFy|_vY_MnWl5wQM%iHK851<&M20;Eeik3|yItH%6|oN9Eun6{%d= z=N*eANB|4DmbrRaN=(|bb2)575&|JP3t}M@h=m!1$dRRp%&-+T0AF8=%d*i<2z{Lh z^F3)IGo1%ZbKG$?nNultCSy0di(F%Ybg&(;k z1izF4^>M!(M)W!<><(H=dwPQDr5OZ?ie+6C6uj**G(x37O`rWR5pseAXJt9$EgTvv zx4a84!V;Ov#?xo~Do%gr{GPUXF8H#!%uK!9%Sr-IZP?*+33*8(p3BHHv%9#C06jvGqkfob46X?zh8#~j zPJ7k1&cfrel5#z{5%T=s%-E-Z#5|L?qmmUG0d=2Ak^=?b&vnK`{Xu_3_vk^E?4$xx z*;D$%(M|j94SX0STo#sIR+rpJ*tY&@s71E=mkubfnYXRVwX8VB+&7aaX zDkYYB08*`-r~k?r|BEg|>3>NVQXVe+TgCDnY4`*WEFO2#&}dCIr(efKj#%hFlb5GZw{&Grpn$HOUs!iagffg< zUOr3@Dmwyx;;e{LUpr{gNl~)W zX@2n$J5io08JiWmLC#GBrIG(1`lzs(%$$xv4*B5(677_}0DvK1{DsG-&*K_EoMlrU z1r9}lAnTooE-E#wQ+?v#McpTvQxiAkk)126n3!C*p}Ki}-pxM`r2ez?TgTl*eVEkx*hsQ4AG1Scb@M1?Bo z64>{l#I7SqZM5$0m$gw!#s{=|bGn1d3YpvS_JPXsv{T^2Xvc)HkNba5@(>xrwNvD3 zSJGWRM!%K`GJiBn_W_SS%OI7~BQ#W!$zg(OccJ37cp#jKUfwUV>yVMqNf$*9P>0_X zQ3XzOz@}VP-r7gmFGi5ST<-NsaScbte+`6jy-v##`Q86b z6jG|SjsPcT{TA5e7iAKdP`-O5snH$Fp#~DWi2dP+tDEgGywPnPkgPeJ+9QTdTzE{X z88~L0W4K4`f9Q5Q<}Oh(JfaAvN+0-dgE;%?(P*qXNwpB_)-Zzm*mP zcex|GZO8(LWj!(h`(I@JpSU%%%+bka+4p#^=Li0xSy-m?t6ws8mE^qtzmeB(XQ@wU ZMt7F5hocMxav&E)U0Fw|QQ>vO{{ZOG+C=~W diff --git a/apps/files_imageviewer/js/jquery.fancybox-1.3.4.js b/apps/files_imageviewer/js/jquery.fancybox-1.3.4.js deleted file mode 100644 index a1db7b6198..0000000000 --- a/apps/files_imageviewer/js/jquery.fancybox-1.3.4.js +++ /dev/null @@ -1,1158 +0,0 @@ -/* - * FancyBox - jQuery Plugin - * Simple and fancy lightbox alternative - * - * Examples and documentation at: http://fancybox.net - * - * Copyright (c) 2008 - 2010 Janis Skarnelis - * That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated. - * - * Version: 1.3.4 (11/11/2010) - * Requires: jQuery v1.3+ - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ - -;(function($) { - var tmp, loading, overlay, wrap, outer, content, close, title, nav_left, nav_right, - - selectedIndex = 0, selectedOpts = {}, selectedArray = [], currentIndex = 0, currentOpts = {}, currentArray = [], - - ajaxLoader = null, imgPreloader = new Image(), imgRegExp = /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i, swfRegExp = /[^\.]\.(swf)\s*$/i, - - loadingTimer, loadingFrame = 1, - - titleHeight = 0, titleStr = '', start_pos, final_pos, busy = false, fx = $.extend($('
                ')[0], { prop: 0 }), - - isIE6 = $.browser.msie && $.browser.version < 7 && !window.XMLHttpRequest, - - /* - * Private methods - */ - - _abort = function() { - loading.hide(); - - imgPreloader.onerror = imgPreloader.onload = null; - - if (ajaxLoader) { - ajaxLoader.abort(); - } - - tmp.empty(); - }, - - _error = function() { - if (false === selectedOpts.onError(selectedArray, selectedIndex, selectedOpts)) { - loading.hide(); - busy = false; - return; - } - - selectedOpts.titleShow = false; - - selectedOpts.width = 'auto'; - selectedOpts.height = 'auto'; - - tmp.html( '

                The requested content cannot be loaded.
                Please try again later.

                ' ); - - _process_inline(); - }, - - _start = function() { - var obj = selectedArray[ selectedIndex ], - href, - type, - title, - str, - emb, - ret; - - _abort(); - - selectedOpts = $.extend({}, $.fn.fancybox.defaults, (typeof $(obj).data('fancybox') == 'undefined' ? selectedOpts : $(obj).data('fancybox'))); - - ret = selectedOpts.onStart(selectedArray, selectedIndex, selectedOpts); - - if (ret === false) { - busy = false; - return; - } else if (typeof ret == 'object') { - selectedOpts = $.extend(selectedOpts, ret); - } - - title = selectedOpts.title || (obj.nodeName ? $(obj).attr('title') : obj.title) || ''; - - if (obj.nodeName && !selectedOpts.orig) { - selectedOpts.orig = $(obj).children("img:first").length ? $(obj).children("img:first") : $(obj); - } - - if (title === '' && selectedOpts.orig && selectedOpts.titleFromAlt) { - title = selectedOpts.orig.attr('alt'); - } - - title = title.replace(//, ">"); - - href = selectedOpts.href || (obj.nodeName ? $(obj).attr('href') : obj.href) || null; - - if ((/^(?:javascript)/i).test(href) || href == '#') { - href = null; - } - - if (selectedOpts.type) { - type = selectedOpts.type; - - if (!href) { - href = selectedOpts.content; - } - - } else if (selectedOpts.content) { - type = 'html'; - - } else if (href) { - if (href.match(imgRegExp)) { - type = 'image'; - - } else if (href.match(swfRegExp)) { - type = 'swf'; - - } else if ($(obj).hasClass("iframe")) { - type = 'iframe'; - - } else if (href.indexOf("#") === 0) { - type = 'inline'; - - } else { - type = 'ajax'; - } - } - - if (!type) { - _error(); - return; - } - - if (type == 'inline') { - obj = href.substr(href.indexOf("#")); - type = $(obj).length > 0 ? 'inline' : 'ajax'; - } - - selectedOpts.type = type; - selectedOpts.href = href; - selectedOpts.title = title; - - if (selectedOpts.autoDimensions) { - if (selectedOpts.type == 'html' || selectedOpts.type == 'inline' || selectedOpts.type == 'ajax') { - selectedOpts.width = 'auto'; - selectedOpts.height = 'auto'; - } else { - selectedOpts.autoDimensions = false; - } - } - - if (selectedOpts.modal) { - selectedOpts.overlayShow = true; - selectedOpts.hideOnOverlayClick = false; - selectedOpts.hideOnContentClick = false; - selectedOpts.enableEscapeButton = false; - selectedOpts.showCloseButton = false; - } - - selectedOpts.padding = parseInt(selectedOpts.padding, 10); - selectedOpts.margin = parseInt(selectedOpts.margin, 10); - - tmp.css('padding', (selectedOpts.padding + selectedOpts.margin)); - - $('.fancybox-inline-tmp').unbind('fancybox-cancel').bind('fancybox-change', function() { - $(this).replaceWith(content.children()); - }); - - switch (type) { - case 'html' : - tmp.html( selectedOpts.content ); - _process_inline(); - break; - - case 'inline' : - if ( $(obj).parent().is('#fancybox-content') === true) { - busy = false; - return; - } - - $('
                ') - .hide() - .insertBefore( $(obj) ) - .bind('fancybox-cleanup', function() { - $(this).replaceWith(content.children()); - }).bind('fancybox-cancel', function() { - $(this).replaceWith(tmp.children()); - }); - - $(obj).appendTo(tmp); - - _process_inline(); - break; - - case 'image': - busy = false; - - $.fancybox.showActivity(); - - imgPreloader = new Image(); - - imgPreloader.onerror = function() { - _error(); - }; - - imgPreloader.onload = function() { - busy = true; - - imgPreloader.onerror = imgPreloader.onload = null; - - _process_image(); - }; - - imgPreloader.src = href; - break; - - case 'swf': - selectedOpts.scrolling = 'no'; - - str = ''; - emb = ''; - - $.each(selectedOpts.swf, function(name, val) { - str += ''; - emb += ' ' + name + '="' + val + '"'; - }); - - str += ''; - - tmp.html(str); - - _process_inline(); - break; - - case 'ajax': - busy = false; - - $.fancybox.showActivity(); - - selectedOpts.ajax.win = selectedOpts.ajax.success; - - ajaxLoader = $.ajax($.extend({}, selectedOpts.ajax, { - url : href, - data : selectedOpts.ajax.data || {}, - error : function(XMLHttpRequest, textStatus, errorThrown) { - if ( XMLHttpRequest.status > 0 ) { - _error(); - } - }, - success : function(data, textStatus, XMLHttpRequest) { - var o = typeof XMLHttpRequest == 'object' ? XMLHttpRequest : ajaxLoader; - if (o.status == 200) { - if ( typeof selectedOpts.ajax.win == 'function' ) { - ret = selectedOpts.ajax.win(href, data, textStatus, XMLHttpRequest); - - if (ret === false) { - loading.hide(); - return; - } else if (typeof ret == 'string' || typeof ret == 'object') { - data = ret; - } - } - - tmp.html( data ); - _process_inline(); - } - } - })); - - break; - - case 'iframe': - _show(); - break; - } - }, - - _process_inline = function() { - var - w = selectedOpts.width, - h = selectedOpts.height; - - if (w.toString().indexOf('%') > -1) { - w = parseInt( ($(window).width() - (selectedOpts.margin * 2)) * parseFloat(w) / 100, 10) + 'px'; - - } else { - w = w == 'auto' ? 'auto' : w + 'px'; - } - - if (h.toString().indexOf('%') > -1) { - h = parseInt( ($(window).height() - (selectedOpts.margin * 2)) * parseFloat(h) / 100, 10) + 'px'; - - } else { - h = h == 'auto' ? 'auto' : h + 'px'; - } - - tmp.wrapInner('
                '); - - selectedOpts.width = tmp.width(); - selectedOpts.height = tmp.height(); - - _show(); - }, - - _process_image = function() { - selectedOpts.width = imgPreloader.width; - selectedOpts.height = imgPreloader.height; - - $("").attr({ - 'id' : 'fancybox-img', - 'src' : imgPreloader.src, - 'alt' : selectedOpts.title - }).appendTo( tmp ); - - _show(); - }, - - _show = function() { - var pos, equal; - - loading.hide(); - - if (wrap.is(":visible") && false === currentOpts.onCleanup(currentArray, currentIndex, currentOpts)) { - $.event.trigger('fancybox-cancel'); - - busy = false; - return; - } - - busy = true; - - $(content.add( overlay )).unbind(); - - $(window).unbind("resize.fb scroll.fb"); - $(document).unbind('keydown.fb'); - - if (wrap.is(":visible") && currentOpts.titlePosition !== 'outside') { - wrap.css('height', wrap.height()); - } - - currentArray = selectedArray; - currentIndex = selectedIndex; - currentOpts = selectedOpts; - - if (currentOpts.overlayShow) { - overlay.css({ - 'background-color' : currentOpts.overlayColor, - 'opacity' : currentOpts.overlayOpacity, - 'cursor' : currentOpts.hideOnOverlayClick ? 'pointer' : 'auto', - 'height' : $(document).height() - }); - - if (!overlay.is(':visible')) { - if (isIE6) { - $('select:not(#fancybox-tmp select)').filter(function() { - return this.style.visibility !== 'hidden'; - }).css({'visibility' : 'hidden'}).one('fancybox-cleanup', function() { - this.style.visibility = 'inherit'; - }); - } - - overlay.show(); - } - } else { - overlay.hide(); - } - - final_pos = _get_zoom_to(); - - _process_title(); - - if (wrap.is(":visible")) { - $( close.add( nav_left ).add( nav_right ) ).hide(); - - pos = wrap.position(), - - start_pos = { - top : pos.top, - left : pos.left, - width : wrap.width(), - height : wrap.height() - }; - - equal = (start_pos.width == final_pos.width && start_pos.height == final_pos.height); - - content.fadeTo(currentOpts.changeFade, 0.3, function() { - var finish_resizing = function() { - content.html( tmp.contents() ).fadeTo(currentOpts.changeFade, 1, _finish); - }; - - $.event.trigger('fancybox-change'); - - content - .empty() - .removeAttr('filter') - .css({ - 'border-width' : currentOpts.padding, - 'width' : final_pos.width - currentOpts.padding * 2, - 'height' : selectedOpts.autoDimensions ? 'auto' : final_pos.height - titleHeight - currentOpts.padding * 2 - }); - - if (equal) { - finish_resizing(); - - } else { - fx.prop = 0; - - $(fx).animate({prop: 1}, { - duration : currentOpts.changeSpeed, - easing : currentOpts.easingChange, - step : _draw, - complete : finish_resizing - }); - } - }); - - return; - } - - wrap.removeAttr("style"); - - content.css('border-width', currentOpts.padding); - - if (currentOpts.transitionIn == 'elastic') { - start_pos = _get_zoom_from(); - - content.html( tmp.contents() ); - - wrap.show(); - - if (currentOpts.opacity) { - final_pos.opacity = 0; - } - - fx.prop = 0; - - $(fx).animate({prop: 1}, { - duration : currentOpts.speedIn, - easing : currentOpts.easingIn, - step : _draw, - complete : _finish - }); - - return; - } - - if (currentOpts.titlePosition == 'inside' && titleHeight > 0) { - title.show(); - } - - content - .css({ - 'width' : final_pos.width - currentOpts.padding * 2, - 'height' : selectedOpts.autoDimensions ? 'auto' : final_pos.height - titleHeight - currentOpts.padding * 2 - }) - .html( tmp.contents() ); - - wrap - .css(final_pos) - .fadeIn( currentOpts.transitionIn == 'none' ? 0 : currentOpts.speedIn, _finish ); - }, - - _format_title = function(title) { - if (title && title.length) { - if (currentOpts.titlePosition == 'float') { - return '
                ' + title + '
                '; - } - - return '
                ' + title + '
                '; - } - - return false; - }, - - _process_title = function() { - titleStr = currentOpts.title || ''; - titleHeight = 0; - - title - .empty() - .removeAttr('style') - .removeClass(); - - if (currentOpts.titleShow === false) { - title.hide(); - return; - } - - titleStr = $.isFunction(currentOpts.titleFormat) ? currentOpts.titleFormat(titleStr, currentArray, currentIndex, currentOpts) : _format_title(titleStr); - - if (!titleStr || titleStr === '') { - title.hide(); - return; - } - - title - .addClass('fancybox-title-' + currentOpts.titlePosition) - .html( titleStr ) - .appendTo( 'body' ) - .show(); - - switch (currentOpts.titlePosition) { - case 'inside': - title - .css({ - 'width' : final_pos.width - (currentOpts.padding * 2), - 'marginLeft' : currentOpts.padding, - 'marginRight' : currentOpts.padding - }); - - titleHeight = title.outerHeight(true); - - title.appendTo( outer ); - - final_pos.height += titleHeight; - break; - - case 'over': - title - .css({ - 'marginLeft' : currentOpts.padding, - 'width' : final_pos.width - (currentOpts.padding * 2), - 'bottom' : currentOpts.padding - }) - .appendTo( outer ); - break; - - case 'float': - title - .css('left', parseInt((title.width() - final_pos.width - 40)/ 2, 10) * -1) - .appendTo( wrap ); - break; - - default: - title - .css({ - 'width' : final_pos.width - (currentOpts.padding * 2), - 'paddingLeft' : currentOpts.padding, - 'paddingRight' : currentOpts.padding - }) - .appendTo( wrap ); - break; - } - - title.hide(); - }, - - _set_navigation = function() { - if (currentOpts.enableEscapeButton || currentOpts.enableKeyboardNav) { - $(document).bind('keydown.fb', function(e) { - if (e.keyCode == 27 && currentOpts.enableEscapeButton) { - e.preventDefault(); - $.fancybox.close(); - - } else if ((e.keyCode == 37 || e.keyCode == 39) && currentOpts.enableKeyboardNav && e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA' && e.target.tagName !== 'SELECT') { - e.preventDefault(); - $.fancybox[ e.keyCode == 37 ? 'prev' : 'next'](); - } - }); - } - - if (!currentOpts.showNavArrows) { - nav_left.hide(); - nav_right.hide(); - return; - } - - if ((currentOpts.cyclic && currentArray.length > 1) || currentIndex !== 0) { - nav_left.show(); - } - - if ((currentOpts.cyclic && currentArray.length > 1) || currentIndex != (currentArray.length -1)) { - nav_right.show(); - } - }, - - _finish = function () { - if (!$.support.opacity) { - content.get(0).style.removeAttribute('filter'); - wrap.get(0).style.removeAttribute('filter'); - } - - if (selectedOpts.autoDimensions) { - content.css('height', 'auto'); - } - - wrap.css('height', 'auto'); - - if (titleStr && titleStr.length) { - title.show(); - } - - if (currentOpts.showCloseButton) { - close.show(); - } - - _set_navigation(); - - if (currentOpts.hideOnContentClick) { - content.bind('click', $.fancybox.close); - } - - if (currentOpts.hideOnOverlayClick) { - overlay.bind('click', $.fancybox.close); - } - - $(window).bind("resize.fb", $.fancybox.resize); - - if (currentOpts.centerOnScroll) { - $(window).bind("scroll.fb", $.fancybox.center); - } - - if (currentOpts.type == 'iframe') { - $('').appendTo(content); - } - - wrap.show(); - - busy = false; - - $.fancybox.center(); - - currentOpts.onComplete(currentArray, currentIndex, currentOpts); - - _preload_images(); - }, - - _preload_images = function() { - var href, - objNext; - - if ((currentArray.length -1) > currentIndex) { - href = currentArray[ currentIndex + 1 ].href; - - if (typeof href !== 'undefined' && href.match(imgRegExp)) { - objNext = new Image(); - objNext.src = href; - } - } - - if (currentIndex > 0) { - href = currentArray[ currentIndex - 1 ].href; - - if (typeof href !== 'undefined' && href.match(imgRegExp)) { - objNext = new Image(); - objNext.src = href; - } - } - }, - - _draw = function(pos) { - var dim = { - width : parseInt(start_pos.width + (final_pos.width - start_pos.width) * pos, 10), - height : parseInt(start_pos.height + (final_pos.height - start_pos.height) * pos, 10), - - top : parseInt(start_pos.top + (final_pos.top - start_pos.top) * pos, 10), - left : parseInt(start_pos.left + (final_pos.left - start_pos.left) * pos, 10) - }; - - if (typeof final_pos.opacity !== 'undefined') { - dim.opacity = pos < 0.5 ? 0.5 : pos; - } - - wrap.css(dim); - - content.css({ - 'width' : dim.width - currentOpts.padding * 2, - 'height' : dim.height - (titleHeight * pos) - currentOpts.padding * 2 - }); - }, - - _get_viewport = function() { - return [ - $(window).width() - (currentOpts.margin * 2), - $(window).height() - (currentOpts.margin * 2), - $(document).scrollLeft() + currentOpts.margin, - $(document).scrollTop() + currentOpts.margin - ]; - }, - - _get_zoom_to = function () { - var view = _get_viewport(), - to = {}, - resize = currentOpts.autoScale, - double_padding = currentOpts.padding * 2, - ratio; - - if (currentOpts.width.toString().indexOf('%') > -1) { - to.width = parseInt((view[0] * parseFloat(currentOpts.width)) / 100, 10); - } else { - to.width = currentOpts.width + double_padding; - } - - if (currentOpts.height.toString().indexOf('%') > -1) { - to.height = parseInt((view[1] * parseFloat(currentOpts.height)) / 100, 10); - } else { - to.height = currentOpts.height + double_padding; - } - - if (resize && (to.width > view[0] || to.height > view[1])) { - if (selectedOpts.type == 'image' || selectedOpts.type == 'swf') { - ratio = (currentOpts.width ) / (currentOpts.height ); - - if ((to.width ) > view[0]) { - to.width = view[0]; - to.height = parseInt(((to.width - double_padding) / ratio) + double_padding, 10); - } - - if ((to.height) > view[1]) { - to.height = view[1]; - to.width = parseInt(((to.height - double_padding) * ratio) + double_padding, 10); - } - - } else { - to.width = Math.min(to.width, view[0]); - to.height = Math.min(to.height, view[1]); - } - } - - to.top = parseInt(Math.max(view[3] - 20, view[3] + ((view[1] - to.height - 40) * 0.5)), 10); - to.left = parseInt(Math.max(view[2] - 20, view[2] + ((view[0] - to.width - 40) * 0.5)), 10); - - return to; - }, - - _get_obj_pos = function(obj) { - var pos = obj.offset(); - - pos.top += parseInt( obj.css('paddingTop'), 10 ) || 0; - pos.left += parseInt( obj.css('paddingLeft'), 10 ) || 0; - - pos.top += parseInt( obj.css('border-top-width'), 10 ) || 0; - pos.left += parseInt( obj.css('border-left-width'), 10 ) || 0; - - pos.width = obj.width(); - pos.height = obj.height(); - - return pos; - }, - - _get_zoom_from = function() { - var orig = selectedOpts.orig ? $(selectedOpts.orig) : false, - from = {}, - pos, - view; - - if (orig && orig.length) { - pos = _get_obj_pos(orig); - - from = { - width : pos.width + (currentOpts.padding * 2), - height : pos.height + (currentOpts.padding * 2), - top : pos.top - currentOpts.padding - 20, - left : pos.left - currentOpts.padding - 20 - }; - - } else { - view = _get_viewport(); - - from = { - width : currentOpts.padding * 2, - height : currentOpts.padding * 2, - top : parseInt(view[3] + view[1] * 0.5, 10), - left : parseInt(view[2] + view[0] * 0.5, 10) - }; - } - - return from; - }, - - _animate_loading = function() { - if (!loading.is(':visible')){ - clearInterval(loadingTimer); - return; - } - - $('div', loading).css('top', (loadingFrame * -40) + 'px'); - - loadingFrame = (loadingFrame + 1) % 12; - }; - - /* - * Public methods - */ - - $.fn.fancybox = function(options) { - if (!$(this).length) { - return this; - } - - $(this) - .data('fancybox', $.extend({}, options, ($.metadata ? $(this).metadata() : {}))) - .unbind('click.fb') - .bind('click.fb', function(e) { - e.preventDefault(); - - if (busy) { - return; - } - - busy = true; - - $(this).blur(); - - selectedArray = []; - selectedIndex = 0; - - var rel = $(this).attr('rel') || ''; - - if (!rel || rel == '' || rel === 'nofollow') { - selectedArray.push(this); - - } else { - selectedArray = $("a[rel=" + rel + "], area[rel=" + rel + "]"); - selectedIndex = selectedArray.index( this ); - } - - _start(); - - return; - }); - - return this; - }; - - $.fancybox = function(obj) { - var opts; - - if (busy) { - return; - } - - busy = true; - opts = typeof arguments[1] !== 'undefined' ? arguments[1] : {}; - - selectedArray = []; - selectedIndex = parseInt(opts.index, 10) || 0; - - if ($.isArray(obj)) { - for (var i = 0, j = obj.length; i < j; i++) { - if (typeof obj[i] == 'object') { - $(obj[i]).data('fancybox', $.extend({}, opts, obj[i])); - } else { - obj[i] = $({}).data('fancybox', $.extend({content : obj[i]}, opts)); - } - } - - selectedArray = jQuery.merge(selectedArray, obj); - - } else { - if (typeof obj == 'object') { - $(obj).data('fancybox', $.extend({}, opts, obj)); - } else { - obj = $({}).data('fancybox', $.extend({content : obj}, opts)); - } - - selectedArray.push(obj); - } - - if (selectedIndex > selectedArray.length || selectedIndex < 0) { - selectedIndex = 0; - } - - _start(); - }; - - $.fancybox.showActivity = function() { - clearInterval(loadingTimer); - - loading.show(); - loadingTimer = setInterval(_animate_loading, 66); - }; - - $.fancybox.hideActivity = function() { - loading.hide(); - }; - - $.fancybox.next = function() { - return $.fancybox.pos( currentIndex + 1); - }; - - $.fancybox.prev = function() { - return $.fancybox.pos( currentIndex - 1); - }; - - $.fancybox.pos = function(pos) { - if (busy) { - return; - } - - pos = parseInt(pos); - - selectedArray = currentArray; - - if (pos > -1 && pos < currentArray.length) { - selectedIndex = pos; - _start(); - - } else if (currentOpts.cyclic && currentArray.length > 1) { - selectedIndex = pos >= currentArray.length ? 0 : currentArray.length - 1; - _start(); - } - - return; - }; - - $.fancybox.cancel = function() { - if (busy) { - return; - } - - busy = true; - - $.event.trigger('fancybox-cancel'); - - _abort(); - - selectedOpts.onCancel(selectedArray, selectedIndex, selectedOpts); - - busy = false; - }; - - // Note: within an iframe use - parent.$.fancybox.close(); - $.fancybox.close = function() { - if (busy || wrap.is(':hidden')) { - return; - } - - busy = true; - - if (currentOpts && false === currentOpts.onCleanup(currentArray, currentIndex, currentOpts)) { - busy = false; - return; - } - - _abort(); - - $(close.add( nav_left ).add( nav_right )).hide(); - - $(content.add( overlay )).unbind(); - - $(window).unbind("resize.fb scroll.fb"); - $(document).unbind('keydown.fb'); - - content.find('iframe').attr('src', isIE6 && /^https/i.test(window.location.href || '') ? 'javascript:void(false)' : 'about:blank'); - - if (currentOpts.titlePosition !== 'inside') { - title.empty(); - } - - wrap.stop(); - - function _cleanup() { - overlay.fadeOut('fast'); - - title.empty().hide(); - wrap.hide(); - - $.event.trigger('fancybox-cleanup'); - - content.empty(); - - currentOpts.onClosed(currentArray, currentIndex, currentOpts); - - currentArray = selectedOpts = []; - currentIndex = selectedIndex = 0; - currentOpts = selectedOpts = {}; - - busy = false; - } - - if (currentOpts.transitionOut == 'elastic') { - start_pos = _get_zoom_from(); - - var pos = wrap.position(); - - final_pos = { - top : pos.top , - left : pos.left, - width : wrap.width(), - height : wrap.height() - }; - - if (currentOpts.opacity) { - final_pos.opacity = 1; - } - - title.empty().hide(); - - fx.prop = 1; - - $(fx).animate({ prop: 0 }, { - duration : currentOpts.speedOut, - easing : currentOpts.easingOut, - step : _draw, - complete : _cleanup - }); - - } else { - wrap.fadeOut( currentOpts.transitionOut == 'none' ? 0 : currentOpts.speedOut, _cleanup); - } - }; - - $.fancybox.resize = function() { - if (overlay.is(':visible')) { - overlay.css('height', $(document).height()); - } - - $.fancybox.center(true); - }; - - $.fancybox.center = function() { - var view, align; - - if (busy) { - return; - } - - align = arguments[0] === true ? 1 : 0; - view = _get_viewport(); - - if (!align && (wrap.width() > view[0] || wrap.height() > view[1])) { - return; - } - - wrap - .stop() - .animate({ - 'top' : parseInt(Math.max(view[3] - 20, view[3] + ((view[1] - content.height() - 40) * 0.5) - currentOpts.padding)), - 'left' : parseInt(Math.max(view[2] - 20, view[2] + ((view[0] - content.width() - 40) * 0.5) - currentOpts.padding)) - }, typeof arguments[0] == 'number' ? arguments[0] : 200); - }; - - $.fancybox.init = function() { - if ($("#fancybox-wrap").length) { - return; - } - - $('body').append( - tmp = $('
                '), - loading = $('
                '), - overlay = $('
                '), - wrap = $('
                ') - ); - - outer = $('
                ') - .append('
                ') - .appendTo( wrap ); - - outer.append( - content = $('
                '), - close = $(''), - title = $('
                '), - - nav_left = $(''), - nav_right = $('') - ); - - close.click($.fancybox.close); - loading.click($.fancybox.cancel); - - nav_left.click(function(e) { - e.preventDefault(); - $.fancybox.prev(); - }); - - nav_right.click(function(e) { - e.preventDefault(); - $.fancybox.next(); - }); - - if ($.fn.mousewheel) { - wrap.bind('mousewheel.fb', function(e, delta) { - if (busy) { - e.preventDefault(); - - } else if ($(e.target).get(0).clientHeight == 0 || $(e.target).get(0).scrollHeight === $(e.target).get(0).clientHeight) { - e.preventDefault(); - $.fancybox[ delta > 0 ? 'prev' : 'next'](); - } - }); - } - - if (!$.support.opacity) { - wrap.addClass('fancybox-ie'); - } - - if (isIE6) { - loading.addClass('fancybox-ie6'); - wrap.addClass('fancybox-ie6'); - - $('').prependTo(outer); - } - }; - - $.fn.fancybox.defaults = { - padding : 10, - margin : 40, - opacity : false, - modal : false, - cyclic : false, - scrolling : 'auto', // 'auto', 'yes' or 'no' - - width : 560, - height : 340, - - autoScale : true, - autoDimensions : true, - centerOnScroll : false, - - ajax : {}, - swf : { wmode: 'transparent' }, - - hideOnOverlayClick : true, - hideOnContentClick : false, - - overlayShow : true, - overlayOpacity : 0.7, - overlayColor : '#777', - - titleShow : true, - titlePosition : 'float', // 'float', 'outside', 'inside' or 'over' - titleFormat : null, - titleFromAlt : false, - - transitionIn : 'fade', // 'elastic', 'fade' or 'none' - transitionOut : 'fade', // 'elastic', 'fade' or 'none' - - speedIn : 300, - speedOut : 300, - - changeSpeed : 300, - changeFade : 'fast', - - easingIn : 'swing', - easingOut : 'swing', - - showCloseButton : true, - showNavArrows : true, - enableEscapeButton : true, - enableKeyboardNav : true, - - onStart : function(){}, - onCancel : function(){}, - onComplete : function(){}, - onCleanup : function(){}, - onClosed : function(){}, - onError : function(){} - }; - - $(document).ready(function() { - $.fancybox.init(); - }); - -})(jQuery); \ No newline at end of file diff --git a/apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js b/apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js deleted file mode 100644 index e5ee2ae359..0000000000 --- a/apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js +++ /dev/null @@ -1 +0,0 @@ -(function(B){var L,T,Q,M,d,m,J,A,O,z,C=0,H={},j=[],e=0,G={},y=[],f=null,o=new Image(),i=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,k=/[^\.]\.(swf)\s*$/i,p,N=1,h=0,t="",b,c,P=false,s=B.extend(B("
                ")[0],{prop:0}),S=B.browser.msie&&B.browser.version<7&&!window.XMLHttpRequest,r=function(){T.hide();o.onerror=o.onload=null;if(f){f.abort()}L.empty()},x=function(){if(false===H.onError(j,C,H)){T.hide();P=false;return}H.titleShow=false;H.width="auto";H.height="auto";L.html('

                The requested content cannot be loaded.
                Please try again later.

                ');n()},w=function(){var Z=j[C],W,Y,ab,aa,V,X;r();H=B.extend({},B.fn.fancybox.defaults,(typeof B(Z).data("fancybox")=="undefined"?H:B(Z).data("fancybox")));X=H.onStart(j,C,H);if(X===false){P=false;return}else{if(typeof X=="object"){H=B.extend(H,X)}}ab=H.title||(Z.nodeName?B(Z).attr("title"):Z.title)||"";if(Z.nodeName&&!H.orig){H.orig=B(Z).children("img:first").length?B(Z).children("img:first"):B(Z)}if(ab===""&&H.orig&&H.titleFromAlt){ab=H.orig.attr("alt")}ab=ab.replace(//,">");W=H.href||(Z.nodeName?B(Z).attr("href"):Z.href)||null;if((/^(?:javascript)/i).test(W)||W=="#"){W=null}if(H.type){Y=H.type;if(!W){W=H.content}}else{if(H.content){Y="html"}else{if(W){if(W.match(i)){Y="image"}else{if(W.match(k)){Y="swf"}else{if(B(Z).hasClass("iframe")){Y="iframe"}else{if(W.indexOf("#")===0){Y="inline"}else{Y="ajax"}}}}}}}if(!Y){x();return}if(Y=="inline"){Z=W.substr(W.indexOf("#"));Y=B(Z).length>0?"inline":"ajax"}H.type=Y;H.href=W;H.title=ab;if(H.autoDimensions){if(H.type=="html"||H.type=="inline"||H.type=="ajax"){H.width="auto";H.height="auto"}else{H.autoDimensions=false}}if(H.modal){H.overlayShow=true;H.hideOnOverlayClick=false;H.hideOnContentClick=false;H.enableEscapeButton=false;H.showCloseButton=false}H.padding=parseInt(H.padding,10);H.margin=parseInt(H.margin,10);L.css("padding",(H.padding+H.margin));B(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){B(this).replaceWith(m.children())});switch(Y){case"html":L.html(H.content);n();break;case"inline":if(B(Z).parent().is("#fancybox-content")===true){P=false;return}B('
                ').hide().insertBefore(B(Z)).bind("fancybox-cleanup",function(){B(this).replaceWith(m.children())}).bind("fancybox-cancel",function(){B(this).replaceWith(L.children())});B(Z).appendTo(L);n();break;case"image":P=false;B.fancybox.showActivity();o=new Image();o.onerror=function(){x()};o.onload=function(){P=true;o.onerror=o.onload=null;F()};o.src=W;break;case"swf":H.scrolling="no";aa='';V="";B.each(H.swf,function(ac,ad){aa+='';V+=" "+ac+'="'+ad+'"'});aa+='";L.html(aa);n();break;case"ajax":P=false;B.fancybox.showActivity();H.ajax.win=H.ajax.success;f=B.ajax(B.extend({},H.ajax,{url:W,data:H.ajax.data||{},error:function(ac,ae,ad){if(ac.status>0){x()}},success:function(ad,af,ac){var ae=typeof ac=="object"?ac:f;if(ae.status==200){if(typeof H.ajax.win=="function"){X=H.ajax.win(W,ad,af,ac);if(X===false){T.hide();return}else{if(typeof X=="string"||typeof X=="object"){ad=X}}}L.html(ad);n()}}}));break;case"iframe":E();break}},n=function(){var V=H.width,W=H.height;if(V.toString().indexOf("%")>-1){V=parseInt((B(window).width()-(H.margin*2))*parseFloat(V)/100,10)+"px"}else{V=V=="auto"?"auto":V+"px"}if(W.toString().indexOf("%")>-1){W=parseInt((B(window).height()-(H.margin*2))*parseFloat(W)/100,10)+"px"}else{W=W=="auto"?"auto":W+"px"}L.wrapInner('
                ');H.width=L.width();H.height=L.height();E()},F=function(){H.width=o.width;H.height=o.height;B("").attr({id:"fancybox-img",src:o.src,alt:H.title}).appendTo(L);E()},E=function(){var W,V;T.hide();if(M.is(":visible")&&false===G.onCleanup(y,e,G)){B.event.trigger("fancybox-cancel");P=false;return}P=true;B(m.add(Q)).unbind();B(window).unbind("resize.fb scroll.fb");B(document).unbind("keydown.fb");if(M.is(":visible")&&G.titlePosition!=="outside"){M.css("height",M.height())}y=j;e=C;G=H;if(G.overlayShow){Q.css({"background-color":G.overlayColor,opacity:G.overlayOpacity,cursor:G.hideOnOverlayClick?"pointer":"auto",height:B(document).height()});if(!Q.is(":visible")){if(S){B("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"})}Q.show()}}else{Q.hide()}c=R();l();if(M.is(":visible")){B(J.add(O).add(z)).hide();W=M.position(),b={top:W.top,left:W.left,width:M.width(),height:M.height()};V=(b.width==c.width&&b.height==c.height);m.fadeTo(G.changeFade,0.3,function(){var X=function(){m.html(L.contents()).fadeTo(G.changeFade,1,v)};B.event.trigger("fancybox-change");m.empty().removeAttr("filter").css({"border-width":G.padding,width:c.width-G.padding*2,height:H.autoDimensions?"auto":c.height-h-G.padding*2});if(V){X()}else{s.prop=0;B(s).animate({prop:1},{duration:G.changeSpeed,easing:G.easingChange,step:U,complete:X})}});return}M.removeAttr("style");m.css("border-width",G.padding);if(G.transitionIn=="elastic"){b=I();m.html(L.contents());M.show();if(G.opacity){c.opacity=0}s.prop=0;B(s).animate({prop:1},{duration:G.speedIn,easing:G.easingIn,step:U,complete:v});return}if(G.titlePosition=="inside"&&h>0){A.show()}m.css({width:c.width-G.padding*2,height:H.autoDimensions?"auto":c.height-h-G.padding*2}).html(L.contents());M.css(c).fadeIn(G.transitionIn=="none"?0:G.speedIn,v)},D=function(V){if(V&&V.length){if(G.titlePosition=="float"){return'
                '+V+'
                '}return'
                '+V+"
                "}return false},l=function(){t=G.title||"";h=0;A.empty().removeAttr("style").removeClass();if(G.titleShow===false){A.hide();return}t=B.isFunction(G.titleFormat)?G.titleFormat(t,y,e,G):D(t);if(!t||t===""){A.hide();return}A.addClass("fancybox-title-"+G.titlePosition).html(t).appendTo("body").show();switch(G.titlePosition){case"inside":A.css({width:c.width-(G.padding*2),marginLeft:G.padding,marginRight:G.padding});h=A.outerHeight(true);A.appendTo(d);c.height+=h;break;case"over":A.css({marginLeft:G.padding,width:c.width-(G.padding*2),bottom:G.padding}).appendTo(d);break;case"float":A.css("left",parseInt((A.width()-c.width-40)/2,10)*-1).appendTo(M);break;default:A.css({width:c.width-(G.padding*2),paddingLeft:G.padding,paddingRight:G.padding}).appendTo(M);break}A.hide()},g=function(){if(G.enableEscapeButton||G.enableKeyboardNav){B(document).bind("keydown.fb",function(V){if(V.keyCode==27&&G.enableEscapeButton){V.preventDefault();B.fancybox.close()}else{if((V.keyCode==37||V.keyCode==39)&&G.enableKeyboardNav&&V.target.tagName!=="INPUT"&&V.target.tagName!=="TEXTAREA"&&V.target.tagName!=="SELECT"){V.preventDefault();B.fancybox[V.keyCode==37?"prev":"next"]()}}})}if(!G.showNavArrows){O.hide();z.hide();return}if((G.cyclic&&y.length>1)||e!==0){O.show()}if((G.cyclic&&y.length>1)||e!=(y.length-1)){z.show()}},v=function(){if(!B.support.opacity){m.get(0).style.removeAttribute("filter");M.get(0).style.removeAttribute("filter")}if(H.autoDimensions){m.css("height","auto")}M.css("height","auto");if(t&&t.length){A.show()}if(G.showCloseButton){J.show()}g();if(G.hideOnContentClick){m.bind("click",B.fancybox.close)}if(G.hideOnOverlayClick){Q.bind("click",B.fancybox.close)}B(window).bind("resize.fb",B.fancybox.resize);if(G.centerOnScroll){B(window).bind("scroll.fb",B.fancybox.center)}if(G.type=="iframe"){B('').appendTo(m)}M.show();P=false;B.fancybox.center();G.onComplete(y,e,G);K()},K=function(){var V,W;if((y.length-1)>e){V=y[e+1].href;if(typeof V!=="undefined"&&V.match(i)){W=new Image();W.src=V}}if(e>0){V=y[e-1].href;if(typeof V!=="undefined"&&V.match(i)){W=new Image();W.src=V}}},U=function(W){var V={width:parseInt(b.width+(c.width-b.width)*W,10),height:parseInt(b.height+(c.height-b.height)*W,10),top:parseInt(b.top+(c.top-b.top)*W,10),left:parseInt(b.left+(c.left-b.left)*W,10)};if(typeof c.opacity!=="undefined"){V.opacity=W<0.5?0.5:W}M.css(V);m.css({width:V.width-G.padding*2,height:V.height-(h*W)-G.padding*2})},u=function(){return[B(window).width()-(G.margin*2),B(window).height()-(G.margin*2),B(document).scrollLeft()+G.margin,B(document).scrollTop()+G.margin]},R=function(){var V=u(),Z={},W=G.autoScale,X=G.padding*2,Y;if(G.width.toString().indexOf("%")>-1){Z.width=parseInt((V[0]*parseFloat(G.width))/100,10)}else{Z.width=G.width+X}if(G.height.toString().indexOf("%")>-1){Z.height=parseInt((V[1]*parseFloat(G.height))/100,10)}else{Z.height=G.height+X}if(W&&(Z.width>V[0]||Z.height>V[1])){if(H.type=="image"||H.type=="swf"){Y=(G.width)/(G.height);if((Z.width)>V[0]){Z.width=V[0];Z.height=parseInt(((Z.width-X)/Y)+X,10)}if((Z.height)>V[1]){Z.height=V[1];Z.width=parseInt(((Z.height-X)*Y)+X,10)}}else{Z.width=Math.min(Z.width,V[0]);Z.height=Math.min(Z.height,V[1])}}Z.top=parseInt(Math.max(V[3]-20,V[3]+((V[1]-Z.height-40)*0.5)),10);Z.left=parseInt(Math.max(V[2]-20,V[2]+((V[0]-Z.width-40)*0.5)),10);return Z},q=function(V){var W=V.offset();W.top+=parseInt(V.css("paddingTop"),10)||0;W.left+=parseInt(V.css("paddingLeft"),10)||0;W.top+=parseInt(V.css("border-top-width"),10)||0;W.left+=parseInt(V.css("border-left-width"),10)||0;W.width=V.width();W.height=V.height();return W},I=function(){var Y=H.orig?B(H.orig):false,X={},W,V;if(Y&&Y.length){W=q(Y);X={width:W.width+(G.padding*2),height:W.height+(G.padding*2),top:W.top-G.padding-20,left:W.left-G.padding-20}}else{V=u();X={width:G.padding*2,height:G.padding*2,top:parseInt(V[3]+V[1]*0.5,10),left:parseInt(V[2]+V[0]*0.5,10)}}return X},a=function(){if(!T.is(":visible")){clearInterval(p);return}B("div",T).css("top",(N*-40)+"px");N=(N+1)%12};B.fn.fancybox=function(V){if(!B(this).length){return this}B(this).data("fancybox",B.extend({},V,(B.metadata?B(this).metadata():{}))).unbind("click.fb").bind("click.fb",function(X){X.preventDefault();if(P){return}P=true;B(this).blur();j=[];C=0;var W=B(this).attr("rel")||"";if(!W||W==""||W==="nofollow"){j.push(this)}else{j=B("a[rel="+W+"], area[rel="+W+"]");C=j.index(this)}w();return});return this};B.fancybox=function(Y){var X;if(P){return}P=true;X=typeof arguments[1]!=="undefined"?arguments[1]:{};j=[];C=parseInt(X.index,10)||0;if(B.isArray(Y)){for(var W=0,V=Y.length;Wj.length||C<0){C=0}w()};B.fancybox.showActivity=function(){clearInterval(p);T.show();p=setInterval(a,66)};B.fancybox.hideActivity=function(){T.hide()};B.fancybox.next=function(){return B.fancybox.pos(e+1)};B.fancybox.prev=function(){return B.fancybox.pos(e-1)};B.fancybox.pos=function(V){if(P){return}V=parseInt(V);j=y;if(V>-1&&V1){C=V>=y.length?0:y.length-1;w()}}return};B.fancybox.cancel=function(){if(P){return}P=true;B.event.trigger("fancybox-cancel");r();H.onCancel(j,C,H);P=false};B.fancybox.close=function(){if(P||M.is(":hidden")){return}P=true;if(G&&false===G.onCleanup(y,e,G)){P=false;return}r();B(J.add(O).add(z)).hide();B(m.add(Q)).unbind();B(window).unbind("resize.fb scroll.fb");B(document).unbind("keydown.fb");m.find("iframe").attr("src",S&&/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank");if(G.titlePosition!=="inside"){A.empty()}M.stop();function V(){Q.fadeOut("fast");A.empty().hide();M.hide();B.event.trigger("fancybox-cleanup");m.empty();G.onClosed(y,e,G);y=H=[];e=C=0;G=H={};P=false}if(G.transitionOut=="elastic"){b=I();var W=M.position();c={top:W.top,left:W.left,width:M.width(),height:M.height()};if(G.opacity){c.opacity=1}A.empty().hide();s.prop=1;B(s).animate({prop:0},{duration:G.speedOut,easing:G.easingOut,step:U,complete:V})}else{M.fadeOut(G.transitionOut=="none"?0:G.speedOut,V)}};B.fancybox.resize=function(){if(Q.is(":visible")){Q.css("height",B(document).height())}B.fancybox.center(true)};B.fancybox.center=function(){var V,W;if(P){return}W=arguments[0]===true?1:0;V=u();if(!W&&(M.width()>V[0]||M.height()>V[1])){return}M.stop().animate({top:parseInt(Math.max(V[3]-20,V[3]+((V[1]-m.height()-40)*0.5)-G.padding)),left:parseInt(Math.max(V[2]-20,V[2]+((V[0]-m.width()-40)*0.5)-G.padding))},typeof arguments[0]=="number"?arguments[0]:200)};B.fancybox.init=function(){if(B("#fancybox-wrap").length){return}B("body").append(L=B('
                '),T=B('
                '),Q=B('
                '),M=B('
                '));d=B('
                ').append('
                ').appendTo(M);d.append(m=B('
                '),J=B(''),A=B('
                '),O=B(''),z=B(''));J.click(B.fancybox.close);T.click(B.fancybox.cancel);O.click(function(V){V.preventDefault();B.fancybox.prev()});z.click(function(V){V.preventDefault();B.fancybox.next()});if(B.fn.mousewheel){M.bind("mousewheel.fb",function(V,W){if(P){V.preventDefault()}else{if(B(V.target).get(0).clientHeight==0||B(V.target).get(0).scrollHeight===B(V.target).get(0).clientHeight){V.preventDefault();B.fancybox[W>0?"prev":"next"]()}}})}if(!B.support.opacity){M.addClass("fancybox-ie")}if(S){T.addClass("fancybox-ie6");M.addClass("fancybox-ie6");B('').prependTo(d)}};B.fn.fancybox.defaults={padding:10,margin:40,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.7,overlayColor:"#777",titleShow:true,titlePosition:"float",titleFormat:null,titleFromAlt:false,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",easingIn:"swing",easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,enableKeyboardNav:true,onStart:function(){},onCancel:function(){},onComplete:function(){},onCleanup:function(){},onClosed:function(){},onError:function(){}};B(document).ready(function(){B.fancybox.init()})})(jQuery); \ No newline at end of file diff --git a/apps/files_imageviewer/js/jquery.mousewheel-3.0.4.js b/apps/files_imageviewer/js/jquery.mousewheel-3.0.4.js deleted file mode 100644 index b7932415ce..0000000000 --- a/apps/files_imageviewer/js/jquery.mousewheel-3.0.4.js +++ /dev/null @@ -1,78 +0,0 @@ -/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net) - * Licensed under the MIT License (LICENSE.txt). - * - * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. - * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. - * Thanks to: Seamus Leahy for adding deltaX and deltaY - * - * Version: 3.0.4 - * - * Requires: 1.2.2+ - */ - -(function($) { - -var types = ['DOMMouseScroll', 'mousewheel']; - -$.event.special.mousewheel = { - setup: function() { - if ( this.addEventListener ) { - for ( var i=types.length; i; ) { - this.addEventListener( types[--i], handler, false ); - } - } else { - this.onmousewheel = handler; - } - }, - - teardown: function() { - if ( this.removeEventListener ) { - for ( var i=types.length; i; ) { - this.removeEventListener( types[--i], handler, false ); - } - } else { - this.onmousewheel = null; - } - } -}; - -$.fn.extend({ - mousewheel: function(fn) { - return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); - }, - - unmousewheel: function(fn) { - return this.unbind("mousewheel", fn); - } -}); - - -function handler(event) { - var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; - event = $.event.fix(orgEvent); - event.type = "mousewheel"; - - // Old school scrollwheel delta - if ( event.wheelDelta ) { delta = event.wheelDelta/120; } - if ( event.detail ) { delta = -event.detail/3; } - - // New school multidimensional scroll (touchpads) deltas - deltaY = delta; - - // Gecko - if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { - deltaY = 0; - deltaX = -1*delta; - } - - // Webkit - if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } - if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } - - // Add event and delta to the front of the arguments - args.unshift(event, delta, deltaX, deltaY); - - return $.event.handle.apply(this, args); -} - -})(jQuery); \ No newline at end of file diff --git a/apps/files_imageviewer/js/jquery.mousewheel-3.0.4.pack.js b/apps/files_imageviewer/js/jquery.mousewheel-3.0.4.pack.js deleted file mode 100644 index cb66588e29..0000000000 --- a/apps/files_imageviewer/js/jquery.mousewheel-3.0.4.pack.js +++ /dev/null @@ -1,14 +0,0 @@ -/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net) -* Licensed under the MIT License (LICENSE.txt). -* -* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. -* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. -* Thanks to: Seamus Leahy for adding deltaX and deltaY -* -* Version: 3.0.4 -* -* Requires: 1.2.2+ -*/ - -(function(d){function g(a){var b=a||window.event,i=[].slice.call(arguments,1),c=0,h=0,e=0;a=d.event.fix(b);a.type="mousewheel";if(a.wheelDelta)c=a.wheelDelta/120;if(a.detail)c=-a.detail/3;e=c;if(b.axis!==undefined&&b.axis===b.HORIZONTAL_AXIS){e=0;h=-1*c}if(b.wheelDeltaY!==undefined)e=b.wheelDeltaY/120;if(b.wheelDeltaX!==undefined)h=-1*b.wheelDeltaX/120;i.unshift(a,c,h,e);return d.event.handle.apply(this,i)}var f=["DOMMouseScroll","mousewheel"];d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a= -f.length;a;)this.addEventListener(f[--a],g,false);else this.onmousewheel=g},teardown:function(){if(this.removeEventListener)for(var a=f.length;a;)this.removeEventListener(f[--a],g,false);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery); \ No newline at end of file diff --git a/apps/files_imageviewer/js/lightbox.js b/apps/files_imageviewer/js/lightbox.js deleted file mode 100644 index 31f08456d2..0000000000 --- a/apps/files_imageviewer/js/lightbox.js +++ /dev/null @@ -1,31 +0,0 @@ -$(document).ready(function() { - if(typeof FileActions!=='undefined'){ - FileActions.register('image','View','',function(filename){ - viewImage($('#dir').val(),filename); - }); - FileActions.setDefault('image','View'); - } - OC.search.customResults.Images=function(row,item){ - var image=item.link.substr(item.link.indexOf('?file=')+6); - var a=row.find('a'); - a.attr('href','#'); - a.click(function(){ - var pos=image.lastIndexOf('/') - var file=image.substr(pos + 1); - var dir=image.substr(0,pos); - viewImage(dir,file); - }); - } -}); - -function viewImage(dir, file) { - if(file.indexOf('.psd')>0){//can't view those - return; - } - var location=OC.filePath('files','ajax','download.php')+encodeURIComponent('?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir)); - $.fancybox({ - "href": location, - "title": file.replace(//, ">"), - "titlePosition": "inside" - }); -} diff --git a/apps/files_pdfviewer/appinfo/app.php b/apps/files_pdfviewer/appinfo/app.php deleted file mode 100644 index e4771ee517..0000000000 --- a/apps/files_pdfviewer/appinfo/app.php +++ /dev/null @@ -1,8 +0,0 @@ - - - files_pdfviewer - PDF Viewer - Inline PDF viewer (pdfjs-based) - GPL - Joan Creus, Thomas Müller - 4 - true - - diff --git a/apps/files_pdfviewer/appinfo/version b/apps/files_pdfviewer/appinfo/version deleted file mode 100644 index ceab6e11ec..0000000000 --- a/apps/files_pdfviewer/appinfo/version +++ /dev/null @@ -1 +0,0 @@ -0.1 \ No newline at end of file diff --git a/apps/files_pdfviewer/css/history.png b/apps/files_pdfviewer/css/history.png deleted file mode 100644 index afa0e4ab70fc83fcd35be727f6f64788beb3417d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 539 zcmV+$0_6RPP)Ll1*>oFc5~H8Hdj%L8z6s z2ysEx{(#jd9XGochMx$SG9N&wG zm|5`N6GEVzLkO4|X2xo@`gnbP{Rt42fM&CK@0|M)MSr$L1QDt7%LpM2%_7H~=snkJ)TC zJUuTR{kcTCE1a;c#HT-xJ3% zNs@4PcgJ8bz|3&YVPO;J_0+wFA^-rnB!MNxdHsxvbUAt)f9;Z@bEsuvNzTCH|v-Subx3r>K>XP=J1 d4#@vK_!}QH$$pNdlPmxL002ovPDHLkV1i+g_a*=U diff --git a/apps/files_pdfviewer/css/viewer.css b/apps/files_pdfviewer/css/viewer.css deleted file mode 100644 index f9ce929d8b..0000000000 --- a/apps/files_pdfviewer/css/viewer.css +++ /dev/null @@ -1,267 +0,0 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / -/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ - -#viewer { - font-family: 'Lucida Grande', 'Lucida Sans Unicode', Helvetica, Arial, Verdana, sans-serif; - /*margin: 0px;*/ - padding: 0px; - /*position:absolute;*/ -} - -[hidden] { - display: none; -} - -#controls2 > a > img { - margin: 4px; - height: 10px; -} - -#controls2 > button { - line-height: 10px; -} - -#controls2 > button > img { - width: 10px; - height: 10px; -} - -#controls2 > button[disabled] > img { - opacity: 0.5; -} - -#pageNumber { - text-align: right; -} - -span#info { - display: none; -} - -@-moz-document regexp("http:.*debug=1.*") { - span#info { - display: inline-block; - } -} - -/* === Sidebar === */ -#sidebar { - position: fixed; - width: 350px; - top: 62px; - bottom: 18px; - left: -290px; - transition: left 0.25s ease-in-out 1s; - -moz-transition: left 0.25s ease-in-out 1s; - -webkit-transition: left 0.25s ease-in-out 1s; - z-index: 1; -} - -#sidebar:hover { - left: 0px; - transition: left 0.25s ease-in-out 0s; - -moz-transition: left 0.25s ease-in-out 0s; - -webkit-transition: left 0.25s ease-in-out 0s; -} - -#sidebarBox { - background-color: rgba(0, 0, 0, 0.7); - width: 300px; - height: 100%; - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; - -moz-border-radius-topright: 8px; - -moz-border-radius-bottomright: 8px; - -webkit-border-top-right-radius: 8px; - -webkit-border-bottom-right-radius: 8px; - box-shadow: 0px 2px 8px #000; - -moz-box-shadow: 0px 2px 8px #000; - -webkit-box-shadow: 0px 2px 8px #000; -} - -#sidebarScrollView { - position: absolute; - overflow: hidden; - overflow-y: auto; - top: 10px; - bottom: 10px; - left: 10px; - width: 280px; -} - -.thumbnail { - width: 134px; - height: 134px; - margin-top: 5px; - margin-bottom: 5px; - margin-left:auto; - margin-right:auto; - line-height: 134px; - text-align: center; - overflow: hidden; -} - -.thumbnail:not([data-loaded]) { - background-color: gray; -} - -.thumbnail > canvas { - vertical-align: middle; - display: inline-block; -} - -#outlineScrollView { - position: absolute; - background-color: #fff; - overflow: auto; - top: 10px; - bottom: 10px; - left: 10px; - width: 280px; -} - -#outlineView { - padding-top: 4px; - padding-bottom: 100px; - padding-left: 6px; - padding-right: 6px; - font-size: smaller; -} - -.outlineItem > .outlineItems { - margin-left: 20px; -} - -.outlineItem > a { - text-decoration: none; - color: black; -} - -.outlineItem > a:hover { - background: #ff0; - box-shadow: 0px 2px 10px #ff0; -} - -#sidebarControls { - position:absolute; - width: 120px; - height: 32px; - left: 15px; - bottom: 35px; -} - -#sidebarControls > button { - box-shadow: 0px 4px 10px #000; - -moz-box-shadow: 0px 4px 10px #000; - -webkit-box-shadow: 0px 4px 10px #000; -} - -#sidebarControls > button > img { - width: 32px; - height: 32px; -} - -#sidebarControls > button[disabled] > img { - opacity: 0.5; -} - -#sidebarControls > button[data-selected] { - box-shadow: 0px 4px 10px #ff0; - -moz-box-shadow: 0px 4px 10px #ff0; - -webkit-box-shadow: 0px 4px 10px #ff0; -} - -/* === Content view === */ -canvas { - margin: auto; - display: block; -} - -.page { - width: 816px; - height: 1056px; - margin: 10px auto; - position: relative; - overflow: hidden; - box-shadow: 0px 4px 10px #000; - -moz-box-shadow: 0px 4px 10px #000; - -webkit-box-shadow: 0px 4px 10px #000; - background-color: white; -} - -.page > a { - display: block; - position: absolute; -} - -.page > a:hover { - opacity: 0.2; - background: #ff0; - box-shadow: 0px 2px 10px #ff0; - -moz-box-shadow: 0px 2px 10px #ff0; - -webkit-box-shadow: 0px 2px 10px #ff0; -} - -#viewer { - /*overflow:auto;*/ - margin: 6.3em 0 0 0; - margin-right:12.5em; - padding: 8px 0px; - position:static; - height:100%; - width:100%; - text-align:center; -} - -#sidebarView canvas:hover { - background: #ff0; - box-shadow: 0px 2px 10px #ff0; - -moz-box-shadow: 0px 2px 10px #ff0; - -webkit-box-shadow: 0px 2px 10px #ff0; -} - -#pageWidthOption { - border-top: 1px solid black; -} - -#customScaleOption { - display: none; -} - -/* === Printed media overrides === */ -@media print { - #sidebar { - display: none; - } - - #controls2 { - display: none; - } - - #viewer { - margin: 0; - padding: 0; - } - - .page { - display: none; - margin: 0; - } - - .page canvas { - box-shadow: none; - -moz-box-shadow: none; - -webkit-box-shadow: none; - } - - .page[data-loaded] { - display: block; - page-break-after: always; - } -} - -#loading { - margin: 100px 0; - text-align: center; -} - diff --git a/apps/files_pdfviewer/js/pdfjs/LICENSE b/apps/files_pdfviewer/js/pdfjs/LICENSE deleted file mode 100644 index f8a8482057..0000000000 --- a/apps/files_pdfviewer/js/pdfjs/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ - - Copyright (c) 2011 Mozilla Foundation - - Contributors: Andreas Gal - Chris G Jones - Shaon Barman - Vivien Nicolas <21@vingtetun.org> - Justin D'Arcangelo - Yury Delendik - Kalervo Kujala - Adil Allawi <@ironymark> - - 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/apps/files_pdfviewer/js/pdfjs/README b/apps/files_pdfviewer/js/pdfjs/README deleted file mode 100644 index ec6a1e1ab1..0000000000 --- a/apps/files_pdfviewer/js/pdfjs/README +++ /dev/null @@ -1,7 +0,0 @@ -Upstream (http://mozilla.github.com/pdf.js/) does not yet provide releases. -The latest version of git master can be taken from http://mozilla.github.com/pdf.js/build/pdf.js - -Please update pdf.js from time to time and test it! - - - diff --git a/apps/files_pdfviewer/js/pdfjs/build/pdf.js b/apps/files_pdfviewer/js/pdfjs/build/pdf.js deleted file mode 100644 index b1fc9d9747..0000000000 --- a/apps/files_pdfviewer/js/pdfjs/build/pdf.js +++ /dev/null @@ -1,33830 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -var PDFJS = {}; - -(function pdfjsWrapper() { - // Use strict in our context only - users might not want it - 'use strict'; - - PDFJS.build = '2aae4fd'; - - // Files are inserted below - see Makefile -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var globalScope = (typeof window === 'undefined') ? this : window; - -var isWorker = (typeof window == 'undefined'); - -var ERRORS = 0, WARNINGS = 1, INFOS = 5; -var verbosity = WARNINGS; - -// The global PDFJS object exposes the API -// In production, it will be declared outside a global wrapper -// In development, it will be declared here -if (!globalScope.PDFJS) { - globalScope.PDFJS = {}; -} - -// getPdf() -// Convenience function to perform binary Ajax GET -// Usage: getPdf('http://...', callback) -// getPdf({ -// url:String , -// [,progress:Function, error:Function] -// }, -// callback) -function getPdf(arg, callback) { - var params = arg; - if (typeof arg === 'string') - params = { url: arg }; - - var xhr = new XMLHttpRequest(); - - xhr.open('GET', params.url); - - var headers = params.headers; - if (headers) { - for (var property in headers) { - if (typeof headers[property] === 'undefined') - continue; - - xhr.setRequestHeader(property, params.headers[property]); - } - } - - xhr.mozResponseType = xhr.responseType = 'arraybuffer'; - var protocol = params.url.indexOf(':') < 0 ? window.location.protocol : - params.url.substring(0, params.url.indexOf(':') + 1); - xhr.expected = (protocol === 'http:' || protocol === 'https:') ? 200 : 0; - - if ('progress' in params) - xhr.onprogress = params.progress || undefined; - - if ('error' in params) - xhr.onerror = params.error || undefined; - - xhr.onreadystatechange = function getPdfOnreadystatechange(e) { - if (xhr.readyState === 4) { - if (xhr.status === xhr.expected) { - var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || - xhr.responseArrayBuffer || xhr.response); - callback(data); - } else if (params.error) { - params.error(e); - } - } - }; - xhr.send(null); -} -globalScope.PDFJS.getPdf = getPdf; -globalScope.PDFJS.pdfBug = false; - -var Page = (function PageClosure() { - function Page(xref, pageNumber, pageDict, ref) { - this.pageNumber = pageNumber; - this.pageDict = pageDict; - this.xref = xref; - this.ref = ref; - - this.displayReadyPromise = null; - } - - Page.prototype = { - getPageProp: function Page_getPageProp(key) { - return this.pageDict.get(key); - }, - inheritPageProp: function Page_inheritPageProp(key) { - var dict = this.pageDict; - var obj = dict.get(key); - while (obj === undefined) { - dict = dict.get('Parent'); - if (!dict) - break; - obj = dict.get(key); - } - return obj; - }, - get content() { - return shadow(this, 'content', this.getPageProp('Contents')); - }, - get resources() { - return shadow(this, 'resources', this.inheritPageProp('Resources')); - }, - get mediaBox() { - var obj = this.inheritPageProp('MediaBox'); - // Reset invalid media box to letter size. - if (!isArray(obj) || obj.length !== 4) - obj = [0, 0, 612, 792]; - return shadow(this, 'mediaBox', obj); - }, - get view() { - var mediaBox = this.mediaBox; - var cropBox = this.inheritPageProp('CropBox'); - if (!isArray(cropBox) || cropBox.length !== 4) - return shadow(this, 'view', mediaBox); - - // From the spec, 6th ed., p.963: - // "The crop, bleed, trim, and art boxes should not ordinarily - // extend beyond the boundaries of the media box. If they do, they are - // effectively reduced to their intersection with the media box." - cropBox = Util.intersect(cropBox, mediaBox); - if (!cropBox) - return shadow(this, 'view', mediaBox); - - return shadow(this, 'view', cropBox); - }, - get annotations() { - return shadow(this, 'annotations', this.inheritPageProp('Annots')); - }, - get rotate() { - var rotate = this.inheritPageProp('Rotate') || 0; - // Normalize rotation so it's a multiple of 90 and between 0 and 270 - if (rotate % 90 != 0) { - rotate = 0; - } else if (rotate >= 360) { - rotate = rotate % 360; - } else if (rotate < 0) { - // The spec doesn't cover negatives, assume its counterclockwise - // rotation. The following is the other implementation of modulo. - rotate = ((rotate % 360) + 360) % 360; - } - return shadow(this, 'rotate', rotate); - }, - - getOperatorList: function Page_getOperatorList(handler, dependency) { - var xref = this.xref; - var content = this.content; - var resources = this.resources; - if (isArray(content)) { - // fetching items - var streams = []; - var i, n = content.length; - var streams = []; - for (i = 0; i < n; ++i) - streams.push(xref.fetchIfRef(content[i])); - content = new StreamsSequenceStream(streams); - } else if (isStream(content)) { - content.reset(); - } else if (!content) { - // replacing non-existent page content with empty one - content = new Stream(new Uint8Array(0)); - } - - var pe = this.pe = new PartialEvaluator( - xref, handler, 'p' + this.pageNumber + '_'); - - return pe.getOperatorList(content, resources, dependency); - }, - extractTextContent: function Page_extractTextContent() { - var handler = { - on: function nullHandlerOn() {}, - send: function nullHandlerSend() {} - }; - - var xref = this.xref; - var content = xref.fetchIfRef(this.content); - var resources = xref.fetchIfRef(this.resources); - if (isArray(content)) { - // fetching items - var i, n = content.length; - var streams = []; - for (i = 0; i < n; ++i) - streams.push(xref.fetchIfRef(content[i])); - content = new StreamsSequenceStream(streams); - } else if (isStream(content)) { - content.reset(); - } - - var pe = new PartialEvaluator( - xref, handler, 'p' + this.pageNumber + '_'); - return pe.getTextContent(content, resources); - }, - - ensureFonts: function Page_ensureFonts(fonts, callback) { - this.stats.time('Font Loading'); - // Convert the font names to the corresponding font obj. - for (var i = 0, ii = fonts.length; i < ii; i++) { - fonts[i] = this.objs.objs[fonts[i]].data; - } - - // Load all the fonts - FontLoader.bind( - fonts, - function pageEnsureFontsFontObjs(fontObjs) { - this.stats.timeEnd('Font Loading'); - - callback.call(this); - }.bind(this) - ); - }, - getLinks: function Page_getLinks() { - var links = []; - var annotations = pageGetAnnotations(); - var i, n = annotations.length; - for (i = 0; i < n; ++i) { - if (annotations[i].type != 'Link') - continue; - links.push(annotations[i]); - } - return links; - }, - getAnnotations: function Page_getAnnotations() { - var xref = this.xref; - function getInheritableProperty(annotation, name) { - var item = annotation; - while (item && !item.has(name)) { - item = item.get('Parent'); - } - if (!item) - return null; - return item.get(name); - } - function isValidUrl(url) { - if (!url) - return false; - var colon = url.indexOf(':'); - if (colon < 0) - return false; - var protocol = url.substr(0, colon); - switch (protocol) { - case 'http': - case 'https': - case 'ftp': - case 'mailto': - return true; - default: - return false; - } - } - - var annotations = this.annotations || []; - var i, n = annotations.length; - var items = []; - for (i = 0; i < n; ++i) { - var annotationRef = annotations[i]; - var annotation = xref.fetch(annotationRef); - if (!isDict(annotation)) - continue; - var subtype = annotation.get('Subtype'); - if (!isName(subtype)) - continue; - var rect = annotation.get('Rect'); - - var item = {}; - item.type = subtype.name; - item.rect = rect; - switch (subtype.name) { - case 'Link': - var a = annotation.get('A'); - if (a) { - switch (a.get('S').name) { - case 'URI': - var url = a.get('URI'); - // TODO: pdf spec mentions urls can be relative to a Base - // entry in the dictionary. - if (!isValidUrl(url)) - url = ''; - item.url = url; - break; - case 'GoTo': - item.dest = a.get('D'); - break; - default: - TODO('other link types'); - } - } else if (annotation.has('Dest')) { - // simple destination link - var dest = annotation.get('Dest'); - item.dest = isName(dest) ? dest.name : dest; - } - break; - case 'Widget': - var fieldType = getInheritableProperty(annotation, 'FT'); - if (!isName(fieldType)) - break; - item.fieldType = fieldType.name; - // Building the full field name by collecting the field and - // its ancestors 'T' properties and joining them using '.'. - var fieldName = []; - var namedItem = annotation, ref = annotationRef; - while (namedItem) { - var parent = namedItem.get('Parent'); - var parentRef = namedItem.getRaw('Parent'); - var name = namedItem.get('T'); - if (name) { - fieldName.unshift(stringToPDFString(name)); - } else { - // The field name is absent, that means more than one field - // with the same name may exist. Replacing the empty name - // with the '`' plus index in the parent's 'Kids' array. - // This is not in the PDF spec but necessary to id the - // the input controls. - var kids = parent.get('Kids'); - var j, jj; - for (j = 0, jj = kids.length; j < jj; j++) { - var kidRef = kids[j]; - if (kidRef.num == ref.num && kidRef.gen == ref.gen) - break; - } - fieldName.unshift('`' + j); - } - namedItem = parent; - ref = parentRef; - } - item.fullName = fieldName.join('.'); - var alternativeText = stringToPDFString(annotation.get('TU') || ''); - item.alternativeText = alternativeText; - var da = getInheritableProperty(annotation, 'DA') || ''; - var m = /([\d\.]+)\sTf/.exec(da); - if (m) - item.fontSize = parseFloat(m[1]); - item.textAlignment = getInheritableProperty(annotation, 'Q'); - item.flags = getInheritableProperty(annotation, 'Ff') || 0; - break; - case 'Text': - var content = annotation.get('Contents'); - var title = annotation.get('T'); - item.content = stringToPDFString(content || ''); - item.title = stringToPDFString(title || ''); - item.name = !annotation.has('Name') ? 'Note' : - annotation.get('Name').name; - break; - default: - TODO('unimplemented annotation type: ' + subtype.name); - break; - } - items.push(item); - } - return items; - } - }; - - return Page; -})(); - -/** - * The `PDFDocument` holds all the data of the PDF file. Compared to the - * `PDFDoc`, this one doesn't have any job management code. - * Right now there exists one PDFDocument on the main thread + one object - * for each worker. If there is no worker support enabled, there are two - * `PDFDocument` objects on the main thread created. - */ -var PDFDocument = (function PDFDocumentClosure() { - function PDFDocument(arg, password) { - if (isStream(arg)) - init.call(this, arg, password); - else if (isArrayBuffer(arg)) - init.call(this, new Stream(arg), password); - else - error('PDFDocument: Unknown argument type'); - } - - function init(stream, password) { - assertWellFormed(stream.length > 0, 'stream must have data'); - this.stream = stream; - this.setup(password); - this.acroForm = this.catalog.catDict.get('AcroForm'); - } - - function find(stream, needle, limit, backwards) { - var pos = stream.pos; - var end = stream.end; - var str = ''; - if (pos + limit > end) - limit = end - pos; - for (var n = 0; n < limit; ++n) - str += stream.getChar(); - stream.pos = pos; - var index = backwards ? str.lastIndexOf(needle) : str.indexOf(needle); - if (index == -1) - return false; /* not found */ - stream.pos += index; - return true; /* found */ - } - - PDFDocument.prototype = { - get linearization() { - var length = this.stream.length; - var linearization = false; - if (length) { - linearization = new Linearization(this.stream); - if (linearization.length != length) - linearization = false; - } - // shadow the prototype getter with a data property - return shadow(this, 'linearization', linearization); - }, - get startXRef() { - var stream = this.stream; - var startXRef = 0; - var linearization = this.linearization; - if (linearization) { - // Find end of first obj. - stream.reset(); - if (find(stream, 'endobj', 1024)) - startXRef = stream.pos + 6; - } else { - // Find startxref by jumping backward from the end of the file. - var step = 1024; - var found = false, pos = stream.end; - while (!found && pos > 0) { - pos -= step - 'startxref'.length; - if (pos < 0) - pos = 0; - stream.pos = pos; - found = find(stream, 'startxref', step, true); - } - if (found) { - stream.skip(9); - var ch; - do { - ch = stream.getChar(); - } while (Lexer.isSpace(ch)); - var str = ''; - while ((ch - '0') <= 9) { - str += ch; - ch = stream.getChar(); - } - startXRef = parseInt(str, 10); - if (isNaN(startXRef)) - startXRef = 0; - } - } - // shadow the prototype getter with a data property - return shadow(this, 'startXRef', startXRef); - }, - get mainXRefEntriesOffset() { - var mainXRefEntriesOffset = 0; - var linearization = this.linearization; - if (linearization) - mainXRefEntriesOffset = linearization.mainXRefEntriesOffset; - // shadow the prototype getter with a data property - return shadow(this, 'mainXRefEntriesOffset', mainXRefEntriesOffset); - }, - // Find the header, remove leading garbage and setup the stream - // starting from the header. - checkHeader: function PDFDocument_checkHeader() { - var stream = this.stream; - stream.reset(); - if (find(stream, '%PDF-', 1024)) { - // Found the header, trim off any garbage before it. - stream.moveStart(); - return; - } - // May not be a PDF file, continue anyway. - }, - setup: function PDFDocument_setup(password) { - this.checkHeader(); - var xref = new XRef(this.stream, - this.startXRef, - this.mainXRefEntriesOffset, - password); - this.xref = xref; - this.catalog = new Catalog(xref); - }, - get numPages() { - var linearization = this.linearization; - var num = linearization ? linearization.numPages : this.catalog.numPages; - // shadow the prototype getter - return shadow(this, 'numPages', num); - }, - getDocumentInfo: function PDFDocument_getDocumentInfo() { - var info; - if (this.xref.trailer.has('Info')) { - var infoDict = this.xref.trailer.get('Info'); - - info = {}; - infoDict.forEach(function(key, value) { - info[key] = typeof value !== 'string' ? value : - stringToPDFString(value); - }); - } - - return shadow(this, 'getDocumentInfo', info); - }, - getFingerprint: function PDFDocument_getFingerprint() { - var xref = this.xref, fileID; - if (xref.trailer.has('ID')) { - fileID = ''; - var id = xref.trailer.get('ID')[0]; - id.split('').forEach(function(el) { - fileID += Number(el.charCodeAt(0)).toString(16); - }); - } else { - // If we got no fileID, then we generate one, - // from the first 100 bytes of PDF - var data = this.stream.bytes.subarray(0, 100); - var hash = calculateMD5(data, 0, data.length); - fileID = ''; - for (var i = 0, length = hash.length; i < length; i++) { - fileID += Number(hash[i]).toString(16); - } - } - - return shadow(this, 'getFingerprint', fileID); - }, - getPage: function PDFDocument_getPage(n) { - return this.catalog.getPage(n); - } - }; - - return PDFDocument; -})(); - - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -// Use only for debugging purposes. This should not be used in any code that is -// in mozilla master. -function log(msg) { - if (console && console.log) - console.log(msg); - else if (print) - print(msg); -} - -// A notice for devs that will not trigger the fallback UI. These are good -// for things that are helpful to devs, such as warning that Workers were -// disabled, which is important to devs but not end users. -function info(msg) { - if (verbosity >= INFOS) { - log('Info: ' + msg); - PDFJS.LogManager.notify('info', msg); - } -} - -// Non-fatal warnings that should trigger the fallback UI. -function warn(msg) { - if (verbosity >= WARNINGS) { - log('Warning: ' + msg); - PDFJS.LogManager.notify('warn', msg); - } -} - -// Fatal errors that should trigger the fallback UI and halt execution by -// throwing an exception. -function error(msg) { - log('Error: ' + msg); - log(backtrace()); - PDFJS.LogManager.notify('error', msg); - throw new Error(msg); -} - -// Missing features that should trigger the fallback UI. -function TODO(what) { - warn('TODO: ' + what); -} - -function backtrace() { - try { - throw new Error(); - } catch (e) { - return e.stack ? e.stack.split('\n').slice(2).join('\n') : ''; - } -} - -function assert(cond, msg) { - if (!cond) - error(msg); -} - -// In a well-formed PDF, |cond| holds. If it doesn't, subsequent -// behavior is undefined. -function assertWellFormed(cond, msg) { - if (!cond) - error(msg); -} - -var LogManager = PDFJS.LogManager = (function LogManagerClosure() { - var loggers = []; - return { - addLogger: function logManager_addLogger(logger) { - loggers.push(logger); - }, - notify: function(type, message) { - for (var i = 0, ii = loggers.length; i < ii; i++) { - var logger = loggers[i]; - if (logger[type]) - logger[type](message); - } - } - }; -})(); - -function shadow(obj, prop, value) { - Object.defineProperty(obj, prop, { value: value, - enumerable: true, - configurable: true, - writable: false }); - return value; -} - -var PasswordException = (function PasswordExceptionClosure() { - function PasswordException(msg, code) { - this.name = 'PasswordException'; - this.message = msg; - this.code = code; - } - - PasswordException.prototype = new Error(); - PasswordException.constructor = PasswordException; - - return PasswordException; -})(); - -function bytesToString(bytes) { - var str = ''; - var length = bytes.length; - for (var n = 0; n < length; ++n) - str += String.fromCharCode(bytes[n]); - return str; -} - -function stringToBytes(str) { - var length = str.length; - var bytes = new Uint8Array(length); - for (var n = 0; n < length; ++n) - bytes[n] = str.charCodeAt(n) & 0xFF; - return bytes; -} - -var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; - -var Util = PDFJS.Util = (function UtilClosure() { - function Util() {} - - Util.makeCssRgb = function Util_makeCssRgb(r, g, b) { - var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0; - return 'rgb(' + ri + ',' + gi + ',' + bi + ')'; - }; - - Util.makeCssCmyk = function Util_makeCssCmyk(c, m, y, k) { - c = (new DeviceCmykCS()).getRgb([c, m, y, k]); - var ri = (255 * c[0]) | 0, gi = (255 * c[1]) | 0, bi = (255 * c[2]) | 0; - return 'rgb(' + ri + ',' + gi + ',' + bi + ')'; - }; - - // For 2d affine transforms - Util.applyTransform = function Util_applyTransform(p, m) { - var xt = p[0] * m[0] + p[1] * m[2] + m[4]; - var yt = p[0] * m[1] + p[1] * m[3] + m[5]; - return [xt, yt]; - }; - - Util.applyInverseTransform = function Util_applyInverseTransform(p, m) { - var d = m[0] * m[3] - m[1] * m[2]; - var xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d; - var yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d; - return [xt, yt]; - }; - - Util.inverseTransform = function Util_inverseTransform(m) { - var d = m[0] * m[3] - m[1] * m[2]; - return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, - (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d]; - }; - - // Apply a generic 3d matrix M on a 3-vector v: - // | a b c | | X | - // | d e f | x | Y | - // | g h i | | Z | - // M is assumed to be serialized as [a,b,c,d,e,f,g,h,i], - // with v as [X,Y,Z] - Util.apply3dTransform = function Util_apply3dTransform(m, v) { - return [ - m[0] * v[0] + m[1] * v[1] + m[2] * v[2], - m[3] * v[0] + m[4] * v[1] + m[5] * v[2], - m[6] * v[0] + m[7] * v[1] + m[8] * v[2] - ]; - } - - // Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2) - // For coordinate systems whose origin lies in the bottom-left, this - // means normalization to (BL,TR) ordering. For systems with origin in the - // top-left, this means (TL,BR) ordering. - Util.normalizeRect = function Util_normalizeRect(rect) { - var r = rect.slice(0); // clone rect - if (rect[0] > rect[2]) { - r[0] = rect[2]; - r[2] = rect[0]; - } - if (rect[1] > rect[3]) { - r[1] = rect[3]; - r[3] = rect[1]; - } - return r; - } - - // Returns a rectangle [x1, y1, x2, y2] corresponding to the - // intersection of rect1 and rect2. If no intersection, returns 'false' - // The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2] - Util.intersect = function Util_intersect(rect1, rect2) { - function compare(a, b) { - return a - b; - }; - - // Order points along the axes - var orderedX = [rect1[0], rect1[2], rect2[0], rect2[2]].sort(compare), - orderedY = [rect1[1], rect1[3], rect2[1], rect2[3]].sort(compare), - result = []; - - rect1 = Util.normalizeRect(rect1); - rect2 = Util.normalizeRect(rect2); - - // X: first and second points belong to different rectangles? - if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) || - (orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) { - // Intersection must be between second and third points - result[0] = orderedX[1]; - result[2] = orderedX[2]; - } else { - return false; - } - - // Y: first and second points belong to different rectangles? - if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) || - (orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) { - // Intersection must be between second and third points - result[1] = orderedY[1]; - result[3] = orderedY[2]; - } else { - return false; - } - - return result; - }; - - Util.sign = function Util_sign(num) { - return num < 0 ? -1 : 1; - }; - - return Util; -})(); - -var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() { - function PageViewport(viewBox, scale, rotate, offsetX, offsetY) { - // creating transform to convert pdf coordinate system to the normal - // canvas like coordinates taking in account scale and rotation - var centerX = (viewBox[2] + viewBox[0]) / 2; - var centerY = (viewBox[3] + viewBox[1]) / 2; - var rotateA, rotateB, rotateC, rotateD; - switch (rotate) { - case -180: - case 180: - rotateA = -1; rotateB = 0; rotateC = 0; rotateD = 1; - break; - case -270: - case 90: - rotateA = 0; rotateB = 1; rotateC = 1; rotateD = 0; - break; - case -90: - case 270: - rotateA = 0; rotateB = -1; rotateC = -1; rotateD = 0; - break; - case 360: - case 0: - default: - rotateA = 1; rotateB = 0; rotateC = 0; rotateD = -1; - break; - } - var offsetCanvasX, offsetCanvasY; - var width, height; - if (rotateA == 0) { - offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX; - offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY; - width = Math.abs(viewBox[3] - viewBox[1]) * scale; - height = Math.abs(viewBox[2] - viewBox[0]) * scale; - } else { - offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX; - offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY; - width = Math.abs(viewBox[2] - viewBox[0]) * scale; - height = Math.abs(viewBox[3] - viewBox[1]) * scale; - } - // creating transform for the following operations: - // translate(-centerX, -centerY), rotate and flip vertically, - // scale, and translate(offsetCanvasX, offsetCanvasY) - this.transform = [ - rotateA * scale, - rotateB * scale, - rotateC * scale, - rotateD * scale, - offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, - offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY - ]; - - this.offsetX = offsetX; - this.offsetY = offsetY; - this.width = width; - this.height = height; - this.fontScale = scale; - } - PageViewport.prototype = { - convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) { - return Util.applyTransform([x, y], this.transform); - }, - convertToViewportRectangle: - function PageViewport_convertToViewportRectangle(rect) { - var tl = Util.applyTransform([rect[0], rect[1]], this.transform); - var br = Util.applyTransform([rect[2], rect[3]], this.transform); - return [tl[0], tl[1], br[0], br[1]]; - }, - convertToPdfPoint: function PageViewport_convertToPdfPoint(x, y) { - return Util.applyInverseTransform([x, y], this.transform); - } - }; - return PageViewport; -})(); - -var PDFStringTranslateTable = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 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, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, - 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C, - 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160, - 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC -]; - -function stringToPDFString(str) { - var i, n = str.length, str2 = ''; - if (str[0] === '\xFE' && str[1] === '\xFF') { - // UTF16BE BOM - for (i = 2; i < n; i += 2) - str2 += String.fromCharCode( - (str.charCodeAt(i) << 8) | str.charCodeAt(i + 1)); - } else { - for (i = 0; i < n; ++i) { - var code = PDFStringTranslateTable[str.charCodeAt(i)]; - str2 += code ? String.fromCharCode(code) : str.charAt(i); - } - } - return str2; -} - -function stringToUTF8String(str) { - return decodeURIComponent(escape(str)); -} - -function isBool(v) { - return typeof v == 'boolean'; -} - -function isInt(v) { - return typeof v == 'number' && ((v | 0) == v); -} - -function isNum(v) { - return typeof v == 'number'; -} - -function isString(v) { - return typeof v == 'string'; -} - -function isNull(v) { - return v === null; -} - -function isName(v) { - return v instanceof Name; -} - -function isCmd(v, cmd) { - return v instanceof Cmd && (!cmd || v.cmd == cmd); -} - -function isDict(v, type) { - return v instanceof Dict && (!type || v.get('Type').name == type); -} - -function isArray(v) { - return v instanceof Array; -} - -function isStream(v) { - return typeof v == 'object' && v != null && ('getChar' in v); -} - -function isArrayBuffer(v) { - return typeof v == 'object' && v != null && ('byteLength' in v); -} - -function isRef(v) { - return v instanceof Ref; -} - -function isPDFFunction(v) { - var fnDict; - if (typeof v != 'object') - return false; - else if (isDict(v)) - fnDict = v; - else if (isStream(v)) - fnDict = v.dict; - else - return false; - return fnDict.has('FunctionType'); -} - -/** - * 'Promise' object. - * Each object that is stored in PDFObjects is based on a Promise object that - * contains the status of the object and the data. There migth be situations, - * where a function want to use the value of an object, but it isn't ready at - * that time. To get a notification, once the object is ready to be used, s.o. - * can add a callback using the `then` method on the promise that then calls - * the callback once the object gets resolved. - * A promise can get resolved only once and only once the data of the promise - * can be set. If any of these happens twice or the data is required before - * it was set, an exception is throw. - */ -var Promise = PDFJS.Promise = (function PromiseClosure() { - var EMPTY_PROMISE = {}; - - /** - * If `data` is passed in this constructor, the promise is created resolved. - * If there isn't data, it isn't resolved at the beginning. - */ - function Promise(name, data) { - this.name = name; - this.isRejected = false; - this.error = null; - // If you build a promise and pass in some data it's already resolved. - if (data != null) { - this.isResolved = true; - this._data = data; - this.hasData = true; - } else { - this.isResolved = false; - this._data = EMPTY_PROMISE; - } - this.callbacks = []; - this.errbacks = []; - this.progressbacks = []; - }; - /** - * Builds a promise that is resolved when all the passed in promises are - * resolved. - * @param {Promise[]} promises Array of promises to wait for. - * @return {Promise} New dependant promise. - */ - Promise.all = function Promise_all(promises) { - var deferred = new Promise(); - var unresolved = promises.length; - var results = []; - if (unresolved === 0) { - deferred.resolve(results); - return deferred; - } - for (var i = 0, ii = promises.length; i < ii; ++i) { - var promise = promises[i]; - promise.then((function(i) { - return function(value) { - results[i] = value; - unresolved--; - if (unresolved === 0) - deferred.resolve(results); - }; - })(i)); - } - return deferred; - }; - Promise.prototype = { - hasData: false, - - set data(value) { - if (value === undefined) { - return; - } - if (this._data !== EMPTY_PROMISE) { - error('Promise ' + this.name + - ': Cannot set the data of a promise twice'); - } - this._data = value; - this.hasData = true; - - if (this.onDataCallback) { - this.onDataCallback(value); - } - }, - - get data() { - if (this._data === EMPTY_PROMISE) { - error('Promise ' + this.name + ': Cannot get data that isn\'t set'); - } - return this._data; - }, - - onData: function Promise_onData(callback) { - if (this._data !== EMPTY_PROMISE) { - callback(this._data); - } else { - this.onDataCallback = callback; - } - }, - - resolve: function Promise_resolve(data) { - if (this.isResolved) { - error('A Promise can be resolved only once ' + this.name); - } - if (this.isRejected) { - error('The Promise was already rejected ' + this.name); - } - - this.isResolved = true; - this.data = (typeof data !== 'undefined') ? data : null; - var callbacks = this.callbacks; - - for (var i = 0, ii = callbacks.length; i < ii; i++) { - callbacks[i].call(null, data); - } - }, - - progress: function Promise_progress(data) { - var callbacks = this.progressbacks; - for (var i = 0, ii = callbacks.length; i < ii; i++) { - callbacks[i].call(null, data); - } - }, - - reject: function Promise_reject(reason, exception) { - if (this.isRejected) { - error('A Promise can be rejected only once ' + this.name); - } - if (this.isResolved) { - error('The Promise was already resolved ' + this.name); - } - - this.isRejected = true; - this.error = reason || null; - var errbacks = this.errbacks; - - for (var i = 0, ii = errbacks.length; i < ii; i++) { - errbacks[i].call(null, reason, exception); - } - }, - - then: function Promise_then(callback, errback, progressback) { - if (!callback) { - error('Requiring callback' + this.name); - } - - // If the promise is already resolved, call the callback directly. - if (this.isResolved) { - var data = this.data; - callback.call(null, data); - } else if (this.isRejected && errback) { - var error = this.error; - errback.call(null, error); - } else { - this.callbacks.push(callback); - if (errback) - this.errbacks.push(errback); - } - - if (progressback) - this.progressbacks.push(progressback); - } - }; - - return Promise; -})(); - -var StatTimer = (function StatTimerClosure() { - function rpad(str, pad, length) { - while (str.length < length) - str += pad; - return str; - } - function StatTimer() { - this.started = {}; - this.times = []; - this.enabled = true; - } - StatTimer.prototype = { - time: function StatTimer_time(name) { - if (!this.enabled) - return; - if (name in this.started) - throw 'Timer is already running for ' + name; - this.started[name] = Date.now(); - }, - timeEnd: function StatTimer_timeEnd(name) { - if (!this.enabled) - return; - if (!(name in this.started)) - throw 'Timer has not been started for ' + name; - this.times.push({ - 'name': name, - 'start': this.started[name], - 'end': Date.now() - }); - // Remove timer from started so it can be called again. - delete this.started[name]; - }, - toString: function StatTimer_toString() { - var times = this.times; - var out = ''; - // Find the longest name for padding purposes. - var longest = 0; - for (var i = 0, ii = times.length; i < ii; ++i) { - var name = times[i]['name']; - if (name.length > longest) - longest = name.length; - } - for (var i = 0, ii = times.length; i < ii; ++i) { - var span = times[i]; - var duration = span.end - span.start; - out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n'; - } - return out; - } - }; - return StatTimer; -})(); - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -/** - * This is the main entry point for loading a PDF and interacting with it. - * NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR) - * is used, which means it must follow the same origin rules that any XHR does - * e.g. No cross domain requests without CORS. - * - * @param {string|TypedAray|object} source Can be an url to where a PDF is - * located, a typed array (Uint8Array) already populated with data or - * and parameter object with the following possible fields: - * - url - The URL of the PDF. - * - data - A typed array with PDF data. - * - httpHeaders - Basic authentication headers. - * - password - For decrypting password-protected PDFs. - * - * @return {Promise} A promise that is resolved with {PDFDocumentProxy} object. - */ -PDFJS.getDocument = function getDocument(source) { - var url, data, headers, password, parameters = {}; - if (typeof source === 'string') { - url = source; - } else if (isArrayBuffer(source)) { - data = source; - } else if (typeof source === 'object') { - url = source.url; - data = source.data; - headers = source.httpHeaders; - password = source.password; - parameters.password = password || null; - - if (!url && !data) - error('Invalid parameter array, need either .data or .url'); - } else { - error('Invalid parameter in getDocument, need either Uint8Array, ' + - 'string or a parameter object'); - } - - var promise = new PDFJS.Promise(); - var transport = new WorkerTransport(promise); - if (data) { - // assuming the data is array, instantiating directly from it - transport.sendData(data, parameters); - } else if (url) { - // fetch url - PDFJS.getPdf( - { - url: url, - progress: function getPDFProgress(evt) { - if (evt.lengthComputable) - promise.progress({ - loaded: evt.loaded, - total: evt.total - }); - }, - error: function getPDFError(e) { - promise.reject('Unexpected server response of ' + - e.target.status + '.'); - }, - headers: headers - }, - function getPDFLoad(data) { - transport.sendData(data, parameters); - }); - } - - return promise; -}; - -/** - * Proxy to a PDFDocument in the worker thread. Also, contains commonly used - * properties that can be read synchronously. - */ -var PDFDocumentProxy = (function PDFDocumentProxyClosure() { - function PDFDocumentProxy(pdfInfo, transport) { - this.pdfInfo = pdfInfo; - this.transport = transport; - } - PDFDocumentProxy.prototype = { - /** - * @return {number} Total number of pages the PDF contains. - */ - get numPages() { - return this.pdfInfo.numPages; - }, - /** - * @return {string} A unique ID to identify a PDF. Not guaranteed to be - * unique. - */ - get fingerprint() { - return this.pdfInfo.fingerprint; - }, - /** - * @param {number} The page number to get. The first page is 1. - * @return {Promise} A promise that is resolved with a {PDFPageProxy} - * object. - */ - getPage: function PDFDocumentProxy_getPage(number) { - return this.transport.getPage(number); - }, - /** - * @return {Promise} A promise that is resolved with a lookup table for - * mapping named destinations to reference numbers. - */ - getDestinations: function PDFDocumentProxy_getDestinations() { - var promise = new PDFJS.Promise(); - var destinations = this.pdfInfo.destinations; - promise.resolve(destinations); - return promise; - }, - /** - * @return {Promise} A promise that is resolved with an {array} that is a - * tree outline (if it has one) of the PDF. The tree is in the format of: - * [ - * { - * title: string, - * bold: boolean, - * italic: boolean, - * color: rgb array, - * dest: dest obj, - * items: array of more items like this - * }, - * ... - * ]. - */ - getOutline: function PDFDocumentProxy_getOutline() { - var promise = new PDFJS.Promise(); - var outline = this.pdfInfo.outline; - promise.resolve(outline); - return promise; - }, - /** - * @return {Promise} A promise that is resolved with an {object} that has - * info and metadata properties. Info is an {object} filled with anything - * available in the information dictionary and similarly metadata is a - * {Metadata} object with information from the metadata section of the PDF. - */ - getMetadata: function PDFDocumentProxy_getMetadata() { - var promise = new PDFJS.Promise(); - var info = this.pdfInfo.info; - var metadata = this.pdfInfo.metadata; - promise.resolve({ - info: info, - metadata: metadata ? new PDFJS.Metadata(metadata) : null - }); - return promise; - }, - isEncrypted: function PDFDocumentProxy_isEncrypted() { - var promise = new PDFJS.Promise(); - promise.resolve(this.pdfInfo.encrypted); - return promise; - }, - /** - * @return {Promise} A promise that is resolved with a TypedArray that has - * the raw data from the PDF. - */ - getData: function PDFDocumentProxy_getData() { - var promise = new PDFJS.Promise(); - this.transport.getData(promise); - return promise; - }, - destroy: function PDFDocumentProxy_destroy() { - this.transport.destroy(); - } - }; - return PDFDocumentProxy; -})(); - -var PDFPageProxy = (function PDFPageProxyClosure() { - function PDFPageProxy(pageInfo, transport) { - this.pageInfo = pageInfo; - this.transport = transport; - this.stats = new StatTimer(); - this.stats.enabled = !!globalScope.PDFJS.enableStats; - this.objs = transport.objs; - this.renderInProgress = false; - } - PDFPageProxy.prototype = { - /** - * @return {number} Page number of the page. First page is 1. - */ - get pageNumber() { - return this.pageInfo.pageIndex + 1; - }, - /** - * @return {number} The number of degrees the page is rotated clockwise. - */ - get rotate() { - return this.pageInfo.rotate; - }, - /** - * @return {object} The reference that points to this page. It has 'num' and - * 'gen' properties. - */ - get ref() { - return this.pageInfo.ref; - }, - /** - * @return {array} An array of the visible portion of the PDF page in the - * user space units - [x1, y1, x2, y2]. - */ - get view() { - return this.pageInfo.view; - }, - /** - * @param {number} scale The desired scale of the viewport. - * @param {number} rotate Degrees to rotate the viewport. If omitted this - * defaults to the page rotation. - * @return {PageViewport} Contains 'width' and 'height' properties along - * with transforms required for rendering. - */ - getViewport: function PDFPageProxy_getViewport(scale, rotate) { - if (arguments.length < 2) - rotate = this.rotate; - return new PDFJS.PageViewport(this.view, scale, rotate, 0, 0); - }, - /** - * @return {Promise} A promise that is resolved with an {array} of the - * annotation objects. - */ - getAnnotations: function PDFPageProxy_getAnnotations() { - if (this.annotationsPromise) - return this.annotationsPromise; - - var promise = new PDFJS.Promise(); - this.annotationsPromise = promise; - this.transport.getAnnotations(this.pageInfo.pageIndex); - return promise; - }, - /** - * Begins the process of rendering a page to the desired context. - * @param {object} params A parameter object that supports: - * { - * canvasContext(required): A 2D context of a DOM Canvas object., - * textLayer(optional): An object that has beginLayout, endLayout, and - * appendText functions. - * }. - * @return {Promise} A promise that is resolved when the page finishes - * rendering. - */ - render: function PDFPageProxy_render(params) { - this.renderInProgress = true; - - var promise = new Promise(); - var stats = this.stats; - stats.time('Overall'); - // If there is no displayReadyPromise yet, then the operatorList was never - // requested before. Make the request and create the promise. - if (!this.displayReadyPromise) { - this.displayReadyPromise = new Promise(); - this.destroyed = false; - - this.stats.time('Page Request'); - this.transport.messageHandler.send('RenderPageRequest', { - pageIndex: this.pageNumber - 1 - }); - } - - var self = this; - function complete(error) { - self.renderInProgress = false; - if (self.destroyed) { - delete self.operatorList; - delete self.displayReadyPromise; - } - - if (error) - promise.reject(error); - else - promise.resolve(); - }; - - // Once the operatorList and fonts are loaded, do the actual rendering. - this.displayReadyPromise.then( - function pageDisplayReadyPromise() { - if (self.destroyed) { - complete(); - return; - } - - var gfx = new CanvasGraphics(params.canvasContext, - this.objs, params.textLayer); - try { - this.display(gfx, params.viewport, complete); - } catch (e) { - complete(e); - } - }.bind(this), - function pageDisplayReadPromiseError(reason) { - complete(reason); - } - ); - - return promise; - }, - /** - * For internal use only. - */ - startRenderingFromOperatorList: - function PDFPageProxy_startRenderingFromOperatorList(operatorList, - fonts) { - var self = this; - this.operatorList = operatorList; - - var displayContinuation = function pageDisplayContinuation() { - // Always defer call to display() to work around bug in - // Firefox error reporting from XHR callbacks. - setTimeout(function pageSetTimeout() { - self.displayReadyPromise.resolve(); - }); - }; - - this.ensureFonts(fonts, - function pageStartRenderingFromOperatorListEnsureFonts() { - displayContinuation(); - } - ); - }, - /** - * For internal use only. - */ - ensureFonts: function PDFPageProxy_ensureFonts(fonts, callback) { - this.stats.time('Font Loading'); - // Convert the font names to the corresponding font obj. - for (var i = 0, ii = fonts.length; i < ii; i++) { - fonts[i] = this.objs.objs[fonts[i]].data; - } - - // Load all the fonts - FontLoader.bind( - fonts, - function pageEnsureFontsFontObjs(fontObjs) { - this.stats.timeEnd('Font Loading'); - - callback.call(this); - }.bind(this) - ); - }, - /** - * For internal use only. - */ - display: function PDFPageProxy_display(gfx, viewport, callback) { - var stats = this.stats; - stats.time('Rendering'); - - gfx.beginDrawing(viewport); - - var startIdx = 0; - var length = this.operatorList.fnArray.length; - var operatorList = this.operatorList; - var stepper = null; - if (PDFJS.pdfBug && StepperManager.enabled) { - stepper = StepperManager.create(this.pageNumber - 1); - stepper.init(operatorList); - stepper.nextBreakPoint = stepper.getNextBreakPoint(); - } - - var self = this; - function next() { - startIdx = - gfx.executeOperatorList(operatorList, startIdx, next, stepper); - if (startIdx == length) { - gfx.endDrawing(); - stats.timeEnd('Rendering'); - stats.timeEnd('Overall'); - if (callback) callback(); - } - } - next(); - }, - /** - * @return {Promise} That is resolved with the a {string} that is the text - * content from the page. - */ - getTextContent: function PDFPageProxy_getTextContent() { - var promise = new PDFJS.Promise(); - this.transport.messageHandler.send('GetTextContent', { - pageIndex: this.pageNumber - 1 - }, - function textContentCallback(textContent) { - promise.resolve(textContent); - } - ); - return promise; - }, - /** - * Stub for future feature. - */ - getOperationList: function PDFPageProxy_getOperationList() { - var promise = new PDFJS.Promise(); - var operationList = { // not implemented - dependencyFontsID: null, - operatorList: null - }; - promise.resolve(operationList); - return promise; - }, - /** - * Destroys resources allocated by the page. - */ - destroy: function PDFPageProxy_destroy() { - this.destroyed = true; - - if (!this.renderInProgress) { - delete this.operatorList; - delete this.displayReadyPromise; - } - } - }; - return PDFPageProxy; -})(); -/** - * For internal use only. - */ -var WorkerTransport = (function WorkerTransportClosure() { - function WorkerTransport(promise) { - this.workerReadyPromise = promise; - this.objs = new PDFObjects(); - - this.pageCache = []; - this.pagePromises = []; - this.fontsLoading = {}; - - // If worker support isn't disabled explicit and the browser has worker - // support, create a new web worker and test if it/the browser fullfills - // all requirements to run parts of pdf.js in a web worker. - // Right now, the requirement is, that an Uint8Array is still an Uint8Array - // as it arrives on the worker. Chrome added this with version 15. - if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') { - var workerSrc = PDFJS.workerSrc; - if (typeof workerSrc === 'undefined') { - error('No PDFJS.workerSrc specified'); - } - - try { - var worker; - if (PDFJS.isFirefoxExtension) { - // The firefox extension can't load the worker from the resource:// - // url so we have to inline the script and then use the blob loader. - var bb = new MozBlobBuilder(); - bb.append(document.querySelector('#PDFJS_SCRIPT_TAG').textContent); - var blobUrl = window.URL.createObjectURL(bb.getBlob()); - worker = new Worker(blobUrl); - } else { - // Some versions of FF can't create a worker on localhost, see: - // https://bugzilla.mozilla.org/show_bug.cgi?id=683280 - worker = new Worker(workerSrc); - } - - var messageHandler = new MessageHandler('main', worker); - this.messageHandler = messageHandler; - - messageHandler.on('test', function transportTest(supportTypedArray) { - if (supportTypedArray) { - this.worker = worker; - this.setupMessageHandler(messageHandler); - } else { - globalScope.PDFJS.disableWorker = true; - this.setupFakeWorker(); - } - }.bind(this)); - - var testObj = new Uint8Array(1); - // Some versions of Opera throw a DATA_CLONE_ERR on - // serializing the typed array. - messageHandler.send('test', testObj); - return; - } catch (e) { - info('The worker has been disabled.'); - } - } - // Either workers are disabled, not supported or have thrown an exception. - // Thus, we fallback to a faked worker. - globalScope.PDFJS.disableWorker = true; - this.setupFakeWorker(); - } - WorkerTransport.prototype = { - destroy: function WorkerTransport_destroy() { - if (this.worker) - this.worker.terminate(); - - this.pageCache = []; - this.pagePromises = []; - }, - setupFakeWorker: function WorkerTransport_setupFakeWorker() { - // If we don't use a worker, just post/sendMessage to the main thread. - var fakeWorker = { - postMessage: function WorkerTransport_postMessage(obj) { - fakeWorker.onmessage({data: obj}); - }, - terminate: function WorkerTransport_terminate() {} - }; - - var messageHandler = new MessageHandler('main', fakeWorker); - this.setupMessageHandler(messageHandler); - - // If the main thread is our worker, setup the handling for the messages - // the main thread sends to it self. - WorkerMessageHandler.setup(messageHandler); - }, - - setupMessageHandler: - function WorkerTransport_setupMessageHandler(messageHandler) { - this.messageHandler = messageHandler; - - messageHandler.on('GetDoc', function transportDoc(data) { - var pdfInfo = data.pdfInfo; - var pdfDocument = new PDFDocumentProxy(pdfInfo, this); - this.pdfDocument = pdfDocument; - this.workerReadyPromise.resolve(pdfDocument); - }, this); - - messageHandler.on('NeedPassword', function transportPassword(data) { - this.workerReadyPromise.reject(data.exception.message, data.exception); - }, this); - - messageHandler.on('IncorrectPassword', function transportBadPass(data) { - this.workerReadyPromise.reject(data.exception.message, data.exception); - }, this); - - messageHandler.on('GetPage', function transportPage(data) { - var pageInfo = data.pageInfo; - var page = new PDFPageProxy(pageInfo, this); - this.pageCache[pageInfo.pageIndex] = page; - var promise = this.pagePromises[pageInfo.pageIndex]; - promise.resolve(page); - }, this); - - messageHandler.on('GetAnnotations', function transportAnnotations(data) { - var annotations = data.annotations; - var promise = this.pageCache[data.pageIndex].annotationsPromise; - promise.resolve(annotations); - }, this); - - messageHandler.on('RenderPage', function transportRender(data) { - var page = this.pageCache[data.pageIndex]; - var depFonts = data.depFonts; - - page.stats.timeEnd('Page Request'); - page.startRenderingFromOperatorList(data.operatorList, depFonts); - }, this); - - messageHandler.on('obj', function transportObj(data) { - var id = data[0]; - var type = data[1]; - if (this.objs.hasData(id)) - return; - - switch (type) { - case 'JpegStream': - var imageData = data[2]; - loadJpegStream(id, imageData, this.objs); - break; - case 'Image': - var imageData = data[2]; - this.objs.resolve(id, imageData); - break; - case 'Font': - var name = data[2]; - var file = data[3]; - var properties = data[4]; - - if (file) { - // Rewrap the ArrayBuffer in a stream. - var fontFileDict = new Dict(); - file = new Stream(file, 0, file.length, fontFileDict); - } - - // At this point, only the font object is created but the font is - // not yet attached to the DOM. This is done in `FontLoader.bind`. - var font = new Font(name, file, properties); - this.objs.resolve(id, font); - break; - default: - error('Got unkown object type ' + type); - } - }, this); - - messageHandler.on('PageError', function transportError(data) { - var page = this.pageCache[data.pageNum - 1]; - if (page.displayReadyPromise) - page.displayReadyPromise.reject(data.error); - else - error(data.error); - }, this); - - messageHandler.on('JpegDecode', function(data, promise) { - var imageData = data[0]; - var components = data[1]; - if (components != 3 && components != 1) - error('Only 3 component or 1 component can be returned'); - - var img = new Image(); - img.onload = (function messageHandler_onloadClosure() { - var width = img.width; - var height = img.height; - var size = width * height; - var rgbaLength = size * 4; - var buf = new Uint8Array(size * components); - var tmpCanvas = createScratchCanvas(width, height); - var tmpCtx = tmpCanvas.getContext('2d'); - tmpCtx.drawImage(img, 0, 0); - var data = tmpCtx.getImageData(0, 0, width, height).data; - - if (components == 3) { - for (var i = 0, j = 0; i < rgbaLength; i += 4, j += 3) { - buf[j] = data[i]; - buf[j + 1] = data[i + 1]; - buf[j + 2] = data[i + 2]; - } - } else if (components == 1) { - for (var i = 0, j = 0; i < rgbaLength; i += 4, j++) { - buf[j] = data[i]; - } - } - promise.resolve({ data: buf, width: width, height: height}); - }).bind(this); - var src = 'data:image/jpeg;base64,' + window.btoa(imageData); - img.src = src; - }); - }, - - sendData: function WorkerTransport_sendData(data, params) { - this.messageHandler.send('GetDocRequest', {data: data, params: params}); - }, - - getData: function WorkerTransport_sendData(promise) { - this.messageHandler.send('GetData', null, function(data) { - promise.resolve(data); - }); - }, - - getPage: function WorkerTransport_getPage(pageNumber, promise) { - var pageIndex = pageNumber - 1; - if (pageIndex in this.pagePromises) - return this.pagePromises[pageIndex]; - var promise = new PDFJS.Promise('Page ' + pageNumber); - this.pagePromises[pageIndex] = promise; - this.messageHandler.send('GetPageRequest', { pageIndex: pageIndex }); - return promise; - }, - - getAnnotations: function WorkerTransport_getAnnotations(pageIndex) { - this.messageHandler.send('GetAnnotationsRequest', - { pageIndex: pageIndex }); - } - }; - return WorkerTransport; - -})(); - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -// contexts store most of the state we need natively. -// However, PDF needs a bit more state, which we store here. - -var TextRenderingMode = { - FILL: 0, - STROKE: 1, - FILL_STROKE: 2, - INVISIBLE: 3, - FILL_ADD_TO_PATH: 4, - STROKE_ADD_TO_PATH: 5, - FILL_STROKE_ADD_TO_PATH: 6, - ADD_TO_PATH: 7 -}; - -// Minimal font size that would be used during canvas fillText operations. -var MIN_FONT_SIZE = 1; - -function createScratchCanvas(width, height) { - var canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - return canvas; -} - -function addContextCurrentTransform(ctx) { - // If the context doesn't expose a `mozCurrentTransform`, add a JS based on. - if (!ctx.mozCurrentTransform) { - // Store the original context - ctx._originalSave = ctx.save; - ctx._originalRestore = ctx.restore; - ctx._originalRotate = ctx.rotate; - ctx._originalScale = ctx.scale; - ctx._originalTranslate = ctx.translate; - ctx._originalTransform = ctx.transform; - - ctx._transformMatrix = [1, 0, 0, 1, 0, 0]; - ctx._transformStack = []; - - Object.defineProperty(ctx, 'mozCurrentTransform', { - get: function getCurrentTransform() { - return this._transformMatrix; - } - }); - - Object.defineProperty(ctx, 'mozCurrentTransformInverse', { - get: function getCurrentTransformInverse() { - // Calculation done using WolframAlpha: - // http://www.wolframalpha.com/input/? - // i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}} - - var m = this._transformMatrix; - var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5]; - - var ad_bc = a * d - b * c; - var bc_ad = b * c - a * d; - - return [ - d / ad_bc, - b / bc_ad, - c / bc_ad, - a / ad_bc, - (d * e - c * f) / bc_ad, - (b * e - a * f) / ad_bc - ]; - } - }); - - ctx.save = function ctxSave() { - var old = this._transformMatrix; - this._transformStack.push(old); - this._transformMatrix = old.slice(0, 6); - - this._originalSave(); - }; - - ctx.restore = function ctxRestore() { - var prev = this._transformStack.pop(); - if (prev) { - this._transformMatrix = prev; - this._originalRestore(); - } - }; - - ctx.translate = function ctxTranslate(x, y) { - var m = this._transformMatrix; - m[4] = m[0] * x + m[2] * y + m[4]; - m[5] = m[1] * x + m[3] * y + m[5]; - - this._originalTranslate(x, y); - }; - - ctx.scale = function ctxScale(x, y) { - var m = this._transformMatrix; - m[0] = m[0] * x; - m[1] = m[1] * x; - m[2] = m[2] * y; - m[3] = m[3] * y; - - this._originalScale(x, y); - }; - - ctx.transform = function ctxTransform(a, b, c, d, e, f) { - var m = this._transformMatrix; - this._transformMatrix = [ - m[0] * a + m[2] * b, - m[1] * a + m[3] * b, - m[0] * c + m[2] * d, - m[1] * c + m[3] * d, - m[0] * e + m[2] * f + m[4], - m[1] * e + m[3] * f + m[5] - ]; - - ctx._originalTransform(a, b, c, d, e, f); - }; - - ctx.rotate = function ctxRotate(angle) { - var cosValue = Math.cos(angle); - var sinValue = Math.sin(angle); - - var m = this._transformMatrix; - this._transformMatrix = [ - m[0] * cosValue + m[2] * sinValue, - m[1] * cosValue + m[3] * sinValue, - m[0] * (-sinValue) + m[2] * cosValue, - m[1] * (-sinValue) + m[3] * cosValue, - m[4], - m[5] - ]; - - this._originalRotate(angle); - }; - } -} - -var CanvasExtraState = (function CanvasExtraStateClosure() { - function CanvasExtraState(old) { - // Are soft masks and alpha values shapes or opacities? - this.alphaIsShape = false; - this.fontSize = 0; - this.fontSizeScale = 1; - this.textMatrix = IDENTITY_MATRIX; - this.fontMatrix = IDENTITY_MATRIX; - this.leading = 0; - // Current point (in user coordinates) - this.x = 0; - this.y = 0; - // Start of text line (in text coordinates) - this.lineX = 0; - this.lineY = 0; - // Character and word spacing - this.charSpacing = 0; - this.wordSpacing = 0; - this.textHScale = 1; - this.textRenderingMode = TextRenderingMode.FILL; - // Color spaces - this.fillColorSpace = new DeviceGrayCS(); - this.fillColorSpaceObj = null; - this.strokeColorSpace = new DeviceGrayCS(); - this.strokeColorSpaceObj = null; - this.fillColorObj = null; - this.strokeColorObj = null; - // Default fore and background colors - this.fillColor = '#000000'; - this.strokeColor = '#000000'; - // Note: fill alpha applies to all non-stroking operations - this.fillAlpha = 1; - this.strokeAlpha = 1; - this.lineWidth = 1; - - this.old = old; - } - - CanvasExtraState.prototype = { - clone: function CanvasExtraState_clone() { - return Object.create(this); - }, - setCurrentPoint: function CanvasExtraState_setCurrentPoint(x, y) { - this.x = x; - this.y = y; - } - }; - return CanvasExtraState; -})(); - -var CanvasGraphics = (function CanvasGraphicsClosure() { - // Defines the time the executeOperatorList is going to be executing - // before it stops and shedules a continue of execution. - var kExecutionTime = 15; - - function CanvasGraphics(canvasCtx, objs, textLayer) { - this.ctx = canvasCtx; - this.current = new CanvasExtraState(); - this.stateStack = []; - this.pendingClip = null; - this.res = null; - this.xobjs = null; - this.objs = objs; - this.textLayer = textLayer; - if (canvasCtx) { - addContextCurrentTransform(canvasCtx); - } - } - - var LINE_CAP_STYLES = ['butt', 'round', 'square']; - var LINE_JOIN_STYLES = ['miter', 'round', 'bevel']; - var NORMAL_CLIP = {}; - var EO_CLIP = {}; - - CanvasGraphics.prototype = { - slowCommands: { - 'stroke': true, - 'closeStroke': true, - 'fill': true, - 'eoFill': true, - 'fillStroke': true, - 'eoFillStroke': true, - 'closeFillStroke': true, - 'closeEOFillStroke': true, - 'showText': true, - 'showSpacedText': true, - 'setStrokeColorSpace': true, - 'setFillColorSpace': true, - 'setStrokeColor': true, - 'setStrokeColorN': true, - 'setFillColor': true, - 'setFillColorN': true, - 'setStrokeGray': true, - 'setFillGray': true, - 'setStrokeRGBColor': true, - 'setFillRGBColor': true, - 'setStrokeCMYKColor': true, - 'setFillCMYKColor': true, - 'paintJpegXObject': true, - 'paintImageXObject': true, - 'paintImageMaskXObject': true, - 'shadingFill': true - }, - - beginDrawing: function CanvasGraphics_beginDrawing(viewport) { - var transform = viewport.transform; - this.ctx.save(); - this.ctx.transform.apply(this.ctx, transform); - - if (this.textLayer) - this.textLayer.beginLayout(); - }, - - executeOperatorList: function CanvasGraphics_executeOperatorList( - operatorList, - executionStartIdx, continueCallback, - stepper) { - var argsArray = operatorList.argsArray; - var fnArray = operatorList.fnArray; - var i = executionStartIdx || 0; - var argsArrayLen = argsArray.length; - - // Sometimes the OperatorList to execute is empty. - if (argsArrayLen == i) { - return i; - } - - var executionEndIdx; - var endTime = Date.now() + kExecutionTime; - - var objs = this.objs; - var fnName; - var slowCommands = this.slowCommands; - - while (true) { - if (stepper && i === stepper.nextBreakPoint) { - stepper.breakIt(i, continueCallback); - return i; - } - - fnName = fnArray[i]; - - if (fnName !== 'dependency') { - this[fnName].apply(this, argsArray[i]); - } else { - var deps = argsArray[i]; - for (var n = 0, nn = deps.length; n < nn; n++) { - var depObjId = deps[n]; - - // If the promise isn't resolved yet, add the continueCallback - // to the promise and bail out. - if (!objs.isResolved(depObjId)) { - objs.get(depObjId, continueCallback); - return i; - } - } - } - - i++; - - // If the entire operatorList was executed, stop as were done. - if (i == argsArrayLen) { - return i; - } - - // If the execution took longer then a certain amount of time, shedule - // to continue exeution after a short delay. - // However, this is only possible if a 'continueCallback' is passed in. - if (continueCallback && slowCommands[fnName] && Date.now() > endTime) { - setTimeout(continueCallback, 0); - return i; - } - - // If the operatorList isn't executed completely yet OR the execution - // time was short enough, do another execution round. - } - }, - - endDrawing: function CanvasGraphics_endDrawing() { - this.ctx.restore(); - - if (this.textLayer) - this.textLayer.endLayout(); - }, - - // Graphics state - setLineWidth: function CanvasGraphics_setLineWidth(width) { - this.current.lineWidth = width; - this.ctx.lineWidth = width; - }, - setLineCap: function CanvasGraphics_setLineCap(style) { - this.ctx.lineCap = LINE_CAP_STYLES[style]; - }, - setLineJoin: function CanvasGraphics_setLineJoin(style) { - this.ctx.lineJoin = LINE_JOIN_STYLES[style]; - }, - setMiterLimit: function CanvasGraphics_setMiterLimit(limit) { - this.ctx.miterLimit = limit; - }, - setDash: function CanvasGraphics_setDash(dashArray, dashPhase) { - this.ctx.mozDash = dashArray; - this.ctx.mozDashOffset = dashPhase; - this.ctx.webkitLineDash = dashArray; - this.ctx.webkitLineDashOffset = dashPhase; - }, - setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) { - // Maybe if we one day fully support color spaces this will be important - // for now we can ignore. - // TODO set rendering intent? - }, - setFlatness: function CanvasGraphics_setFlatness(flatness) { - // There's no way to control this with canvas, but we can safely ignore. - // TODO set flatness? - }, - setGState: function CanvasGraphics_setGState(states) { - for (var i = 0, ii = states.length; i < ii; i++) { - var state = states[i]; - var key = state[0]; - var value = state[1]; - - switch (key) { - case 'LW': - this.setLineWidth(value); - break; - case 'LC': - this.setLineCap(value); - break; - case 'LJ': - this.setLineJoin(value); - break; - case 'ML': - this.setMiterLimit(value); - break; - case 'D': - this.setDash(value[0], value[1]); - break; - case 'RI': - this.setRenderingIntent(value); - break; - case 'FL': - this.setFlatness(value); - break; - case 'Font': - this.setFont(state[1], state[2]); - break; - case 'CA': - this.current.strokeAlpha = state[1]; - break; - case 'ca': - this.current.fillAlpha = state[1]; - this.ctx.globalAlpha = state[1]; - break; - } - } - }, - save: function CanvasGraphics_save() { - this.ctx.save(); - var old = this.current; - this.stateStack.push(old); - this.current = old.clone(); - }, - restore: function CanvasGraphics_restore() { - var prev = this.stateStack.pop(); - if (prev) { - this.current = prev; - this.ctx.restore(); - } - }, - transform: function CanvasGraphics_transform(a, b, c, d, e, f) { - this.ctx.transform(a, b, c, d, e, f); - }, - - // Path - moveTo: function CanvasGraphics_moveTo(x, y) { - this.ctx.moveTo(x, y); - this.current.setCurrentPoint(x, y); - }, - lineTo: function CanvasGraphics_lineTo(x, y) { - this.ctx.lineTo(x, y); - this.current.setCurrentPoint(x, y); - }, - curveTo: function CanvasGraphics_curveTo(x1, y1, x2, y2, x3, y3) { - this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); - this.current.setCurrentPoint(x3, y3); - }, - curveTo2: function CanvasGraphics_curveTo2(x2, y2, x3, y3) { - var current = this.current; - this.ctx.bezierCurveTo(current.x, current.y, x2, y2, x3, y3); - current.setCurrentPoint(x3, y3); - }, - curveTo3: function CanvasGraphics_curveTo3(x1, y1, x3, y3) { - this.curveTo(x1, y1, x3, y3, x3, y3); - this.current.setCurrentPoint(x3, y3); - }, - closePath: function CanvasGraphics_closePath() { - this.ctx.closePath(); - }, - rectangle: function CanvasGraphics_rectangle(x, y, width, height) { - this.ctx.rect(x, y, width, height); - }, - stroke: function CanvasGraphics_stroke(consumePath) { - consumePath = typeof consumePath !== 'undefined' ? consumePath : true; - var ctx = this.ctx; - var strokeColor = this.current.strokeColor; - if (this.current.lineWidth === 0) - ctx.lineWidth = this.getSinglePixelWidth(); - // For stroke we want to temporarily change the global alpha to the - // stroking alpha. - ctx.globalAlpha = this.current.strokeAlpha; - if (strokeColor && strokeColor.hasOwnProperty('type') && - strokeColor.type === 'Pattern') { - // for patterns, we transform to pattern space, calculate - // the pattern, call stroke, and restore to user space - ctx.save(); - ctx.strokeStyle = strokeColor.getPattern(ctx); - ctx.stroke(); - ctx.restore(); - } else { - ctx.stroke(); - } - if (consumePath) - this.consumePath(); - // Restore the global alpha to the fill alpha - ctx.globalAlpha = this.current.fillAlpha; - }, - closeStroke: function CanvasGraphics_closeStroke() { - this.closePath(); - this.stroke(); - }, - fill: function CanvasGraphics_fill(consumePath) { - consumePath = typeof consumePath !== 'undefined' ? consumePath : true; - var ctx = this.ctx; - var fillColor = this.current.fillColor; - - if (fillColor && fillColor.hasOwnProperty('type') && - fillColor.type === 'Pattern') { - ctx.save(); - ctx.fillStyle = fillColor.getPattern(ctx); - ctx.fill(); - ctx.restore(); - } else { - ctx.fill(); - } - if (consumePath) - this.consumePath(); - }, - eoFill: function CanvasGraphics_eoFill() { - var savedFillRule = this.setEOFillRule(); - this.fill(); - this.restoreFillRule(savedFillRule); - }, - fillStroke: function CanvasGraphics_fillStroke() { - this.fill(false); - this.stroke(false); - - this.consumePath(); - }, - eoFillStroke: function CanvasGraphics_eoFillStroke() { - var savedFillRule = this.setEOFillRule(); - this.fillStroke(); - this.restoreFillRule(savedFillRule); - }, - closeFillStroke: function CanvasGraphics_closeFillStroke() { - this.closePath(); - this.fillStroke(); - }, - closeEOFillStroke: function CanvasGraphics_closeEOFillStroke() { - var savedFillRule = this.setEOFillRule(); - this.closePath(); - this.fillStroke(); - this.restoreFillRule(savedFillRule); - }, - endPath: function CanvasGraphics_endPath() { - this.consumePath(); - }, - - // Clipping - clip: function CanvasGraphics_clip() { - this.pendingClip = NORMAL_CLIP; - }, - eoClip: function CanvasGraphics_eoClip() { - this.pendingClip = EO_CLIP; - }, - - // Text - beginText: function CanvasGraphics_beginText() { - this.current.textMatrix = IDENTITY_MATRIX; - this.current.x = this.current.lineX = 0; - this.current.y = this.current.lineY = 0; - }, - endText: function CanvasGraphics_endText() { - }, - setCharSpacing: function CanvasGraphics_setCharSpacing(spacing) { - this.current.charSpacing = spacing; - }, - setWordSpacing: function CanvasGraphics_setWordSpacing(spacing) { - this.current.wordSpacing = spacing; - }, - setHScale: function CanvasGraphics_setHScale(scale) { - this.current.textHScale = scale / 100; - }, - setLeading: function CanvasGraphics_setLeading(leading) { - this.current.leading = -leading; - }, - setFont: function CanvasGraphics_setFont(fontRefName, size) { - var fontObj = this.objs.get(fontRefName); - var current = this.current; - - if (!fontObj) - error('Can\'t find font for ' + fontRefName); - - // Slice-clone matrix so we can manipulate it without affecting original - if (fontObj.fontMatrix) - current.fontMatrix = fontObj.fontMatrix.slice(0); - else - current.fontMatrix = IDENTITY_MATRIX.slice(0); - - // A valid matrix needs all main diagonal elements to be non-zero - // This also ensures we bypass FF bugzilla bug #719844. - if (current.fontMatrix[0] === 0 || - current.fontMatrix[3] === 0) { - warn('Invalid font matrix for font ' + fontRefName); - } - - // The spec for Tf (setFont) says that 'size' specifies the font 'scale', - // and in some docs this can be negative (inverted x-y axes). - // We implement this condition with fontMatrix. - if (size < 0) { - size = -size; - current.fontMatrix[0] *= -1; - current.fontMatrix[3] *= -1; - } - - this.current.font = fontObj; - this.current.fontSize = size; - - if (fontObj.coded) - return; // we don't need ctx.font for Type3 fonts - - var name = fontObj.loadedName || 'sans-serif'; - var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') : - (fontObj.bold ? 'bold' : 'normal'); - - var italic = fontObj.italic ? 'italic' : 'normal'; - var serif = fontObj.isSerifFont ? 'serif' : 'sans-serif'; - var typeface = '"' + name + '", ' + serif; - - // Some font backends cannot handle fonts below certain size. - // Keeping the font at minimal size and using the fontSizeScale to change - // the current transformation matrix before the fillText/strokeText. - // See https://bugzilla.mozilla.org/show_bug.cgi?id=726227 - var browserFontSize = size >= MIN_FONT_SIZE ? size : MIN_FONT_SIZE; - this.current.fontSizeScale = browserFontSize != MIN_FONT_SIZE ? 1.0 : - size / MIN_FONT_SIZE; - - var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface; - this.ctx.font = rule; - }, - setTextRenderingMode: function CanvasGraphics_setTextRenderingMode(mode) { - if (mode >= TextRenderingMode.FILL_ADD_TO_PATH) - TODO('unsupported text rendering mode: ' + mode); - this.current.textRenderingMode = mode; - }, - setTextRise: function CanvasGraphics_setTextRise(rise) { - TODO('text rise: ' + rise); - }, - moveText: function CanvasGraphics_moveText(x, y) { - this.current.x = this.current.lineX += x; - this.current.y = this.current.lineY += y; - }, - setLeadingMoveText: function CanvasGraphics_setLeadingMoveText(x, y) { - this.setLeading(-y); - this.moveText(x, y); - }, - setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) { - this.current.textMatrix = [a, b, c, d, e, f]; - - this.current.x = this.current.lineX = 0; - this.current.y = this.current.lineY = 0; - }, - nextLine: function CanvasGraphics_nextLine() { - this.moveText(0, this.current.leading); - }, - applyTextTransforms: function CanvasGraphics_applyTextTransforms() { - var ctx = this.ctx; - var current = this.current; - var textHScale = current.textHScale; - var fontMatrix = current.fontMatrix || IDENTITY_MATRIX; - - ctx.transform.apply(ctx, current.textMatrix); - ctx.scale(1, -1); - ctx.translate(current.x, -1 * current.y); - ctx.transform.apply(ctx, fontMatrix); - ctx.scale(textHScale, 1); - }, - getTextGeometry: function CanvasGraphics_getTextGeometry() { - var geometry = {}; - var ctx = this.ctx; - var font = this.current.font; - var ctxMatrix = ctx.mozCurrentTransform; - if (ctxMatrix) { - var bl = Util.applyTransform([0, 0], ctxMatrix); - var tr = Util.applyTransform([1, 1], ctxMatrix); - geometry.x = bl[0]; - geometry.y = bl[1]; - geometry.hScale = tr[0] - bl[0]; - geometry.vScale = tr[1] - bl[1]; - } - geometry.spaceWidth = font.spaceWidth; - return geometry; - }, - - showText: function CanvasGraphics_showText(str, skipTextSelection) { - var ctx = this.ctx; - var current = this.current; - var font = current.font; - var glyphs = font.charsToGlyphs(str); - var fontSize = current.fontSize; - var fontSizeScale = current.fontSizeScale; - var charSpacing = current.charSpacing; - var wordSpacing = current.wordSpacing; - var textHScale = current.textHScale; - var fontMatrix = current.fontMatrix || IDENTITY_MATRIX; - var textHScale2 = textHScale * fontMatrix[0]; - var glyphsLength = glyphs.length; - var textLayer = this.textLayer; - var text = {str: '', length: 0, canvasWidth: 0, geom: {}}; - var textSelection = textLayer && !skipTextSelection ? true : false; - var textRenderingMode = current.textRenderingMode; - - // Type3 fonts - each glyph is a "mini-PDF" - if (font.coded) { - ctx.save(); - ctx.transform.apply(ctx, current.textMatrix); - ctx.translate(current.x, current.y); - - ctx.scale(textHScale, 1); - - if (textSelection) { - this.save(); - ctx.scale(1, -1); - text.geom = this.getTextGeometry(); - this.restore(); - } - for (var i = 0; i < glyphsLength; ++i) { - - var glyph = glyphs[i]; - if (glyph === null) { - // word break - this.ctx.translate(wordSpacing, 0); - continue; - } - - this.save(); - ctx.scale(fontSize, fontSize); - ctx.transform.apply(ctx, fontMatrix); - this.executeOperatorList(glyph.operatorList); - this.restore(); - - var transformed = Util.applyTransform([glyph.width, 0], fontMatrix); - var width = transformed[0] * fontSize + - Util.sign(current.fontMatrix[0]) * charSpacing; - - ctx.translate(width, 0); - current.x += width * textHScale; - - text.str += glyph.unicode; - text.length++; - text.canvasWidth += width; - } - ctx.restore(); - } else { - ctx.save(); - this.applyTextTransforms(); - - var lineWidth = current.lineWidth; - var scale = Math.abs(current.textMatrix[0] * fontMatrix[0]); - if (scale == 0 || lineWidth == 0) - lineWidth = this.getSinglePixelWidth(); - else - lineWidth /= scale; - - if (textSelection) - text.geom = this.getTextGeometry(); - - if (fontSizeScale != 1.0) { - ctx.scale(fontSizeScale, fontSizeScale); - lineWidth /= fontSizeScale; - } - - ctx.lineWidth = lineWidth; - - var x = 0; - for (var i = 0; i < glyphsLength; ++i) { - var glyph = glyphs[i]; - if (glyph === null) { - // word break - x += Util.sign(current.fontMatrix[0]) * wordSpacing; - continue; - } - - var character = glyph.fontChar; - var charWidth = glyph.width * fontSize * 0.001 + - Util.sign(current.fontMatrix[0]) * charSpacing; - - if (!glyph.disabled) { - var scaledX = x / fontSizeScale; - switch (textRenderingMode) { - default: // other unsupported rendering modes - case TextRenderingMode.FILL: - case TextRenderingMode.FILL_ADD_TO_PATH: - ctx.fillText(character, scaledX, 0); - break; - case TextRenderingMode.STROKE: - case TextRenderingMode.STROKE_ADD_TO_PATH: - ctx.strokeText(character, scaledX, 0); - break; - case TextRenderingMode.FILL_STROKE: - case TextRenderingMode.FILL_STROKE_ADD_TO_PATH: - ctx.fillText(character, scaledX, 0); - ctx.strokeText(character, scaledX, 0); - break; - case TextRenderingMode.INVISIBLE: - break; - } - } - - x += charWidth; - - var glyphUnicode = glyph.unicode === ' ' ? '\u00A0' : glyph.unicode; - var glyphUnicodeLength = glyphUnicode.length; - //reverse an arabic ligature - if (glyphUnicodeLength > 1 && - isRTLRangeFor(glyphUnicode.charCodeAt(0))) { - for (var ii = glyphUnicodeLength - 1; ii >= 0; ii--) - text.str += glyphUnicode[ii]; - } else - text.str += glyphUnicode; - text.length += glyphUnicodeLength; - text.canvasWidth += charWidth; - } - current.x += x * textHScale2; - ctx.restore(); - } - - if (textSelection) - this.textLayer.appendText(text, font.loadedName, fontSize); - - return text; - }, - showSpacedText: function CanvasGraphics_showSpacedText(arr) { - var ctx = this.ctx; - var current = this.current; - var font = current.font; - var fontSize = current.fontSize; - var textHScale = current.textHScale; - if (!font.coded) - textHScale *= (current.fontMatrix || IDENTITY_MATRIX)[0]; - var arrLength = arr.length; - var textLayer = this.textLayer; - var text = {str: '', length: 0, canvasWidth: 0, geom: {}}; - var textSelection = textLayer ? true : false; - - if (textSelection) { - ctx.save(); - // Type3 fonts - each glyph is a "mini-PDF" (see also showText) - if (font.coded) { - ctx.transform.apply(ctx, current.textMatrix); - ctx.scale(1, -1); - ctx.translate(current.x, -1 * current.y); - ctx.scale(textHScale, 1); - } else - this.applyTextTransforms(); - text.geom = this.getTextGeometry(); - ctx.restore(); - } - - for (var i = 0; i < arrLength; ++i) { - var e = arr[i]; - if (isNum(e)) { - var spacingLength = -e * 0.001 * fontSize * textHScale; - current.x += spacingLength; - - if (textSelection) { - // Emulate precise spacing via HTML spaces - text.canvasWidth += spacingLength; - if (e < 0 && text.geom.spaceWidth > 0) { // avoid div by zero - var numFakeSpaces = Math.round(-e / text.geom.spaceWidth); - if (numFakeSpaces > 0) { - text.str += '\u00A0'; - text.length++; - } - } - } - } else if (isString(e)) { - var shownText = this.showText(e, true); - - if (textSelection) { - if (shownText.str === ' ') { - text.str += '\u00A0'; - } else { - text.str += shownText.str; - } - text.canvasWidth += shownText.canvasWidth; - text.length += shownText.length; - } - } else { - error('TJ array element ' + e + ' is not string or num'); - } - } - - if (textSelection) - this.textLayer.appendText(text, font.loadedName, fontSize); - }, - nextLineShowText: function CanvasGraphics_nextLineShowText(text) { - this.nextLine(); - this.showText(text); - }, - nextLineSetSpacingShowText: - function CanvasGraphics_nextLineSetSpacingShowText(wordSpacing, - charSpacing, - text) { - this.setWordSpacing(wordSpacing); - this.setCharSpacing(charSpacing); - this.nextLineShowText(text); - }, - - // Type3 fonts - setCharWidth: function CanvasGraphics_setCharWidth(xWidth, yWidth) { - // We can safely ignore this since the width should be the same - // as the width in the Widths array. - }, - setCharWidthAndBounds: function CanvasGraphics_setCharWidthAndBounds(xWidth, - yWidth, - llx, - lly, - urx, - ury) { - // TODO According to the spec we're also suppose to ignore any operators - // that set color or include images while processing this type3 font. - this.rectangle(llx, lly, urx - llx, ury - lly); - this.clip(); - this.endPath(); - }, - - // Color - setStrokeColorSpace: function CanvasGraphics_setStrokeColorSpace(raw) { - this.current.strokeColorSpace = ColorSpace.fromIR(raw); - }, - setFillColorSpace: function CanvasGraphics_setFillColorSpace(raw) { - this.current.fillColorSpace = ColorSpace.fromIR(raw); - }, - setStrokeColor: function CanvasGraphics_setStrokeColor(/*...*/) { - var cs = this.current.strokeColorSpace; - var rgbColor = cs.getRgb(arguments); - var color = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]); - this.ctx.strokeStyle = color; - this.current.strokeColor = color; - }, - getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR, cs) { - if (IR[0] == 'TilingPattern') { - var args = IR[1]; - var base = cs.base; - var color; - if (base) { - var baseComps = base.numComps; - - color = []; - for (var i = 0; i < baseComps; ++i) - color.push(args[i]); - - color = base.getRgb(color); - } - var pattern = new TilingPattern(IR, color, this.ctx, this.objs); - } else if (IR[0] == 'RadialAxial' || IR[0] == 'Dummy') { - var pattern = Pattern.shadingFromIR(IR); - } else { - error('Unkown IR type ' + IR[0]); - } - return pattern; - }, - setStrokeColorN: function CanvasGraphics_setStrokeColorN(/*...*/) { - var cs = this.current.strokeColorSpace; - - if (cs.name == 'Pattern') { - this.current.strokeColor = this.getColorN_Pattern(arguments, cs); - } else { - this.setStrokeColor.apply(this, arguments); - } - }, - setFillColor: function CanvasGraphics_setFillColor(/*...*/) { - var cs = this.current.fillColorSpace; - var rgbColor = cs.getRgb(arguments); - var color = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]); - this.ctx.fillStyle = color; - this.current.fillColor = color; - }, - setFillColorN: function CanvasGraphics_setFillColorN(/*...*/) { - var cs = this.current.fillColorSpace; - - if (cs.name == 'Pattern') { - this.current.fillColor = this.getColorN_Pattern(arguments, cs); - } else { - this.setFillColor.apply(this, arguments); - } - }, - setStrokeGray: function CanvasGraphics_setStrokeGray(gray) { - if (!(this.current.strokeColorSpace instanceof DeviceGrayCS)) - this.current.strokeColorSpace = new DeviceGrayCS(); - - var color = Util.makeCssRgb(gray, gray, gray); - this.ctx.strokeStyle = color; - this.current.strokeColor = color; - }, - setFillGray: function CanvasGraphics_setFillGray(gray) { - if (!(this.current.fillColorSpace instanceof DeviceGrayCS)) - this.current.fillColorSpace = new DeviceGrayCS(); - - var color = Util.makeCssRgb(gray, gray, gray); - this.ctx.fillStyle = color; - this.current.fillColor = color; - }, - setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) { - if (!(this.current.strokeColorSpace instanceof DeviceRgbCS)) - this.current.strokeColorSpace = new DeviceRgbCS(); - - var color = Util.makeCssRgb(r, g, b); - this.ctx.strokeStyle = color; - this.current.strokeColor = color; - }, - setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) { - if (!(this.current.fillColorSpace instanceof DeviceRgbCS)) - this.current.fillColorSpace = new DeviceRgbCS(); - - var color = Util.makeCssRgb(r, g, b); - this.ctx.fillStyle = color; - this.current.fillColor = color; - }, - setStrokeCMYKColor: function CanvasGraphics_setStrokeCMYKColor(c, m, y, k) { - if (!(this.current.strokeColorSpace instanceof DeviceCmykCS)) - this.current.strokeColorSpace = new DeviceCmykCS(); - - var color = Util.makeCssCmyk(c, m, y, k); - this.ctx.strokeStyle = color; - this.current.strokeColor = color; - }, - setFillCMYKColor: function CanvasGraphics_setFillCMYKColor(c, m, y, k) { - if (!(this.current.fillColorSpace instanceof DeviceCmykCS)) - this.current.fillColorSpace = new DeviceCmykCS(); - - var color = Util.makeCssCmyk(c, m, y, k); - this.ctx.fillStyle = color; - this.current.fillColor = color; - }, - - shadingFill: function CanvasGraphics_shadingFill(patternIR) { - var ctx = this.ctx; - - this.save(); - var pattern = Pattern.shadingFromIR(patternIR); - ctx.fillStyle = pattern.getPattern(ctx); - - var inv = ctx.mozCurrentTransformInverse; - if (inv) { - var canvas = ctx.canvas; - var width = canvas.width; - var height = canvas.height; - - var bl = Util.applyTransform([0, 0], inv); - var br = Util.applyTransform([0, height], inv); - var ul = Util.applyTransform([width, 0], inv); - var ur = Util.applyTransform([width, height], inv); - - var x0 = Math.min(bl[0], br[0], ul[0], ur[0]); - var y0 = Math.min(bl[1], br[1], ul[1], ur[1]); - var x1 = Math.max(bl[0], br[0], ul[0], ur[0]); - var y1 = Math.max(bl[1], br[1], ul[1], ur[1]); - - this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); - } else { - // HACK to draw the gradient onto an infinite rectangle. - // PDF gradients are drawn across the entire image while - // Canvas only allows gradients to be drawn in a rectangle - // The following bug should allow us to remove this. - // https://bugzilla.mozilla.org/show_bug.cgi?id=664884 - - this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); - } - - this.restore(); - }, - - // Images - beginInlineImage: function CanvasGraphics_beginInlineImage() { - error('Should not call beginInlineImage'); - }, - beginImageData: function CanvasGraphics_beginImageData() { - error('Should not call beginImageData'); - }, - - paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin(matrix, - bbox) { - this.save(); - - if (matrix && isArray(matrix) && 6 == matrix.length) - this.transform.apply(this, matrix); - - if (bbox && isArray(bbox) && 4 == bbox.length) { - var width = bbox[2] - bbox[0]; - var height = bbox[3] - bbox[1]; - this.rectangle(bbox[0], bbox[1], width, height); - this.clip(); - this.endPath(); - } - }, - - paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() { - this.restore(); - }, - - paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) { - var domImage = this.objs.get(objId); - if (!domImage) { - error('Dependent image isn\'t ready yet'); - } - - this.save(); - - var ctx = this.ctx; - // scale the image to the unit square - ctx.scale(1 / w, -1 / h); - - ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height, - 0, -h, w, h); - - this.restore(); - }, - - paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject( - imgArray, inverseDecode, width, height) { - function applyStencilMask(buffer, inverseDecode) { - var imgArrayPos = 0; - var i, j, mask, buf; - // removing making non-masked pixels transparent - var bufferPos = 3; // alpha component offset - for (i = 0; i < height; i++) { - mask = 0; - for (j = 0; j < width; j++) { - if (!mask) { - buf = imgArray[imgArrayPos++]; - mask = 128; - } - if (!(buf & mask) == inverseDecode) { - buffer[bufferPos] = 0; - } - bufferPos += 4; - mask >>= 1; - } - } - } - function rescaleImage(pixels, widthScale, heightScale) { - var scaledWidth = Math.ceil(width / widthScale); - var scaledHeight = Math.ceil(height / heightScale); - - var itemsSum = new Uint32Array(scaledWidth * scaledHeight * 4); - var itemsCount = new Uint32Array(scaledWidth * scaledHeight); - for (var i = 0, position = 0; i < height; i++) { - var lineOffset = (0 | (i / heightScale)) * scaledWidth; - for (var j = 0; j < width; j++) { - var countOffset = lineOffset + (0 | (j / widthScale)); - var sumOffset = countOffset << 2; - itemsSum[sumOffset] += pixels[position]; - itemsSum[sumOffset + 1] += pixels[position + 1]; - itemsSum[sumOffset + 2] += pixels[position + 2]; - itemsSum[sumOffset + 3] += pixels[position + 3]; - itemsCount[countOffset]++; - position += 4; - } - } - var tmpCanvas = createScratchCanvas(scaledWidth, scaledHeight); - var tmpCtx = tmpCanvas.getContext('2d'); - var imgData = tmpCtx.getImageData(0, 0, scaledWidth, scaledHeight); - pixels = imgData.data; - for (var i = 0, j = 0, ii = scaledWidth * scaledHeight; i < ii; i++) { - var count = itemsCount[i]; - pixels[j] = itemsSum[j] / count; - pixels[j + 1] = itemsSum[j + 1] / count; - pixels[j + 2] = itemsSum[j + 2] / count; - pixels[j + 3] = itemsSum[j + 3] / count; - j += 4; - } - tmpCtx.putImageData(imgData, 0, 0); - return tmpCanvas; - } - - this.save(); - - var ctx = this.ctx; - var w = width, h = height; - // scale the image to the unit square - ctx.scale(1 / w, -1 / h); - - var tmpCanvas = createScratchCanvas(w, h); - var tmpCtx = tmpCanvas.getContext('2d'); - - var fillColor = this.current.fillColor; - tmpCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') && - fillColor.type === 'Pattern') ? - fillColor.getPattern(tmpCtx) : fillColor; - tmpCtx.fillRect(0, 0, w, h); - - var imgData = tmpCtx.getImageData(0, 0, w, h); - var pixels = imgData.data; - - applyStencilMask(pixels, inverseDecode); - - var currentTransform = ctx.mozCurrentTransformInverse; - var widthScale = Math.max(Math.abs(currentTransform[0]), 1); - var heightScale = Math.max(Math.abs(currentTransform[3]), 1); - if (widthScale >= 2 || heightScale >= 2) { - // canvas does not resize well large images to small -- using simple - // algorithm to perform pre-scaling - tmpCanvas = rescaleImage(imgData.data, widthScale, heightScale); - ctx.scale(widthScale, heightScale); - ctx.drawImage(tmpCanvas, 0, -h / heightScale); - } else { - tmpCtx.putImageData(imgData, 0, 0); - ctx.drawImage(tmpCanvas, 0, -h); - } - this.restore(); - }, - - paintImageXObject: function CanvasGraphics_paintImageXObject(objId) { - var imgData = this.objs.get(objId); - if (!imgData) - error('Dependent image isn\'t ready yet'); - - this.save(); - var ctx = this.ctx; - var w = imgData.width; - var h = imgData.height; - // scale the image to the unit square - ctx.scale(1 / w, -1 / h); - - var tmpCanvas = createScratchCanvas(w, h); - var tmpCtx = tmpCanvas.getContext('2d'); - this.putBinaryImageData(tmpCtx, imgData, w, h); - - ctx.drawImage(tmpCanvas, 0, -h); - this.restore(); - }, - - putBinaryImageData: function CanvasGraphics_putBinaryImageData() { - // - }, - - // Marked content - - markPoint: function CanvasGraphics_markPoint(tag) { - TODO('Marked content'); - }, - markPointProps: function CanvasGraphics_markPointProps(tag, properties) { - TODO('Marked content'); - }, - beginMarkedContent: function CanvasGraphics_beginMarkedContent(tag) { - TODO('Marked content'); - }, - beginMarkedContentProps: function CanvasGraphics_beginMarkedContentProps( - tag, properties) { - TODO('Marked content'); - }, - endMarkedContent: function CanvasGraphics_endMarkedContent() { - TODO('Marked content'); - }, - - // Compatibility - - beginCompat: function CanvasGraphics_beginCompat() { - TODO('ignore undefined operators (should we do that anyway?)'); - }, - endCompat: function CanvasGraphics_endCompat() { - TODO('stop ignoring undefined operators'); - }, - - // Helper functions - - consumePath: function CanvasGraphics_consumePath() { - if (this.pendingClip) { - var savedFillRule = null; - if (this.pendingClip == EO_CLIP) - savedFillRule = this.setEOFillRule(); - - this.ctx.clip(); - - this.pendingClip = null; - if (savedFillRule !== null) - this.restoreFillRule(savedFillRule); - } - this.ctx.beginPath(); - }, - // We generally keep the canvas context set for - // nonzero-winding, and just set evenodd for the operations - // that need them. - setEOFillRule: function CanvasGraphics_setEOFillRule() { - var savedFillRule = this.ctx.mozFillRule; - this.ctx.mozFillRule = 'evenodd'; - return savedFillRule; - }, - restoreFillRule: function CanvasGraphics_restoreFillRule(rule) { - this.ctx.mozFillRule = rule; - }, - getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) { - var inverse = this.ctx.mozCurrentTransformInverse; - return Math.abs(inverse[0] + inverse[2]); - } - }; - - return CanvasGraphics; -})(); - -if (!isWorker) { - // Feature detection if the browser can use an Uint8Array directly as imgData. - var canvas = document.createElement('canvas'); - canvas.width = 1; - canvas.height = 1; - var ctx = canvas.getContext('2d'); - - try { - ctx.putImageData({ - width: 1, - height: 1, - data: new Uint8Array(4) - }, 0, 0); - - CanvasGraphics.prototype.putBinaryImageData = - function CanvasGraphicsPutBinaryImageDataNative(ctx, imgData) { - ctx.putImageData(imgData, 0, 0); - }; - } catch (e) { - CanvasGraphics.prototype.putBinaryImageData = - function CanvasGraphicsPutBinaryImageDataShim(ctx, imgData, w, h) { - var tmpImgData = ctx.getImageData(0, 0, w, h); - - // Copy over the imageData pixel by pixel. - var tmpImgDataPixels = tmpImgData.data; - var len = tmpImgDataPixels.length; - - while (len--) { - tmpImgDataPixels[len] = imgData.data[len]; - } - - ctx.putImageData(tmpImgData, 0, 0); - }; - } -} - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var Name = (function NameClosure() { - function Name(name) { - this.name = name; - } - - Name.prototype = {}; - - return Name; -})(); - -var Cmd = (function CmdClosure() { - function Cmd(cmd) { - this.cmd = cmd; - } - - Cmd.prototype = {}; - - var cmdCache = {}; - - Cmd.get = function Cmd_get(cmd) { - var cmdValue = cmdCache[cmd]; - if (cmdValue) - return cmdValue; - - return cmdCache[cmd] = new Cmd(cmd); - }; - - return Cmd; -})(); - -var Dict = (function DictClosure() { - // xref is optional - function Dict(xref) { - // Map should only be used internally, use functions below to access. - var map = Object.create(null); - - this.assignXref = function Dict_assignXref(newXref) { - xref = newXref; - }; - - // automatically dereferences Ref objects - this.get = function Dict_get(key1, key2, key3) { - var value; - if (typeof (value = map[key1]) != 'undefined' || key1 in map || - typeof key2 == 'undefined') { - return xref ? xref.fetchIfRef(value) : value; - } - if (typeof (value = map[key2]) != 'undefined' || key2 in map || - typeof key3 == 'undefined') { - return xref ? xref.fetchIfRef(value) : value; - } - value = map[key3] || null; - return xref ? xref.fetchIfRef(value) : value; - }; - - // no dereferencing - this.getRaw = function Dict_getRaw(key) { - return map[key]; - }; - - // creates new map and dereferences all Refs - this.getAll = function Dict_getAll() { - var all = {}; - for (var key in map) { - var obj = this.get(key); - all[key] = obj instanceof Dict ? obj.getAll() : obj; - } - return all; - }; - - this.set = function Dict_set(key, value) { - map[key] = value; - }; - - this.has = function Dict_has(key) { - return key in map; - }; - - this.forEach = function Dict_forEach(callback) { - for (var key in map) { - callback(key, this.get(key)); - } - }; - }; - - return Dict; -})(); - -var Ref = (function RefClosure() { - function Ref(num, gen) { - this.num = num; - this.gen = gen; - } - - Ref.prototype = {}; - - return Ref; -})(); - -// The reference is identified by number and generation, -// this structure stores only one instance of the reference. -var RefSet = (function RefSetClosure() { - function RefSet() { - this.dict = {}; - } - - RefSet.prototype = { - has: function RefSet_has(ref) { - return !!this.dict['R' + ref.num + '.' + ref.gen]; - }, - - put: function RefSet_put(ref) { - this.dict['R' + ref.num + '.' + ref.gen] = ref; - } - }; - - return RefSet; -})(); - -var Catalog = (function CatalogClosure() { - function Catalog(xref) { - this.xref = xref; - var obj = xref.getCatalogObj(); - assertWellFormed(isDict(obj), 'catalog object is not a dictionary'); - this.catDict = obj; - } - - Catalog.prototype = { - get metadata() { - var streamRef = this.catDict.getRaw('Metadata'); - if (!isRef(streamRef)) - return shadow(this, 'metadata', null); - - var encryptMetadata = !this.xref.encrypt ? false : - this.xref.encrypt.encryptMetadata; - - var stream = this.xref.fetch(streamRef, !encryptMetadata); - var metadata; - if (stream && isDict(stream.dict)) { - var type = stream.dict.get('Type'); - var subtype = stream.dict.get('Subtype'); - - if (isName(type) && isName(subtype) && - type.name === 'Metadata' && subtype.name === 'XML') { - // XXX: This should examine the charset the XML document defines, - // however since there are currently no real means to decode - // arbitrary charsets, let's just hope that the author of the PDF - // was reasonable enough to stick with the XML default charset, - // which is UTF-8. - try { - metadata = stringToUTF8String(bytesToString(stream.getBytes())); - } catch (e) { - info('Skipping invalid metadata.'); - } - } - } - - return shadow(this, 'metadata', metadata); - }, - get toplevelPagesDict() { - var pagesObj = this.catDict.get('Pages'); - assertWellFormed(isDict(pagesObj), 'invalid top-level pages dictionary'); - // shadow the prototype getter - return shadow(this, 'toplevelPagesDict', pagesObj); - }, - get documentOutline() { - var xref = this.xref; - var obj = this.catDict.get('Outlines'); - var root = { items: [] }; - if (isDict(obj)) { - obj = obj.getRaw('First'); - var processed = new RefSet(); - if (isRef(obj)) { - var queue = [{obj: obj, parent: root}]; - // to avoid recursion keeping track of the items - // in the processed dictionary - processed.put(obj); - while (queue.length > 0) { - var i = queue.shift(); - var outlineDict = xref.fetchIfRef(i.obj); - if (outlineDict === null) - continue; - if (!outlineDict.has('Title')) - error('Invalid outline item'); - var dest = outlineDict.get('A'); - if (dest) - dest = dest.get('D'); - else if (outlineDict.has('Dest')) { - dest = outlineDict.getRaw('Dest'); - if (isName(dest)) - dest = dest.name; - } - var title = outlineDict.get('Title'); - var outlineItem = { - dest: dest, - title: stringToPDFString(title), - color: outlineDict.get('C') || [0, 0, 0], - count: outlineDict.get('Count'), - bold: !!(outlineDict.get('F') & 2), - italic: !!(outlineDict.get('F') & 1), - items: [] - }; - i.parent.items.push(outlineItem); - obj = outlineDict.getRaw('First'); - if (isRef(obj) && !processed.has(obj)) { - queue.push({obj: obj, parent: outlineItem}); - processed.put(obj); - } - obj = outlineDict.getRaw('Next'); - if (isRef(obj) && !processed.has(obj)) { - queue.push({obj: obj, parent: i.parent}); - processed.put(obj); - } - } - } - } - obj = root.items.length > 0 ? root.items : null; - return shadow(this, 'documentOutline', obj); - }, - get numPages() { - var obj = this.toplevelPagesDict.get('Count'); - assertWellFormed( - isInt(obj), - 'page count in top level pages object is not an integer' - ); - // shadow the prototype getter - return shadow(this, 'num', obj); - }, - traverseKids: function Catalog_traverseKids(pagesDict) { - var pageCache = this.pageCache; - var kids = pagesDict.get('Kids'); - assertWellFormed(isArray(kids), - 'page dictionary kids object is not an array'); - for (var i = 0, ii = kids.length; i < ii; ++i) { - var kid = kids[i]; - assertWellFormed(isRef(kid), - 'page dictionary kid is not a reference'); - var obj = this.xref.fetch(kid); - if (isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids'))) { - pageCache.push(new Page(this.xref, pageCache.length, obj, kid)); - } else { // must be a child page dictionary - assertWellFormed( - isDict(obj), - 'page dictionary kid reference points to wrong type of object' - ); - this.traverseKids(obj); - } - } - }, - get destinations() { - function fetchDestination(dest) { - return isDict(dest) ? dest.get('D') : dest; - } - - var xref = this.xref; - var dests = {}, nameTreeRef, nameDictionaryRef; - var obj = this.catDict.get('Names'); - if (obj) - nameTreeRef = obj.getRaw('Dests'); - else if (this.catDict.has('Dests')) - nameDictionaryRef = this.catDict.get('Dests'); - - if (nameDictionaryRef) { - // reading simple destination dictionary - obj = nameDictionaryRef; - obj.forEach(function catalogForEach(key, value) { - if (!value) return; - dests[key] = fetchDestination(value); - }); - } - if (nameTreeRef) { - // reading name tree - var processed = new RefSet(); - processed.put(nameTreeRef); - var queue = [nameTreeRef]; - while (queue.length > 0) { - var i, n; - obj = xref.fetch(queue.shift()); - if (obj.has('Kids')) { - var kids = obj.get('Kids'); - for (i = 0, n = kids.length; i < n; i++) { - var kid = kids[i]; - if (processed.has(kid)) - error('invalid destinations'); - queue.push(kid); - processed.put(kid); - } - continue; - } - var names = obj.get('Names'); - for (i = 0, n = names.length; i < n; i += 2) { - dests[names[i]] = fetchDestination(xref.fetchIfRef(names[i + 1])); - } - } - } - return shadow(this, 'destinations', dests); - }, - getPage: function Catalog_getPage(n) { - var pageCache = this.pageCache; - if (!pageCache) { - pageCache = this.pageCache = []; - this.traverseKids(this.toplevelPagesDict); - } - return this.pageCache[n - 1]; - } - }; - - return Catalog; -})(); - -var XRef = (function XRefClosure() { - function XRef(stream, startXRef, mainXRefEntriesOffset, password) { - this.stream = stream; - this.entries = []; - this.xrefstms = {}; - var trailerDict = this.readXRef(startXRef); - trailerDict.assignXref(this); - this.trailer = trailerDict; - // prepare the XRef cache - this.cache = []; - - var encrypt = trailerDict.get('Encrypt'); - if (encrypt) { - var fileId = trailerDict.get('ID'); - this.encrypt = new CipherTransformFactory(encrypt, fileId[0], password); - } - - // get the root dictionary (catalog) object - if (!(this.root = trailerDict.get('Root'))) - error('Invalid root reference'); - } - - XRef.prototype = { - readXRefTable: function XRef_readXRefTable(parser) { - // Example of cross-reference table: - // xref - // 0 1 <-- subsection header (first obj #, obj count) - // 0000000000 65535 f <-- actual object (offset, generation #, f/n) - // 23 2 <-- subsection header ... and so on ... - // 0000025518 00002 n - // 0000025635 00000 n - // trailer - // ... - - // Outer loop is over subsection headers - var obj; - while (!isCmd(obj = parser.getObj(), 'trailer')) { - var first = obj, - count = parser.getObj(); - - if (!isInt(first) || !isInt(count)) - error('Invalid XRef table: wrong types in subsection header'); - - // Inner loop is over objects themselves - for (var i = 0; i < count; i++) { - var entry = {}; - entry.offset = parser.getObj(); - entry.gen = parser.getObj(); - var type = parser.getObj(); - - if (isCmd(type, 'f')) - entry.free = true; - else if (isCmd(type, 'n')) - entry.uncompressed = true; - - // Validate entry obj - if (!isInt(entry.offset) || !isInt(entry.gen) || - !(entry.free || entry.uncompressed)) { - error('Invalid entry in XRef subsection: ' + first + ', ' + count); - } - - if (!this.entries[i + first]) - this.entries[i + first] = entry; - } - } - - // Sanity check: as per spec, first object must be free - if (this.entries[0] && !this.entries[0].free) - error('Invalid XRef table: unexpected first object'); - - // Sanity check - if (!isCmd(obj, 'trailer')) - error('Invalid XRef table: could not find trailer dictionary'); - - // Read trailer dictionary, e.g. - // trailer - // << /Size 22 - // /Root 20R - // /Info 10R - // /ID [ <81b14aafa313db63dbd6f981e49f94f4> ] - // >> - // The parser goes through the entire stream << ... >> and provides - // a getter interface for the key-value table - var dict = parser.getObj(); - if (!isDict(dict)) - error('Invalid XRef table: could not parse trailer dictionary'); - - return dict; - }, - readXRefStream: function XRef_readXRefStream(stream) { - var streamParameters = stream.parameters; - var byteWidths = streamParameters.get('W'); - var range = streamParameters.get('Index'); - if (!range) - range = [0, streamParameters.get('Size')]; - var i, j; - while (range.length > 0) { - var first = range[0], n = range[1]; - if (!isInt(first) || !isInt(n)) - error('Invalid XRef range fields: ' + first + ', ' + n); - var typeFieldWidth = byteWidths[0]; - var offsetFieldWidth = byteWidths[1]; - var generationFieldWidth = byteWidths[2]; - if (!isInt(typeFieldWidth) || !isInt(offsetFieldWidth) || - !isInt(generationFieldWidth)) { - error('Invalid XRef entry fields length: ' + first + ', ' + n); - } - for (i = 0; i < n; ++i) { - var type = 0, offset = 0, generation = 0; - for (j = 0; j < typeFieldWidth; ++j) - type = (type << 8) | stream.getByte(); - // if type field is absent, its default value = 1 - if (typeFieldWidth == 0) - type = 1; - for (j = 0; j < offsetFieldWidth; ++j) - offset = (offset << 8) | stream.getByte(); - for (j = 0; j < generationFieldWidth; ++j) - generation = (generation << 8) | stream.getByte(); - var entry = {}; - entry.offset = offset; - entry.gen = generation; - switch (type) { - case 0: - entry.free = true; - break; - case 1: - entry.uncompressed = true; - break; - case 2: - break; - default: - error('Invalid XRef entry type: ' + type); - } - if (!this.entries[first + i]) - this.entries[first + i] = entry; - } - range.splice(0, 2); - } - return streamParameters; - }, - indexObjects: function XRef_indexObjects() { - // Simple scan through the PDF content to find objects, - // trailers and XRef streams. - function readToken(data, offset) { - var token = '', ch = data[offset]; - while (ch !== 13 && ch !== 10) { - if (++offset >= data.length) - break; - token += String.fromCharCode(ch); - ch = data[offset]; - } - return token; - } - function skipUntil(data, offset, what) { - var length = what.length, dataLength = data.length; - var skipped = 0; - // finding byte sequence - while (offset < dataLength) { - var i = 0; - while (i < length && data[offset + i] == what[i]) - ++i; - if (i >= length) - break; // sequence found - - offset++; - skipped++; - } - return skipped; - } - var trailerBytes = new Uint8Array([116, 114, 97, 105, 108, 101, 114]); - var startxrefBytes = new Uint8Array([115, 116, 97, 114, 116, 120, 114, - 101, 102]); - var endobjBytes = new Uint8Array([101, 110, 100, 111, 98, 106]); - var xrefBytes = new Uint8Array([47, 88, 82, 101, 102]); - - var stream = this.stream; - stream.pos = 0; - var buffer = stream.getBytes(); - var position = stream.start, length = buffer.length; - var trailers = [], xrefStms = []; - var state = 0; - var currentToken; - while (position < length) { - var ch = buffer[position]; - if (ch === 32 || ch === 9 || ch === 13 || ch === 10) { - ++position; - continue; - } - if (ch === 37) { // %-comment - do { - ++position; - ch = buffer[position]; - } while (ch !== 13 && ch !== 10); - continue; - } - var token = readToken(buffer, position); - var m; - if (token === 'xref') { - position += skipUntil(buffer, position, trailerBytes); - trailers.push(position); - position += skipUntil(buffer, position, startxrefBytes); - } else if ((m = /^(\d+)\s+(\d+)\s+obj\b/.exec(token))) { - this.entries[m[1]] = { - offset: position, - gen: m[2] | 0, - uncompressed: true - }; - - var contentLength = skipUntil(buffer, position, endobjBytes) + 7; - var content = buffer.subarray(position, position + contentLength); - - // checking XRef stream suspect - // (it shall have '/XRef' and next char is not a letter) - var xrefTagOffset = skipUntil(content, 0, xrefBytes); - if (xrefTagOffset < contentLength && - content[xrefTagOffset + 5] < 64) { - xrefStms.push(position); - this.xrefstms[position] = 1; // don't read it recursively - } - - position += contentLength; - } else - position += token.length + 1; - } - // reading XRef streams - for (var i = 0, ii = xrefStms.length; i < ii; ++i) { - this.readXRef(xrefStms[i], true); - } - // finding main trailer - var dict; - for (var i = 0, ii = trailers.length; i < ii; ++i) { - stream.pos = trailers[i]; - var parser = new Parser(new Lexer(stream), true, null); - var obj = parser.getObj(); - if (!isCmd(obj, 'trailer')) - continue; - // read the trailer dictionary - if (!isDict(dict = parser.getObj())) - continue; - // taking the first one with 'ID' - if (dict.has('ID')) - return dict; - } - // no tailer with 'ID', taking last one (if exists) - if (dict) - return dict; - // nothing helps - error('Invalid PDF structure'); - }, - readXRef: function XRef_readXRef(startXRef, recoveryMode) { - var stream = this.stream; - stream.pos = startXRef; - - try { - var parser = new Parser(new Lexer(stream), true, null); - var obj = parser.getObj(); - var dict; - - // Get dictionary - if (isCmd(obj, 'xref')) { - // Parse end-of-file XRef - dict = this.readXRefTable(parser); - - // Recursively get other XRefs 'XRefStm', if any - obj = dict.get('XRefStm'); - if (isInt(obj)) { - var pos = obj; - // ignore previously loaded xref streams - // (possible infinite recursion) - if (!(pos in this.xrefstms)) { - this.xrefstms[pos] = 1; - this.readXRef(pos); - } - } - } else if (isInt(obj)) { - // Parse in-stream XRef - if (!isInt(parser.getObj()) || - !isCmd(parser.getObj(), 'obj') || - !isStream(obj = parser.getObj())) { - error('Invalid XRef stream'); - } - dict = this.readXRefStream(obj); - if (!dict) - error('Failed to read XRef stream'); - } - - // Recursively get previous dictionary, if any - obj = dict.get('Prev'); - if (isInt(obj)) - this.readXRef(obj, recoveryMode); - else if (isRef(obj)) { - // The spec says Prev must not be a reference, i.e. "/Prev NNN" - // This is a fallback for non-compliant PDFs, i.e. "/Prev NNN 0 R" - this.readXRef(obj.num, recoveryMode); - } - - return dict; - } catch (e) { - log('(while reading XRef): ' + e); - } - - if (recoveryMode) - return; - - warn('Indexing all PDF objects'); - return this.indexObjects(); - }, - getEntry: function XRef_getEntry(i) { - var e = this.entries[i]; - if (e === null) - return null; - return e.free ? null : e; // returns null is the entry is free - }, - fetchIfRef: function XRef_fetchIfRef(obj) { - if (!isRef(obj)) - return obj; - return this.fetch(obj); - }, - fetch: function XRef_fetch(ref, suppressEncryption) { - assertWellFormed(isRef(ref), 'ref object is not a reference'); - var num = ref.num; - if (num in this.cache) - return this.cache[num]; - - var e = this.getEntry(num); - - // the referenced entry can be free - if (e === null) - return (this.cache[num] = e); - - var gen = ref.gen; - var stream, parser; - if (e.uncompressed) { - if (e.gen != gen) - error('inconsistent generation in XRef'); - stream = this.stream.makeSubStream(e.offset); - parser = new Parser(new Lexer(stream), true, this); - var obj1 = parser.getObj(); - var obj2 = parser.getObj(); - var obj3 = parser.getObj(); - if (!isInt(obj1) || obj1 != num || - !isInt(obj2) || obj2 != gen || - !isCmd(obj3)) { - error('bad XRef entry'); - } - if (!isCmd(obj3, 'obj')) { - // some bad pdfs use "obj1234" and really mean 1234 - if (obj3.cmd.indexOf('obj') == 0) { - num = parseInt(obj3.cmd.substring(3), 10); - if (!isNaN(num)) - return num; - } - error('bad XRef entry'); - } - if (this.encrypt && !suppressEncryption) { - try { - e = parser.getObj(this.encrypt.createCipherTransform(num, gen)); - } catch (ex) { - // almost all streams must be encrypted, but sometimes - // they are not probably due to some broken generators - // re-trying without encryption - return this.fetch(ref, true); - } - } else { - e = parser.getObj(); - } - // Don't cache streams since they are mutable (except images). - if (!isStream(e) || e instanceof JpegStream) - this.cache[num] = e; - return e; - } - - // compressed entry - stream = this.fetch(new Ref(e.offset, 0)); - if (!isStream(stream)) - error('bad ObjStm stream'); - var first = stream.parameters.get('First'); - var n = stream.parameters.get('N'); - if (!isInt(first) || !isInt(n)) { - error('invalid first and n parameters for ObjStm stream'); - } - parser = new Parser(new Lexer(stream), false, this); - var i, entries = [], nums = []; - // read the object numbers to populate cache - for (i = 0; i < n; ++i) { - num = parser.getObj(); - if (!isInt(num)) { - error('invalid object number in the ObjStm stream: ' + num); - } - nums.push(num); - var offset = parser.getObj(); - if (!isInt(offset)) { - error('invalid object offset in the ObjStm stream: ' + offset); - } - } - // read stream objects for cache - for (i = 0; i < n; ++i) { - entries.push(parser.getObj()); - this.cache[nums[i]] = entries[i]; - } - e = entries[e.gen]; - if (!e) { - error('bad XRef entry for compressed object'); - } - return e; - }, - getCatalogObj: function XRef_getCatalogObj() { - return this.root; - } - }; - - return XRef; -})(); - -/** - * A PDF document and page is built of many objects. E.g. there are objects - * for fonts, images, rendering code and such. These objects might get processed - * inside of a worker. The `PDFObjects` implements some basic functions to - * manage these objects. - */ -var PDFObjects = (function PDFObjectsClosure() { - function PDFObjects() { - this.objs = {}; - } - - PDFObjects.prototype = { - objs: null, - - /** - * Internal function. - * Ensures there is an object defined for `objId`. Stores `data` on the - * object *if* it is created. - */ - ensureObj: function PDFObjects_ensureObj(objId, data) { - if (this.objs[objId]) - return this.objs[objId]; - return this.objs[objId] = new Promise(objId, data); - }, - - /** - * If called *without* callback, this returns the data of `objId` but the - * object needs to be resolved. If it isn't, this function throws. - * - * If called *with* a callback, the callback is called with the data of the - * object once the object is resolved. That means, if you call this - * function and the object is already resolved, the callback gets called - * right away. - */ - get: function PDFObjects_get(objId, callback) { - // If there is a callback, then the get can be async and the object is - // not required to be resolved right now - if (callback) { - this.ensureObj(objId).then(callback); - return null; - } - - // If there isn't a callback, the user expects to get the resolved data - // directly. - var obj = this.objs[objId]; - - // If there isn't an object yet or the object isn't resolved, then the - // data isn't ready yet! - if (!obj || !obj.isResolved) - error('Requesting object that isn\'t resolved yet ' + objId); - - return obj.data; - }, - - /** - * Resolves the object `objId` with optional `data`. - */ - resolve: function PDFObjects_resolve(objId, data) { - var objs = this.objs; - - // In case there is a promise already on this object, just resolve it. - if (objs[objId]) { - objs[objId].resolve(data); - } else { - this.ensureObj(objId, data); - } - }, - - onData: function PDFObjects_onData(objId, callback) { - this.ensureObj(objId).onData(callback); - }, - - isResolved: function PDFObjects_isResolved(objId) { - var objs = this.objs; - if (!objs[objId]) { - return false; - } else { - return objs[objId].isResolved; - } - }, - - hasData: function PDFObjects_hasData(objId) { - var objs = this.objs; - if (!objs[objId]) { - return false; - } else { - return objs[objId].hasData; - } - }, - - /** - * Sets the data of an object but *doesn't* resolve it. - */ - setData: function PDFObjects_setData(objId, data) { - // Watchout! If you call `this.ensureObj(objId, data)` you're going to - // create a *resolved* promise which shouldn't be the case! - this.ensureObj(objId).data = data; - } - }; - return PDFObjects; -})(); - - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var PDFFunction = (function PDFFunctionClosure() { - var CONSTRUCT_SAMPLED = 0; - var CONSTRUCT_INTERPOLATED = 2; - var CONSTRUCT_STICHED = 3; - var CONSTRUCT_POSTSCRIPT = 4; - - return { - getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps, - str) { - var length = 1; - for (var i = 0, ii = size.length; i < ii; i++) - length *= size[i]; - length *= outputSize; - - var array = []; - var codeSize = 0; - var codeBuf = 0; - // 32 is a valid bps so shifting won't work - var sampleMul = 1.0 / (Math.pow(2.0, bps) - 1); - - var strBytes = str.getBytes((length * bps + 7) / 8); - var strIdx = 0; - for (var i = 0; i < length; i++) { - while (codeSize < bps) { - codeBuf <<= 8; - codeBuf |= strBytes[strIdx++]; - codeSize += 8; - } - codeSize -= bps; - array.push((codeBuf >> codeSize) * sampleMul); - codeBuf &= (1 << codeSize) - 1; - } - return array; - }, - - getIR: function PDFFunction_getIR(xref, fn) { - var dict = fn.dict; - if (!dict) - dict = fn; - - var types = [this.constructSampled, - null, - this.constructInterpolated, - this.constructStiched, - this.constructPostScript]; - - var typeNum = dict.get('FunctionType'); - var typeFn = types[typeNum]; - if (!typeFn) - error('Unknown type of function'); - - return typeFn.call(this, fn, dict, xref); - }, - - fromIR: function PDFFunction_fromIR(IR) { - var type = IR[0]; - switch (type) { - case CONSTRUCT_SAMPLED: - return this.constructSampledFromIR(IR); - case CONSTRUCT_INTERPOLATED: - return this.constructInterpolatedFromIR(IR); - case CONSTRUCT_STICHED: - return this.constructStichedFromIR(IR); - case CONSTRUCT_POSTSCRIPT: - default: - return this.constructPostScriptFromIR(IR); - } - }, - - parse: function PDFFunction_parse(xref, fn) { - var IR = this.getIR(xref, fn); - return this.fromIR(IR); - }, - - constructSampled: function PDFFunction_constructSampled(str, dict) { - function toMultiArray(arr) { - var inputLength = arr.length; - var outputLength = arr.length / 2; - var out = []; - var index = 0; - for (var i = 0; i < inputLength; i += 2) { - out[index] = [arr[i], arr[i + 1]]; - ++index; - } - return out; - } - var domain = dict.get('Domain'); - var range = dict.get('Range'); - - if (!domain || !range) - error('No domain or range'); - - var inputSize = domain.length / 2; - var outputSize = range.length / 2; - - domain = toMultiArray(domain); - range = toMultiArray(range); - - var size = dict.get('Size'); - var bps = dict.get('BitsPerSample'); - var order = dict.get('Order'); - if (!order) - order = 1; - if (order !== 1) - error('No support for cubic spline interpolation: ' + order); - - var encode = dict.get('Encode'); - if (!encode) { - encode = []; - for (var i = 0; i < inputSize; ++i) { - encode.push(0); - encode.push(size[i] - 1); - } - } - encode = toMultiArray(encode); - - var decode = dict.get('Decode'); - if (!decode) - decode = range; - else - decode = toMultiArray(decode); - - var samples = this.getSampleArray(size, outputSize, bps, str); - - return [ - CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size, - outputSize, Math.pow(2, bps) - 1, range - ]; - }, - - constructSampledFromIR: function PDFFunction_constructSampledFromIR(IR) { - // See chapter 3, page 109 of the PDF reference - function interpolate(x, xmin, xmax, ymin, ymax) { - return ymin + ((x - xmin) * ((ymax - ymin) / (xmax - xmin))); - } - - return function constructSampledFromIRResult(args) { - // See chapter 3, page 110 of the PDF reference. - var m = IR[1]; - var domain = IR[2]; - var encode = IR[3]; - var decode = IR[4]; - var samples = IR[5]; - var size = IR[6]; - var n = IR[7]; - var mask = IR[8]; - var range = IR[9]; - - if (m != args.length) - error('Incorrect number of arguments: ' + inputSize + ' != ' + - args.length); - - var x = args; - - // Building the cube vertices: its part and sample index - // http://rjwagner49.com/Mathematics/Interpolation.pdf - var cubeVertices = 1 << m; - var cubeN = new Float64Array(cubeVertices); - var cubeVertex = new Uint32Array(cubeVertices); - for (var j = 0; j < cubeVertices; j++) - cubeN[j] = 1; - - var k = n, pos = 1; - // Map x_i to y_j for 0 <= i < m using the sampled function. - for (var i = 0; i < m; ++i) { - // x_i' = min(max(x_i, Domain_2i), Domain_2i+1) - var domain_2i = domain[i][0]; - var domain_2i_1 = domain[i][1]; - var xi = Math.min(Math.max(x[i], domain_2i), domain_2i_1); - - // e_i = Interpolate(x_i', Domain_2i, Domain_2i+1, - // Encode_2i, Encode_2i+1) - var e = interpolate(xi, domain_2i, domain_2i_1, - encode[i][0], encode[i][1]); - - // e_i' = min(max(e_i, 0), Size_i - 1) - var size_i = size[i]; - e = Math.min(Math.max(e, 0), size_i - 1); - - // Adjusting the cube: N and vertex sample index - var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1; - var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0); - var n1 = e - e0; // (e - e0) / (e1 - e0); - var offset0 = e0 * k; - var offset1 = offset0 + k; // e1 * k - for (var j = 0; j < cubeVertices; j++) { - if (j & pos) { - cubeN[j] *= n1; - cubeVertex[j] += offset1; - } else { - cubeN[j] *= n0; - cubeVertex[j] += offset0; - } - } - - k *= size_i; - pos <<= 1; - } - - var y = new Float64Array(n); - for (var j = 0; j < n; ++j) { - // Sum all cube vertices' samples portions - var rj = 0; - for (var i = 0; i < cubeVertices; i++) - rj += samples[cubeVertex[i] + j] * cubeN[i]; - - // r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1, - // Decode_2j, Decode_2j+1) - rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]); - - // y_j = min(max(r_j, range_2j), range_2j+1) - y[j] = Math.min(Math.max(rj, range[j][0]), range[j][1]); - } - - return y; - } - }, - - constructInterpolated: function PDFFunction_constructInterpolated(str, - dict) { - var c0 = dict.get('C0') || [0]; - var c1 = dict.get('C1') || [1]; - var n = dict.get('N'); - - if (!isArray(c0) || !isArray(c1)) - error('Illegal dictionary for interpolated function'); - - var length = c0.length; - var diff = []; - for (var i = 0; i < length; ++i) - diff.push(c1[i] - c0[i]); - - return [CONSTRUCT_INTERPOLATED, c0, diff, n]; - }, - - constructInterpolatedFromIR: - function PDFFunction_constructInterpolatedFromIR(IR) { - var c0 = IR[1]; - var diff = IR[2]; - var n = IR[3]; - - var length = diff.length; - - return function constructInterpolatedFromIRResult(args) { - var x = n == 1 ? args[0] : Math.pow(args[0], n); - - var out = []; - for (var j = 0; j < length; ++j) - out.push(c0[j] + (x * diff[j])); - - return out; - - } - }, - - constructStiched: function PDFFunction_constructStiched(fn, dict, xref) { - var domain = dict.get('Domain'); - - if (!domain) - error('No domain'); - - var inputSize = domain.length / 2; - if (inputSize != 1) - error('Bad domain for stiched function'); - - var fnRefs = dict.get('Functions'); - var fns = []; - for (var i = 0, ii = fnRefs.length; i < ii; ++i) - fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i]))); - - var bounds = dict.get('Bounds'); - var encode = dict.get('Encode'); - - return [CONSTRUCT_STICHED, domain, bounds, encode, fns]; - }, - - constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) { - var domain = IR[1]; - var bounds = IR[2]; - var encode = IR[3]; - var fnsIR = IR[4]; - var fns = []; - - for (var i = 0, ii = fnsIR.length; i < ii; i++) { - fns.push(PDFFunction.fromIR(fnsIR[i])); - } - - return function constructStichedFromIRResult(args) { - var clip = function constructStichedFromIRClip(v, min, max) { - if (v > max) - v = max; - else if (v < min) - v = min; - return v; - }; - - // clip to domain - var v = clip(args[0], domain[0], domain[1]); - // calulate which bound the value is in - for (var i = 0, ii = bounds.length; i < ii; ++i) { - if (v < bounds[i]) - break; - } - - // encode value into domain of function - var dmin = domain[0]; - if (i > 0) - dmin = bounds[i - 1]; - var dmax = domain[1]; - if (i < bounds.length) - dmax = bounds[i]; - - var rmin = encode[2 * i]; - var rmax = encode[2 * i + 1]; - - var v2 = rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin); - - // call the appropropriate function - return fns[i]([v2]); - }; - }, - - constructPostScript: function PDFFunction_constructPostScript(fn, dict, - xref) { - var domain = dict.get('Domain'); - var range = dict.get('Range'); - - if (!domain) - error('No domain.'); - - if (!range) - error('No range.'); - - var lexer = new PostScriptLexer(fn); - var parser = new PostScriptParser(lexer); - var code = parser.parse(); - - return [CONSTRUCT_POSTSCRIPT, domain, range, code]; - }, - - constructPostScriptFromIR: function PDFFunction_constructPostScriptFromIR( - IR) { - var domain = IR[1]; - var range = IR[2]; - var code = IR[3]; - var numOutputs = range.length / 2; - var evaluator = new PostScriptEvaluator(code); - // Cache the values for a big speed up, the cache size is limited though - // since the number of possible values can be huge from a PS function. - var cache = new FunctionCache(); - return function constructPostScriptFromIRResult(args) { - var initialStack = []; - for (var i = 0, ii = (domain.length / 2); i < ii; ++i) { - initialStack.push(args[i]); - } - - var key = initialStack.join('_'); - if (cache.has(key)) - return cache.get(key); - - var stack = evaluator.execute(initialStack); - var transformed = []; - for (i = numOutputs - 1; i >= 0; --i) { - var out = stack.pop(); - var rangeIndex = 2 * i; - if (out < range[rangeIndex]) - out = range[rangeIndex]; - else if (out > range[rangeIndex + 1]) - out = range[rangeIndex + 1]; - transformed[i] = out; - } - cache.set(key, transformed); - return transformed; - }; - } - }; -})(); - -var FunctionCache = (function FunctionCacheClosure() { - // Of 10 PDF's with type4 functions the maxium number of distinct values seen - // was 256. This still may need some tweaking in the future though. - var MAX_CACHE_SIZE = 1024; - function FunctionCache() { - this.cache = {}; - this.total = 0; - } - FunctionCache.prototype = { - has: function FunctionCache_has(key) { - return key in this.cache; - }, - get: function FunctionCache_get(key) { - return this.cache[key]; - }, - set: function FunctionCache_set(key, value) { - if (this.total < MAX_CACHE_SIZE) { - this.cache[key] = value; - this.total++; - } - } - }; - return FunctionCache; -})(); - -var PostScriptStack = (function PostScriptStackClosure() { - var MAX_STACK_SIZE = 100; - function PostScriptStack(initialStack) { - this.stack = initialStack || []; - } - - PostScriptStack.prototype = { - push: function PostScriptStack_push(value) { - if (this.stack.length >= MAX_STACK_SIZE) - error('PostScript function stack overflow.'); - this.stack.push(value); - }, - pop: function PostScriptStack_pop() { - if (this.stack.length <= 0) - error('PostScript function stack underflow.'); - return this.stack.pop(); - }, - copy: function PostScriptStack_copy(n) { - if (this.stack.length + n >= MAX_STACK_SIZE) - error('PostScript function stack overflow.'); - var stack = this.stack; - for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++) - stack.push(stack[i]); - }, - index: function PostScriptStack_index(n) { - this.push(this.stack[this.stack.length - n - 1]); - }, - // rotate the last n stack elements p times - roll: function PostScriptStack_roll(n, p) { - var stack = this.stack; - var l = stack.length - n; - var r = stack.length - 1, c = l + (p - Math.floor(p / n) * n), i, j, t; - for (i = l, j = r; i < j; i++, j--) { - t = stack[i]; stack[i] = stack[j]; stack[j] = t; - } - for (i = l, j = c - 1; i < j; i++, j--) { - t = stack[i]; stack[i] = stack[j]; stack[j] = t; - } - for (i = c, j = r; i < j; i++, j--) { - t = stack[i]; stack[i] = stack[j]; stack[j] = t; - } - } - }; - return PostScriptStack; -})(); -var PostScriptEvaluator = (function PostScriptEvaluatorClosure() { - function PostScriptEvaluator(operators, operands) { - this.operators = operators; - this.operands = operands; - } - PostScriptEvaluator.prototype = { - execute: function PostScriptEvaluator_execute(initialStack) { - var stack = new PostScriptStack(initialStack); - var counter = 0; - var operators = this.operators; - var length = operators.length; - var operator, a, b; - while (counter < length) { - operator = operators[counter++]; - if (typeof operator == 'number') { - // Operator is really an operand and should be pushed to the stack. - stack.push(operator); - continue; - } - switch (operator) { - // non standard ps operators - case 'jz': // jump if false - b = stack.pop(); - a = stack.pop(); - if (!a) - counter = b; - break; - case 'j': // jump - a = stack.pop(); - counter = a; - break; - - // all ps operators in alphabetical order (excluding if/ifelse) - case 'abs': - a = stack.pop(); - stack.push(Math.abs(a)); - break; - case 'add': - b = stack.pop(); - a = stack.pop(); - stack.push(a + b); - break; - case 'and': - b = stack.pop(); - a = stack.pop(); - if (isBool(a) && isBool(b)) - stack.push(a && b); - else - stack.push(a & b); - break; - case 'atan': - a = stack.pop(); - stack.push(Math.atan(a)); - break; - case 'bitshift': - b = stack.pop(); - a = stack.pop(); - if (a > 0) - stack.push(a << b); - else - stack.push(a >> b); - break; - case 'ceiling': - a = stack.pop(); - stack.push(Math.ceil(a)); - break; - case 'copy': - a = stack.pop(); - stack.copy(a); - break; - case 'cos': - a = stack.pop(); - stack.push(Math.cos(a)); - break; - case 'cvi': - a = stack.pop() | 0; - stack.push(a); - break; - case 'cvr': - // noop - break; - case 'div': - b = stack.pop(); - a = stack.pop(); - stack.push(a / b); - break; - case 'dup': - stack.copy(1); - break; - case 'eq': - b = stack.pop(); - a = stack.pop(); - stack.push(a == b); - break; - case 'exch': - stack.roll(2, 1); - break; - case 'exp': - b = stack.pop(); - a = stack.pop(); - stack.push(Math.pow(a, b)); - break; - case 'false': - stack.push(false); - break; - case 'floor': - a = stack.pop(); - stack.push(Math.floor(a)); - break; - case 'ge': - b = stack.pop(); - a = stack.pop(); - stack.push(a >= b); - break; - case 'gt': - b = stack.pop(); - a = stack.pop(); - stack.push(a > b); - break; - case 'idiv': - b = stack.pop(); - a = stack.pop(); - stack.push((a / b) | 0); - break; - case 'index': - a = stack.pop(); - stack.index(a); - break; - case 'le': - b = stack.pop(); - a = stack.pop(); - stack.push(a <= b); - break; - case 'ln': - a = stack.pop(); - stack.push(Math.log(a)); - break; - case 'log': - a = stack.pop(); - stack.push(Math.log(a) / Math.LN10); - break; - case 'lt': - b = stack.pop(); - a = stack.pop(); - stack.push(a < b); - break; - case 'mod': - b = stack.pop(); - a = stack.pop(); - stack.push(a % b); - break; - case 'mul': - b = stack.pop(); - a = stack.pop(); - stack.push(a * b); - break; - case 'ne': - b = stack.pop(); - a = stack.pop(); - stack.push(a != b); - break; - case 'neg': - a = stack.pop(); - stack.push(-b); - break; - case 'not': - a = stack.pop(); - if (isBool(a) && isBool(b)) - stack.push(a && b); - else - stack.push(a & b); - break; - case 'or': - b = stack.pop(); - a = stack.pop(); - if (isBool(a) && isBool(b)) - stack.push(a || b); - else - stack.push(a | b); - break; - case 'pop': - stack.pop(); - break; - case 'roll': - b = stack.pop(); - a = stack.pop(); - stack.roll(a, b); - break; - case 'round': - a = stack.pop(); - stack.push(Math.round(a)); - break; - case 'sin': - a = stack.pop(); - stack.push(Math.sin(a)); - break; - case 'sqrt': - a = stack.pop(); - stack.push(Math.sqrt(a)); - break; - case 'sub': - b = stack.pop(); - a = stack.pop(); - stack.push(a - b); - break; - case 'true': - stack.push(true); - break; - case 'truncate': - a = stack.pop(); - a = a < 0 ? Math.ceil(a) : Math.floor(a); - stack.push(a); - break; - case 'xor': - b = stack.pop(); - a = stack.pop(); - if (isBool(a) && isBool(b)) - stack.push(a != b); - else - stack.push(a ^ b); - break; - default: - error('Unknown operator ' + operator); - break; - } - } - return stack.stack; - } - }; - return PostScriptEvaluator; -})(); - -var PostScriptParser = (function PostScriptParserClosure() { - function PostScriptParser(lexer) { - this.lexer = lexer; - this.operators = []; - this.token; - this.prev; - } - PostScriptParser.prototype = { - nextToken: function PostScriptParser_nextToken() { - this.prev = this.token; - this.token = this.lexer.getToken(); - }, - accept: function PostScriptParser_accept(type) { - if (this.token.type == type) { - this.nextToken(); - return true; - } - return false; - }, - expect: function PostScriptParser_expect(type) { - if (this.accept(type)) - return true; - error('Unexpected symbol: found ' + this.token.type + ' expected ' + - type + '.'); - }, - parse: function PostScriptParser_parse() { - this.nextToken(); - this.expect(PostScriptTokenTypes.LBRACE); - this.parseBlock(); - this.expect(PostScriptTokenTypes.RBRACE); - return this.operators; - }, - parseBlock: function PostScriptParser_parseBlock() { - while (true) { - if (this.accept(PostScriptTokenTypes.NUMBER)) { - this.operators.push(this.prev.value); - } else if (this.accept(PostScriptTokenTypes.OPERATOR)) { - this.operators.push(this.prev.value); - } else if (this.accept(PostScriptTokenTypes.LBRACE)) { - this.parseCondition(); - } else { - return; - } - } - }, - parseCondition: function PostScriptParser_parseCondition() { - // Add two place holders that will be updated later - var conditionLocation = this.operators.length; - this.operators.push(null, null); - - this.parseBlock(); - this.expect(PostScriptTokenTypes.RBRACE); - if (this.accept(PostScriptTokenTypes.IF)) { - // The true block is right after the 'if' so it just falls through on - // true else it jumps and skips the true block. - this.operators[conditionLocation] = this.operators.length; - this.operators[conditionLocation + 1] = 'jz'; - } else if (this.accept(PostScriptTokenTypes.LBRACE)) { - var jumpLocation = this.operators.length; - this.operators.push(null, null); - var endOfTrue = this.operators.length; - this.parseBlock(); - this.expect(PostScriptTokenTypes.RBRACE); - this.expect(PostScriptTokenTypes.IFELSE); - // The jump is added at the end of the true block to skip the false - // block. - this.operators[jumpLocation] = this.operators.length; - this.operators[jumpLocation + 1] = 'j'; - - this.operators[conditionLocation] = endOfTrue; - this.operators[conditionLocation + 1] = 'jz'; - } else { - error('PS Function: error parsing conditional.'); - } - } - }; - return PostScriptParser; -})(); - -var PostScriptTokenTypes = { - LBRACE: 0, - RBRACE: 1, - NUMBER: 2, - OPERATOR: 3, - IF: 4, - IFELSE: 5 -}; - -var PostScriptToken = (function PostScriptTokenClosure() { - function PostScriptToken(type, value) { - this.type = type; - this.value = value; - } - - var opCache = {}; - - PostScriptToken.getOperator = function PostScriptToken_getOperator(op) { - var opValue = opCache[op]; - if (opValue) - return opValue; - - return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op); - }; - - PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE, - '{'); - PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE, - '}'); - PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF'); - PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE, - 'IFELSE'); - return PostScriptToken; -})(); - -var PostScriptLexer = (function PostScriptLexerClosure() { - function PostScriptLexer(stream) { - this.stream = stream; - } - PostScriptLexer.prototype = { - getToken: function PostScriptLexer_getToken() { - var s = ''; - var ch; - var comment = false; - var stream = this.stream; - - // skip comments - while (true) { - if (!(ch = stream.getChar())) - return EOF; - - if (comment) { - if (ch == '\x0a' || ch == '\x0d') - comment = false; - } else if (ch == '%') { - comment = true; - } else if (!Lexer.isSpace(ch)) { - break; - } - } - switch (ch) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '+': case '-': case '.': - return new PostScriptToken(PostScriptTokenTypes.NUMBER, - this.getNumber(ch)); - case '{': - return PostScriptToken.LBRACE; - case '}': - return PostScriptToken.RBRACE; - } - // operator - var str = ch.toLowerCase(); - while (true) { - ch = stream.lookChar(); - if (ch === null) - break; - ch = ch.toLowerCase(); - if (ch >= 'a' && ch <= 'z') - str += ch; - else - break; - stream.skip(); - } - switch (str) { - case 'if': - return PostScriptToken.IF; - case 'ifelse': - return PostScriptToken.IFELSE; - default: - return PostScriptToken.getOperator(str); - } - }, - getNumber: function PostScriptLexer_getNumber(ch) { - var str = ch; - var stream = this.stream; - while (true) { - ch = stream.lookChar(); - if ((ch >= '0' && ch <= '9') || ch == '-' || ch == '.') - str += ch; - else - break; - stream.skip(); - } - var value = parseFloat(str); - if (isNaN(value)) - error('Invalid floating point number: ' + value); - return value; - } - }; - return PostScriptLexer; -})(); - - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var ISOAdobeCharset = [ - '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', - 'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright', - 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', - 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', - 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', - 'at', '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', - 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', - 'quoteleft', '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', - 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', - 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', - 'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft', - 'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl', - 'periodcentered', 'paragraph', 'bullet', 'quotesinglbase', - 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', - 'perthousand', 'questiondown', 'grave', 'acute', 'circumflex', 'tilde', - 'macron', 'breve', 'dotaccent', 'dieresis', 'ring', 'cedilla', - 'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine', - 'Lslash', 'Oslash', 'OE', 'ordmasculine', 'ae', 'dotlessi', 'lslash', - 'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu', - 'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter', - 'divide', 'brokenbar', 'degree', 'thorn', 'threequarters', 'twosuperior', - 'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright', - 'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde', - 'Ccedilla', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', 'Iacute', - 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex', - 'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex', - 'Udieresis', 'Ugrave', 'Yacute', 'Ydieresis', 'Zcaron', 'aacute', - 'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', 'ccedilla', - 'eacute', 'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex', - 'idieresis', 'igrave', 'ntilde', 'oacute', 'ocircumflex', 'odieresis', - 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', - 'ugrave', 'yacute', 'ydieresis', 'zcaron' -]; - -var ExpertCharset = [ - '.notdef', 'space', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', - 'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', - 'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma', - 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', - 'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', - 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', - 'colon', 'semicolon', 'commasuperior', 'threequartersemdash', - 'periodsuperior', 'questionsmall', 'asuperior', 'bsuperior', - 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', - 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', - 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', - 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', - 'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', - 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', - 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', - 'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', - 'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall', 'centoldstyle', - 'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', - 'Brevesmall', 'Caronsmall', 'Dotaccentsmall', 'Macronsmall', - 'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall', - 'Cedillasmall', 'onequarter', 'onehalf', 'threequarters', - 'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', - 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', - 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', - 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', - 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', - 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', - 'periodinferior', 'commainferior', 'Agravesmall', 'Aacutesmall', - 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall', - 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall', - 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall', - 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', - 'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall', - 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall', - 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', - 'Ydieresissmall' -]; - -var ExpertSubsetCharset = [ - '.notdef', 'space', 'dollaroldstyle', 'dollarsuperior', - 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', - 'onedotenleader', 'comma', 'hyphen', 'period', 'fraction', - 'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle', - 'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', - 'eightoldstyle', 'nineoldstyle', 'colon', 'semicolon', 'commasuperior', - 'threequartersemdash', 'periodsuperior', 'asuperior', 'bsuperior', - 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', - 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', - 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', - 'parenrightinferior', 'hyphensuperior', 'colonmonetary', 'onefitted', - 'rupiah', 'centoldstyle', 'figuredash', 'hypheninferior', 'onequarter', - 'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', - 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', - 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', - 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', - 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', - 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', - 'periodinferior', 'commainferior' -]; - - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var CIDToUnicodeMaps = { - 'Adobe-Japan1': [[32, 160], {f: 12, c: 33}, [45, 8209], {f: 46, c: 46}, 165, - {f: 2, c: 93}, [95, 818], [96, 768], {f: 27, c: 97}, 166, 125, [732, 771], - [700, 8217], 92, [699, 8216], 124, [126, 8764], {f: 3, c: 161}, 8260, 402, - 0, 164, 8220, 171, {f: 2, c: 8249}, {f: 2, c: 64257}, [8210, 8211], 0, 0, - [183, 8729], 0, 8226, 8218, 8222, 8221, 187, 0, 0, 191, {f: 2, c: 769}, - [175, 772], {f: 3, c: 774}, 778, [184, 807], 779, 808, 780, [822, 8212], - 198, 170, 321, 216, 338, 186, 230, 305, 322, 248, 339, 223, 173, 169, 172, - 174, 0, 0, {f: 2, c: 178}, 181, 185, {f: 3, c: 188}, {f: 6, c: 192}, - {f: 16, c: 199}, 0, {f: 6, c: 217}, {f: 6, c: 224}, {f: 16, c: 231}, 0, - {f: 7, c: 249}, 352, 376, 381, [773, 8254], 353, 8482, 382, 0, 8194, - {s: 91}, 65512, {s: 3}, {f: 63, c: 65377}, {s: 243}, [8195, 12288], - {f: 2, c: 12289}, 65292, 65294, 12539, {f: 2, c: 65306}, 65311, 65281, - {f: 2, c: 12443}, 180, 65344, 168, 65342, 65507, 65343, {f: 2, c: 12541}, - {f: 2, c: 12445}, 12291, 20189, {f: 3, c: 12293}, 12540, 8213, 8208, 65295, - 65340, [12316, 65374], 8214, 65372, 8230, 8229, {s: 4}, {f: 2, c: 65288}, - {f: 2, c: 12308}, 65339, 65341, 65371, 65373, {f: 10, c: 12296}, 65291, - [8722, 65293], 177, 215, 247, 65309, 8800, 65308, 65310, {f: 2, c: 8806}, - 8734, 8756, 9794, 9792, 176, {f: 2, c: 8242}, 8451, 65509, 65284, - {f: 2, c: 65504}, 65285, 65283, 65286, 65290, 65312, 167, 9734, 9733, 9675, - 9679, 9678, 9671, 9670, 9633, 9632, 9651, 9650, 9661, 9660, 8251, 12306, - 8594, {f: 2, c: 8592}, 8595, 12307, 8712, 8715, {f: 2, c: 8838}, - {f: 2, c: 8834}, 8746, 8745, {f: 2, c: 8743}, 65506, 8658, 8660, 8704, - 8707, 8736, 8869, 8978, 8706, 8711, 8801, 8786, {f: 2, c: 8810}, 8730, - 8765, 8733, 8757, {f: 2, c: 8747}, 8491, 8240, 9839, 9837, 9834, - {f: 2, c: 8224}, 182, 9711, {f: 10, c: 65296}, {f: 26, c: 65313}, - {f: 26, c: 65345}, {f: 83, c: 12353}, {f: 86, c: 12449}, {f: 17, c: 913}, - {f: 7, c: 931}, {f: 17, c: 945}, {f: 7, c: 963}, {f: 6, c: 1040}, 1025, - {f: 32, c: 1046}, 1105, {f: 26, c: 1078}, 20124, 21782, 23043, 38463, - 21696, 24859, 25384, 23030, 36898, 33909, 33564, 31312, 24746, 25569, - 28197, 26093, 33894, 33446, 39925, 26771, 22311, 26017, 25201, 23451, - 22992, 34427, 39156, 32098, 32190, 39822, 25110, 31903, 34999, 23433, - 24245, 25353, 26263, 26696, 38343, 38797, 26447, 20197, 20234, 20301, - 20381, 20553, 22258, 22839, 22996, 23041, 23561, 24799, 24847, 24944, - 26131, 26885, 28858, 30031, 30064, 31227, 32173, 32239, 32963, 33806, - [12176, 34915], 35586, 36949, 36986, 21307, 20117, 20133, 22495, 32946, - 37057, 30959, [12032, 19968], 22769, 28322, 36920, 31282, 33576, 33419, - 39983, 20801, 21360, 21693, 21729, 22240, 23035, 24341, 39154, 28139, - 32996, 34093, 38498, 38512, 38560, 38907, 21515, 21491, 23431, 28879, - [12155, 32701], 36802, [12204, 38632], 21359, 40284, 31418, 19985, 30867, - [12165, 33276], 28198, 22040, 21764, 27421, 34074, 39995, 23013, 21417, - 28006, [12128, 29916], 38287, 22082, 20113, 36939, 38642, 33615, 39180, - 21473, 21942, 23344, 24433, 26144, 26355, 26628, 27704, 27891, 27945, - 29787, 30408, 31310, 38964, 33521, 34907, 35424, 37613, 28082, 30123, - 30410, 39365, 24742, 35585, 36234, 38322, 27022, 21421, 20870, 22290, - 22576, 22852, 23476, 24310, 24616, 25513, 25588, 27839, 28436, 28814, - 28948, 29017, 29141, 29503, 32257, 33398, 33489, 34199, 36960, 37467, - 40219, 22633, 26044, 27738, 29989, 20985, 22830, 22885, 24448, 24540, - 25276, 26106, 27178, 27431, 27572, 29579, 32705, 35158, 40236, 40206, - [12009, 40644], 23713, 27798, 33659, 20740, 23627, 25014, 33222, 26742, - 29281, [12036, 20057], 20474, 21368, 24681, 28201, 31311, [12211, 38899], - 19979, 21270, 20206, 20309, 20285, 20385, 20339, 21152, 21487, 22025, - 22799, 23233, 23478, 23521, 31185, 26247, 26524, 26550, 27468, 27827, - [12117, 28779], 29634, 31117, [12146, 31166], 31292, 31623, 33457, 33499, - 33540, 33655, 33775, 33747, 34662, 35506, 22057, 36008, 36838, 36942, - 38686, 34442, 20420, 23784, 25105, [12123, 29273], 30011, 33253, 33469, - 34558, 36032, 38597, 39187, 39381, 20171, 20250, 35299, 22238, 22602, - 22730, 24315, 24555, 24618, 24724, 24674, 25040, 25106, 25296, 25913, - 39745, 26214, 26800, 28023, 28784, 30028, 30342, 32117, 33445, 34809, - 38283, 38542, [12185, 35997], 20977, 21182, 22806, 21683, 23475, 23830, - 24936, 27010, 28079, 30861, 33995, 34903, 35442, 37799, 39608, 28012, - 39336, 34521, 22435, 26623, 34510, 37390, 21123, 22151, 21508, 24275, - 25313, 25785, 26684, 26680, 27579, 29554, 30906, 31339, 35226, - [12179, 35282], 36203, 36611, 37101, 38307, 38548, [12208, 38761], 23398, - 23731, 27005, {f: 2, c: 38989}, 25499, 31520, 27179, 27263, 26806, 39949, - 28511, 21106, 21917, 24688, 25324, 27963, 28167, 28369, 33883, 35088, - 36676, 19988, 39993, 21494, 26907, 27194, 38788, 26666, 20828, 31427, - 33970, 37340, 37772, 22107, 40232, 26658, 33541, 33841, 31909, 21000, - 33477, [12129, 29926], 20094, 20355, 20896, 23506, 21002, 21208, 21223, - 24059, 21914, 22570, 23014, 23436, 23448, 23515, [12082, 24178], 24185, - 24739, 24863, 24931, 25022, 25563, 25954, 26577, 26707, 26874, 27454, - 27475, 27735, 28450, 28567, 28485, 29872, [12130, 29976], 30435, 30475, - 31487, 31649, 31777, 32233, [12152, 32566], 32752, 32925, 33382, 33694, - 35251, 35532, 36011, 36996, 37969, 38291, 38289, 38306, 38501, 38867, - 39208, 33304, 20024, 21547, 23736, 24012, 29609, 30284, 30524, 23721, - 32747, 36107, 38593, 38929, 38996, 39000, 20225, 20238, 21361, 21916, - 22120, 22522, 22855, 23305, 23492, 23696, 24076, 24190, 24524, 25582, - 26426, 26071, 26082, 26399, 26827, 26820, 27231, 24112, 27589, 27671, - 27773, 30079, 31048, 23395, 31232, 32000, 24509, 35215, 35352, 36020, - 36215, 36556, 36637, 39138, 39438, [12004, 12225, 39740], [12018, 20096], - 20605, 20736, 22931, 23452, 25135, 25216, 25836, 27450, 29344, 30097, - 31047, 32681, 34811, 35516, 35696, 25516, 33738, 38816, 21513, 21507, - 21931, 26708, 27224, 35440, 30759, 26485, [12233, 40653], 21364, 23458, - 33050, 34384, 36870, 19992, 20037, 20167, 20241, 21450, 21560, 23470, - [12088, 24339], 24613, 25937, 26429, 27714, 27762, 27875, 28792, 29699, - 31350, 31406, 31496, 32026, 31998, 32102, 26087, [12124, 29275], 21435, - 23621, 24040, 25298, 25312, 25369, 28192, 34394, 35377, 36317, 37624, - 28417, 31142, [12226, 39770], 20136, {f: 2, c: 20139}, 20379, 20384, 20689, - 20807, 31478, 20849, 20982, 21332, 21281, 21375, 21483, 21932, 22659, - 23777, 24375, 24394, 24623, 24656, 24685, 25375, 25945, 27211, 27841, - 29378, 29421, 30703, 33016, 33029, 33288, 34126, 37111, 37857, 38911, - 39255, 39514, 20208, 20957, 23597, 26241, 26989, 23616, 26354, 26997, - [12127, 29577], 26704, 31873, 20677, 21220, 22343, [12081, 24062], 37670, - [12100, 26020], 27427, 27453, 29748, 31105, 31165, 31563, 32202, 33465, - 33740, 34943, 35167, 35641, 36817, [12198, 37329], 21535, 37504, 20061, - 20534, 21477, 21306, 29399, 29590, 30697, 33510, 36527, 39366, 39368, - 39378, 20855, 24858, 34398, 21936, 31354, 20598, 23507, 36935, 38533, - 20018, 27355, 37351, 23633, 23624, 25496, 31391, 27795, 38772, 36705, - 31402, 29066, 38536, 31874, 26647, 32368, 26705, 37740, 21234, 21531, - 34219, 35347, 32676, 36557, 37089, 21350, 34952, 31041, 20418, 20670, - 21009, 20804, 21843, 22317, 29674, 22411, 22865, 24418, 24452, 24693, - 24950, 24935, 25001, 25522, 25658, 25964, 26223, 26690, 28179, 30054, - 31293, 31995, 32076, 32153, 32331, 32619, 33550, 33610, 34509, 35336, - 35427, 35686, 36605, 38938, 40335, 33464, 36814, 39912, 21127, 25119, - 25731, 28608, 38553, 26689, 20625, [12107, 27424], 27770, 28500, - [12147, 31348], 32080, [12174, 34880], 35363, [12105, 26376], 20214, 20537, - 20518, 20581, 20860, 21048, 21091, 21927, 22287, 22533, 23244, 24314, - 25010, 25080, 25331, 25458, 26908, 27177, 29309, [12125, 29356], 29486, - 30740, 30831, 32121, 30476, 32937, [12178, 35211], 35609, 36066, 36562, - 36963, 37749, 38522, 38997, 39443, 40568, 20803, 21407, 21427, 24187, - 24358, 28187, 28304, [12126, 29572], 29694, 32067, 33335, [12180, 35328], - 35578, 38480, 20046, 20491, 21476, 21628, 22266, 22993, 23396, - [12080, 24049], 24235, 24359, [12094, 25144], 25925, 26543, 28246, 29392, - 31946, 34996, 32929, 32993, 33776, [11969, 34382], 35463, 36328, 37431, - 38599, 39015, [12238, 40723], 20116, 20114, 20237, 21320, 21577, 21566, - 23087, 24460, 24481, 24735, 26791, 27278, 29786, 30849, 35486, 35492, - 35703, 37264, 20062, 39881, 20132, 20348, 20399, 20505, 20502, 20809, - 20844, 21151, 21177, 21246, 21402, [12061, 21475], 21521, 21518, 21897, - 22353, 22434, 22909, 23380, 23389, 23439, [12079, 24037], 24039, 24055, - 24184, 24195, 24218, 24247, 24344, 24658, 24908, 25239, 25304, 25511, - 25915, 26114, 26179, 26356, 26477, 26657, 26775, 27083, 27743, 27946, - 28009, 28207, 28317, 30002, 30343, 30828, 31295, 31968, 32005, 32024, - 32094, 32177, 32789, 32771, 32943, 32945, 33108, 33167, 33322, 33618, - [12175, 34892], 34913, 35611, 36002, 36092, 37066, 37237, 37489, 30783, - 37628, 38308, 38477, 38917, [12217, 39321], [12220, 39640], 40251, 21083, - 21163, 21495, 21512, 22741, 25335, 28640, 35946, 36703, 40633, 20811, - 21051, 21578, 22269, 31296, 37239, 40288, [12234, 40658], 29508, 28425, - 33136, 29969, 24573, 24794, [12219, 39592], 29403, 36796, 27492, 38915, - 20170, 22256, 22372, 22718, 23130, 24680, 25031, 26127, 26118, 26681, - 26801, 28151, 30165, 32058, [12169, 33390], 39746, 20123, 20304, 21449, - 21766, 23919, 24038, 24046, 26619, 27801, 29811, 30722, 35408, 37782, - 35039, 22352, 24231, 25387, 20661, 20652, 20877, 26368, 21705, 22622, - 22971, 23472, 24425, 25165, 25505, 26685, 27507, 28168, 28797, 37319, - 29312, 30741, 30758, 31085, 25998, 32048, 33756, 35009, 36617, 38555, - 21092, 22312, 26448, 32618, 36001, 20916, 22338, 38442, 22586, 27018, - 32948, 21682, 23822, 22524, 30869, 40442, 20316, 21066, 21643, 25662, - 26152, 26388, 26613, 31364, 31574, 32034, 37679, 26716, 39853, 31545, - 21273, 20874, 21047, 23519, 25334, 25774, 25830, 26413, 27578, 34217, - 38609, 30352, 39894, 25420, 37638, 39851, [12139, 30399], 26194, 19977, - 20632, 21442, [12077, 23665], 24808, 25746, 25955, 26719, 29158, 29642, - 29987, 31639, 32386, 34453, 35715, 36059, 37240, 39184, 26028, 26283, - 27531, 20181, 20180, 20282, 20351, 21050, 21496, 21490, 21987, 22235, - [12064, 22763], 22987, 22985, 23039, [12070, 23376], 23629, 24066, 24107, - 24535, 24605, 25351, [12096, 25903], 23388, 26031, 26045, 26088, 26525, - [12108, 27490], 27515, [12114, 27663], 29509, 31049, 31169, [12151, 31992], - 32025, 32043, 32930, 33026, [12164, 33267], 35222, 35422, 35433, 35430, - 35468, 35566, 36039, 36060, 38604, 39164, [12013, 27503], 20107, 20284, - 20365, 20816, 23383, 23546, 24904, 25345, 26178, 27425, 28363, 27835, - 29246, 29885, 30164, 30913, [12144, 31034], [12157, 32780], [12159, 32819], - [12163, 33258], 33940, 36766, 27728, [12229, 40575], 24335, 35672, 40235, - 31482, 36600, 23437, 38635, 19971, 21489, 22519, 22833, 23241, 23460, - 24713, 28287, 28422, 30142, 36074, 23455, 34048, 31712, 20594, 26612, - 33437, 23649, 34122, 32286, 33294, 20889, 23556, 25448, 36198, 26012, - 29038, 31038, 32023, 32773, 35613, [12190, 36554], 36974, 34503, 37034, - 20511, 21242, 23610, 26451, 28796, 29237, 37196, 37320, 37675, 33509, - 23490, 24369, 24825, 20027, 21462, 23432, [12095, 25163], 26417, 27530, - 29417, 29664, 31278, 33131, 36259, 37202, [12216, 39318], 20754, 21463, - 21610, 23551, 25480, 27193, 32172, 38656, 22234, 21454, 21608, 23447, - 23601, 24030, 20462, 24833, 25342, 27954, 31168, 31179, 32066, 32333, - 32722, 33261, [12168, 33311], 33936, 34886, 35186, 35728, 36468, 36655, - 36913, 37195, 37228, 38598, 37276, 20160, 20303, 20805, [12055, 21313], - 24467, 25102, 26580, 27713, 28171, 29539, 32294, 37325, 37507, 21460, - 22809, 23487, 28113, 31069, 32302, 31899, 22654, 29087, 20986, 34899, - 36848, 20426, 23803, 26149, 30636, 31459, 33308, 39423, 20934, 24490, - 26092, 26991, 27529, 28147, 28310, 28516, 30462, 32020, 24033, 36981, - 37255, 38918, 20966, 21021, 25152, 26257, 26329, 28186, 24246, 32210, - 32626, 26360, 34223, 34295, 35576, 21161, 21465, [12069, 22899], 24207, - 24464, 24661, 37604, 38500, 20663, 20767, 21213, 21280, 21319, 21484, - 21736, 21830, 21809, 22039, 22888, 22974, 23100, 23477, 23558, - [12073, 23567], 23569, 23578, 24196, 24202, 24288, 24432, 25215, 25220, - 25307, 25484, 25463, 26119, 26124, 26157, 26230, 26494, 26786, 27167, - 27189, 27836, 28040, 28169, 28248, 28988, 28966, 29031, 30151, 30465, - 30813, 30977, 31077, 31216, 31456, 31505, 31911, 32057, 32918, 33750, - 33931, 34121, 34909, 35059, 35359, 35388, 35412, 35443, 35937, 36062, - 37284, 37478, 37758, 37912, 38556, 38808, 19978, 19976, 19998, 20055, - 20887, 21104, 22478, 22580, 22732, 23330, 24120, 24773, 25854, 26465, - 26454, 27972, 29366, 30067, 31331, 33976, 35698, 37304, 37664, 22065, - 22516, 39166, 25325, 26893, 27542, 29165, 32340, 32887, [12170, 33394], - 35302, [12215, 39135], 34645, 36785, 23611, 20280, 20449, 20405, 21767, - 23072, 23517, 23529, [12092, 24515], 24910, 25391, 26032, 26187, 26862, - 27035, 28024, 28145, 30003, 30137, 30495, 31070, 31206, 32051, - [12162, 33251], 33455, 34218, 35242, 35386, [12189, 36523], [12191, 36763], - 36914, 37341, 38663, [12040, 20154], 20161, 20995, 22645, 22764, 23563, - 29978, 23613, 33102, 35338, 36805, 38499, 38765, 31525, 35535, 38920, - 37218, 22259, 21416, 36887, 21561, 22402, 24101, 25512, [12116, 27700], - 28810, 30561, 31883, 32736, 34928, 36930, 37204, 37648, 37656, 38543, - 29790, 39620, 23815, 23913, 25968, 26530, 36264, 38619, 25454, 26441, - 26905, 33733, 38935, 38592, 35070, 28548, 25722, [12072, 23544], 19990, - 28716, 30045, 26159, 20932, 21046, 21218, 22995, 24449, 24615, 25104, - 25919, 25972, 26143, 26228, 26866, 26646, 27491, 28165, 29298, - [12131, 29983], 30427, 31934, 32854, 22768, 35069, [11972, 35199], 35488, - 35475, 35531, 36893, 37266, [11992, 38738], 38745, [12011, 25993], 31246, - 33030, 38587, 24109, 24796, 25114, 26021, 26132, 26512, [12143, 30707], - 31309, 31821, 32318, 33034, 36012, [12186, 36196], 36321, 36447, 30889, - 20999, 25305, 25509, 25666, 25240, 35373, 31363, 31680, 35500, 38634, - 32118, [12166, 33292], 34633, 20185, 20808, 21315, 21344, 23459, 23554, - 23574, 24029, 25126, 25159, 25776, 26643, 26676, 27849, 27973, 27927, - 26579, 28508, 29006, 29053, 26059, 31359, 31661, 32218, 32330, 32680, - 33146, [12167, 33307], 33337, 34214, 35438, 36046, 36341, 36984, 36983, - 37549, 37521, 38275, 39854, 21069, 21892, 28472, 28982, 20840, 31109, - 32341, 33203, 31950, 22092, 22609, 23720, 25514, 26366, 26365, 26970, - 29401, 30095, 30094, 30990, 31062, 31199, 31895, 32032, 32068, 34311, - 35380, 38459, 36961, [12239, 40736], 20711, 21109, 21452, 21474, 20489, - 21930, 22766, 22863, 29245, 23435, 23652, 21277, 24803, 24819, 25436, - 25475, 25407, 25531, 25805, 26089, 26361, 24035, 27085, 27133, 28437, - 29157, 20105, 30185, 30456, 31379, 31967, 32207, 32156, 32865, 33609, - 33624, 33900, 33980, 34299, 35013, [12187, 36208], 36865, 36973, 37783, - 38684, 39442, 20687, 22679, 24974, 33235, 34101, 36104, 36896, 20419, - 20596, 21063, 21363, 24687, 25417, 26463, 28204, [12188, 36275], 36895, - 20439, 23646, 36042, 26063, 32154, 21330, 34966, 20854, 25539, 23384, - 23403, 23562, 25613, 26449, 36956, 20182, 22810, 22826, 27760, 35409, - 21822, 22549, 22949, 24816, 25171, 26561, 33333, 26965, 38464, 39364, - 39464, 20307, 22534, 23550, 32784, 23729, 24111, 24453, 24608, 24907, - 25140, 26367, 27888, 28382, 32974, 33151, 33492, 34955, 36024, 36864, - 36910, 38538, 40667, 39899, 20195, 21488, [12068, 22823], 31532, 37261, - 38988, 40441, 28381, 28711, 21331, 21828, 23429, 25176, 25246, 25299, - 27810, 28655, 29730, 35351, 37944, 28609, 35582, 33592, 20967, 34552, - 21482, 21481, 20294, 36948, [12192, 36784], 22890, 33073, 24061, 31466, - 36799, 26842, [12181, 35895], 29432, 40008, 27197, 35504, 20025, 21336, - 22022, 22374, 25285, 25506, 26086, 27470, 28129, 28251, 28845, 30701, - 31471, 31658, 32187, 32829, 32966, 34507, 35477, 37723, 22243, 22727, - 24382, 26029, 26262, 27264, 27573, 30007, 35527, 20516, 30693, 22320, - 24347, 24677, 26234, 27744, 30196, 31258, 32622, 33268, 34584, 36933, - 39347, 31689, 30044, [12149, 31481], 31569, 33988, 36880, 31209, 31378, - 33590, 23265, 30528, 20013, 20210, 23449, 24544, 25277, 26172, 26609, - 27880, [12173, 34411], 34935, 35387, 37198, 37619, 39376, 27159, 28710, - 29482, 33511, 33879, 36015, 19969, 20806, 20939, 21899, 23541, 24086, - 24115, 24193, 24340, 24373, 24427, 24500, 25074, 25361, 26274, 26397, - 28526, 29266, 30010, 30522, 32884, 33081, 33144, 34678, 35519, 35548, - 36229, 36339, 37530, [11985, 12199, 38263], 38914, [12227, 40165], 21189, - 25431, 30452, 26389, 27784, 29645, 36035, 37806, 38515, 27941, 22684, - 26894, 27084, 36861, 37786, 30171, 36890, 22618, 26626, 25524, 27131, - 20291, 28460, 26584, 36795, 34086, 32180, 37716, 26943, 28528, 22378, - 22775, 23340, 32044, [12118, 29226], 21514, 37347, 40372, 20141, 20302, - 20572, 20597, 21059, 35998, 21576, 22564, 23450, 24093, 24213, 24237, - 24311, 24351, 24716, 25269, 25402, 25552, 26799, 27712, 30855, 31118, - 31243, 32224, 33351, 35330, 35558, 36420, 36883, 37048, 37165, 37336, - [12237, 40718], 27877, 25688, 25826, 25973, 28404, 30340, 31515, 36969, - 37841, 28346, 21746, 24505, 25764, 36685, 36845, 37444, 20856, 22635, - 22825, 23637, 24215, 28155, 32399, 29980, 36028, 36578, 39003, 28857, - 20253, 27583, 28593, [12133, 30000], 38651, 20814, 21520, 22581, 22615, - 22956, 23648, 24466, [12099, 26007], 26460, 28193, 30331, 33759, 36077, - 36884, 37117, 37709, 30757, 30778, 21162, 24230, [12063, 22303], 22900, - 24594, 20498, 20826, 20908, 20941, [12049, 20992], 21776, 22612, 22616, - 22871, 23445, 23798, 23947, 24764, 25237, 25645, 26481, 26691, 26812, - 26847, 30423, 28120, 28271, 28059, 28783, 29128, 24403, 30168, 31095, - 31561, 31572, 31570, 31958, 32113, 21040, 33891, 34153, 34276, 35342, - 35588, [12182, 35910], 36367, 36867, 36879, 37913, 38518, 38957, 39472, - 38360, 20685, 21205, 21516, 22530, 23566, 24999, 25758, 27934, 30643, - 31461, 33012, 33796, 36947, 37509, 23776, 40199, 21311, 24471, 24499, - 28060, 29305, 30563, 31167, 31716, 27602, 29420, 35501, 26627, 27233, - 20984, 31361, 26932, 23626, 40182, 33515, 23493, [12195, 37193], 28702, - 22136, 23663, 24775, 25958, 27788, 35930, 36929, 38931, 21585, 26311, - 37389, 22856, 37027, 20869, 20045, 20970, 34201, 35598, 28760, 25466, - 37707, 26978, 39348, 32260, 30071, 21335, 26976, 36575, 38627, 27741, - [12038, 20108], 23612, 24336, 36841, 21250, 36049, [12161, 32905], 34425, - 24319, [12103, 26085], 20083, [12042, 20837], 22914, 23615, 38894, 20219, - 22922, 24525, 35469, 28641, 31152, 31074, 23527, 33905, 29483, 29105, - 24180, 24565, 25467, 25754, 29123, 31896, 20035, 24316, 20043, 22492, - 22178, 24745, 28611, 32013, 33021, 33075, 33215, 36786, 35223, 34468, - 24052, 25226, 25773, 35207, 26487, 27874, 27966, 29750, 30772, 23110, - 32629, 33453, [12218, 39340], 20467, 24259, 25309, 25490, 25943, 26479, - 30403, 29260, 32972, 32954, 36649, 37197, 20493, 22521, 23186, 26757, - 26995, 29028, 29437, 36023, 22770, 36064, 38506, 36889, 34687, 31204, - 30695, 33833, 20271, 21093, 21338, 25293, 26575, 27850, [12137, 30333], - 31636, 31893, 33334, 34180, 36843, 26333, 28448, 29190, 32283, 33707, - 39361, [12008, 40614], 20989, 31665, 30834, 31672, 32903, 31560, 27368, - 24161, 32908, 30033, 30048, [12043, 20843], 37474, 28300, 30330, 37271, - 39658, 20240, 32624, 25244, 31567, 38309, 40169, 22138, 22617, 34532, - 38588, 20276, 21028, 21322, 21453, 21467, 24070, 25644, 26001, 26495, - 27710, 27726, 29256, 29359, 29677, 30036, 32321, 33324, 34281, 36009, - 31684, [12196, 37318], 29033, 38930, 39151, 25405, 26217, 30058, 30436, - 30928, 34115, 34542, 21290, 21329, 21542, 22915, 24199, 24444, 24754, - 25161, 25209, 25259, 26000, [12112, 27604], 27852, 30130, [12138, 30382], - 30865, 31192, 32203, 32631, 32933, 34987, 35513, 36027, 36991, - [12206, 38750], [12214, 39131], 27147, 31800, 20633, 23614, 24494, 26503, - 27608, 29749, 30473, 32654, [12240, 40763], 26570, 31255, 21305, - [12134, 30091], 39661, 24422, 33181, 33777, 32920, 24380, 24517, 30050, - 31558, 36924, 26727, 23019, 23195, 32016, 30334, 35628, 20469, 24426, - 27161, 27703, 28418, 29922, 31080, 34920, 35413, 35961, 24287, 25551, - 30149, 31186, 33495, 37672, 37618, 33948, 34541, 39981, 21697, 24428, - 25996, 27996, 28693, 36007, 36051, 38971, 25935, 29942, 19981, 20184, - 22496, 22827, 23142, 23500, 20904, 24067, 24220, 24598, 25206, 25975, - 26023, 26222, 28014, [12119, 29238], 31526, 33104, 33178, 33433, 35676, - 36000, 36070, 36212, [12201, 38428], 38468, 20398, 25771, 27494, 33310, - 33889, 34154, 37096, 23553, 26963, [12213, 39080], 33914, 34135, 20239, - 21103, 24489, 24133, 26381, 31119, 33145, 35079, 35206, 28149, 24343, - 25173, 27832, 20175, 29289, 39826, 20998, 21563, 22132, 22707, 24996, - 25198, 28954, 22894, 31881, 31966, 32027, 38640, [12098, 25991], 32862, - 19993, 20341, 20853, 22592, 24163, 24179, 24330, 26564, 20006, 34109, - 38281, 38491, [12150, 31859], [12212, 38913], 20731, 22721, 30294, 30887, - 21029, 30629, 34065, 31622, 20559, 22793, [12122, 29255], 31687, 32232, - 36794, 36820, 36941, 20415, 21193, 23081, 24321, 38829, 20445, 33303, - 37610, 22275, 25429, 27497, 29995, 35036, 36628, 31298, 21215, 22675, - 24917, 25098, 26286, [11935, 27597], 31807, 33769, 20515, 20472, 21253, - 21574, 22577, 22857, 23453, 23792, 23791, 23849, 24214, 25265, 25447, - 25918, [12101, 26041], 26379, 27861, 27873, 28921, 30770, 32299, 32990, - 33459, 33804, 34028, 34562, 35090, 35370, 35914, 37030, 37586, 39165, - 40179, 40300, 20047, 20129, 20621, 21078, 22346, 22952, 24125, - {f: 2, c: 24536}, 25151, 26292, 26395, 26576, 26834, 20882, 32033, 32938, - 33192, 35584, 35980, 36031, 37502, 38450, 21536, 38956, 21271, 20693, - [12056, 21340], 22696, 25778, 26420, 29287, 30566, 31302, 37350, 21187, - 27809, 27526, 22528, 24140, 22868, 26412, 32763, 20961, 30406, 25705, - 30952, 39764, [12231, 40635], 22475, 22969, 26151, 26522, 27598, 21737, - 27097, 24149, 33180, 26517, 39850, 26622, 40018, 26717, 20134, 20451, - [12060, 21448], 25273, 26411, 27819, 36804, 20397, 32365, 40639, 19975, - 24930, 28288, 28459, 34067, 21619, 26410, 39749, [11922, 24051], 31637, - 23724, 23494, 34588, 28234, 34001, 31252, 33032, 22937, 31885, - [11936, 27665], 30496, 21209, 22818, 28961, 29279, [12141, 30683], 38695, - 40289, 26891, 23167, 23064, 20901, 21517, 21629, 26126, 30431, 36855, - 37528, 40180, 23018, 29277, 28357, 20813, 26825, 32191, 32236, - [12207, 38754], 40634, 25720, 27169, 33538, 22916, 23391, [12113, 27611], - 29467, 30450, 32178, 32791, 33945, 20786, [12106, 26408], 40665, - [12140, 30446], 26466, 21247, 39173, 23588, 25147, 31870, 36016, 21839, - 24758, 32011, [12200, 38272], 21249, 20063, 20918, 22812, 29242, 32822, - 37326, 24357, [12142, 30690], 21380, 24441, 32004, 34220, 35379, 36493, - 38742, 26611, 34222, 37971, 24841, 24840, 27833, 30290, 35565, 36664, - 21807, 20305, 20778, 21191, 21451, 23461, 24189, 24736, 24962, 25558, - 26377, 26586, 28263, 28044, {f: 2, c: 29494}, 30001, 31056, 35029, 35480, - 36938, [12194, 37009], 37109, 38596, 34701, [12067, 22805], 20104, 20313, - 19982, 35465, 36671, 38928, 20653, 24188, 22934, 23481, 24248, 25562, - 25594, 25793, 26332, 26954, 27096, 27915, 28342, 29076, [12132, 29992], - 31407, [12154, 32650], 32768, 33865, 33993, 35201, 35617, 36362, 36965, - 38525, 39178, 24958, 25233, 27442, 27779, 28020, 32716, 32764, 28096, - 32645, 34746, 35064, 26469, 33713, 38972, 38647, 27931, 32097, 33853, - 37226, 20081, 21365, 23888, 27396, 28651, 34253, 34349, 35239, 21033, - 21519, 23653, 26446, 26792, 29702, 29827, 30178, 35023, 35041, - [12197, 37324], 38626, 38520, 24459, 29575, [12148, 31435], 33870, 25504, - 30053, 21129, 27969, 28316, 29705, 30041, 30827, 31890, 38534, - [12015, 31452], [12243, 40845], 20406, 24942, 26053, 34396, 20102, 20142, - 20698, 20001, 20940, 23534, 26009, 26753, 28092, 29471, 30274, 30637, - 31260, 31975, 33391, 35538, 36988, 37327, 38517, 38936, [12050, 21147], - 32209, 20523, 21400, 26519, 28107, 29136, 29747, 33256, 36650, 38563, - 40023, 40607, 29792, 22593, 28057, 32047, 39006, 20196, 20278, 20363, - 20919, 21169, 23994, 24604, 29618, 31036, 33491, 37428, 38583, 38646, - 38666, 40599, 40802, 26278, 27508, 21015, 21155, 28872, 35010, 24265, - 24651, 24976, 28451, 29001, 31806, 32244, 32879, 34030, 36899, 37676, - 21570, 39791, 27347, 28809, 36034, 36335, 38706, 21172, 23105, 24266, - 24324, 26391, 27004, 27028, 28010, 28431, 29282, 29436, 31725, - [12156, 32769], 32894, 34635, 37070, 20845, 40595, 31108, 32907, 37682, - 35542, 20525, 21644, 35441, 27498, 36036, 33031, 24785, 26528, 40434, - 20121, 20120, 39952, 35435, 34241, 34152, 26880, 28286, 30871, 33109, - 24332, 19984, 19989, 20010, 20017, [12034, 20022], 20028, [12035, 20031], - 20034, 20054, 20056, 20098, [12037, 20101], 35947, 20106, 33298, 24333, - 20110, {f: 2, c: 20126}, [12039, 20128], 20130, 20144, 20147, 20150, 20174, - 20173, 20164, 20166, 20162, 20183, 20190, 20205, 20191, 20215, 20233, - 20314, 20272, 20315, 20317, 20311, 20295, 20342, 20360, 20367, 20376, - 20347, 20329, 20336, 20369, 20335, 20358, 20374, 20760, 20436, 20447, - 20430, 20440, 20443, 20433, 20442, 20432, {f: 2, c: 20452}, 20506, 20520, - 20500, 20522, 20517, 20485, 20252, 20470, 20513, 20521, 20524, 20478, - 20463, 20497, 20486, 20547, 20551, 26371, 20565, 20560, 20552, 20570, - 20566, 20588, 20600, 20608, 20634, 20613, 20660, 20658, {f: 2, c: 20681}, - 20659, 20674, 20694, 20702, 20709, 20717, 20707, 20718, 20729, 20725, - 20745, {f: 2, c: 20737}, 20758, 20757, 20756, 20762, 20769, 20794, 20791, - 20796, 20795, [12041, 20799], [11918, 20800], 20818, 20812, 20820, 20834, - 31480, {f: 2, c: 20841}, 20846, 20864, [12044, 20866], 22232, 20876, 20873, - 20879, 20881, 20883, 20885, [12045, 20886], 20900, 20902, 20898, - {f: 2, c: 20905}, [12046, 20907], 20915, {f: 2, c: 20913}, 20912, 20917, - 20925, 20933, 20937, 20955, [12047, 20960], 34389, 20969, 20973, 20976, - [12048, 20981], 20990, 20996, 21003, 21012, 21006, 21031, 21034, 21038, - 21043, 21049, 21071, 21060, {f: 2, c: 21067}, 21086, 21076, 21098, 21108, - 21097, 21107, 21119, 21117, 21133, 21140, 21138, 21105, 21128, 21137, - 36776, 36775, {f: 2, c: 21164}, 21180, 21173, 21185, 21197, 21207, 21214, - 21219, 21222, 39149, 21216, 21235, 21237, 21240, [12051, 21241], 21254, - 21256, 30008, 21261, 21264, 21263, [12052, 21269], [12053, 21274], 21283, - 21295, 21297, 21299, [12054, 21304], 21312, 21318, 21317, 19991, 21321, - 21325, 20950, 21342, [12057, 21353], 21358, 22808, 21371, 21367, - [12058, 21378], 21398, 21408, 21414, 21413, 21422, 21424, [12059, 21430], - 21443, 31762, 38617, 21471, 26364, 29166, 21486, 21480, 21485, 21498, - 21505, 21565, 21568, {f: 2, c: 21548}, 21564, 21550, 21558, 21545, 21533, - 21582, 21647, 21621, 21646, 21599, 21617, 21623, 21616, 21650, 21627, - 21632, 21622, 21636, 21648, 21638, 21703, 21666, 21688, 21669, 21676, - 21700, 21704, 21672, 21675, 21698, 21668, 21694, 21692, 21720, - {f: 2, c: 21733}, 21775, 21780, 21757, 21742, 21741, 21754, 21730, 21817, - 21824, 21859, 21836, 21806, 21852, 21829, {f: 2, c: 21846}, 21816, 21811, - 21853, 21913, 21888, 21679, 21898, 21919, 21883, 21886, 21912, 21918, - 21934, 21884, 21891, 21929, 21895, 21928, 21978, 21957, 21983, 21956, - 21980, 21988, 21972, 22036, 22007, 22038, 22014, 22013, 22043, 22009, - 22094, 22096, 29151, 22068, 22070, 22066, 22072, 22123, 22116, 22063, - 22124, 22122, 22150, 22144, 22154, 22176, 22164, 22159, 22181, 22190, - 22198, 22196, 22210, 22204, 22209, 22211, 22208, 22216, 22222, 22225, - 22227, [12062, 22231], 22254, 22265, 22272, 22271, 22276, 22281, 22280, - 22283, 22285, 22291, 22296, 22294, 21959, 22300, 22310, {f: 2, c: 22327}, - 22350, 22331, 22336, 22351, 22377, 22464, 22408, 22369, 22399, 22409, - 22419, 22432, 22451, 22436, 22442, 22448, 22467, 22470, 22484, - {f: 2, c: 22482}, 22538, 22486, 22499, 22539, 22553, 22557, 22642, 22561, - 22626, 22603, 22640, 27584, 22610, 22589, 22649, 22661, 22713, 22687, - 22699, 22714, 22750, 22715, 22712, 22702, 22725, 22739, 22737, 22743, - 22745, 22744, 22757, 22748, 22756, 22751, 22767, 22778, 22777, - {f: 3, c: 22779}, [12065, 22786], [12066, 22794], 22800, 22811, 26790, - 22821, {f: 2, c: 22828}, 22834, 22840, 22846, 31442, 22869, 22864, 22862, - 22874, 22872, 22882, 22880, 22887, 22892, 22889, 22904, 22913, 22941, - 20318, 20395, 22947, 22962, 22982, 23016, 23004, 22925, {f: 2, c: 23001}, - 23077, 23071, 23057, 23068, 23049, 23066, 23104, 23148, 23113, - {f: 2, c: 23093}, 23138, 23146, 23194, 23228, 23230, 23243, 23234, 23229, - 23267, 23255, 23270, 23273, 23254, {f: 2, c: 23290}, 23308, 23307, 23318, - 23346, 23248, 23338, 23350, 23358, 23363, 23365, 23360, 23377, 23381, - {f: 2, c: 23386}, 23397, 23401, 23408, 23411, 23413, 23416, 25992, 23418, - [12071, 23424], 23427, 23462, 23480, 23491, 23495, 23497, 23508, 23504, - 23524, 23526, 23522, 23518, 23525, 23531, 23536, 23542, 23539, 23557, - {f: 2, c: 23559}, 23565, 23571, 23584, [11920, 12074, 23586], 23592, - [12075, 23608], 23609, 23617, 23622, 23630, 23635, 23632, 23631, 23409, - 23660, [12076, 23662], 20066, 23670, 23673, 23692, 23697, 23700, 22939, - 23723, 23739, 23734, 23740, 23735, 23749, 23742, 23751, 23769, 23785, - 23805, 23802, 23789, 23948, 23786, 23819, 23829, 23831, 23900, 23839, - 23835, 23825, 23828, 23842, 23834, 23833, 23832, 23884, 23890, 23886, - 23883, 23916, 23923, 23926, 23943, 23940, 23938, 23970, 23965, 23980, - 23982, 23997, 23952, 23991, 23996, 24009, 24013, 24019, 24018, 24022, - [12078, 24027], 24043, 24050, 24053, 24075, 24090, 24089, 24081, 24091, - {f: 2, c: 24118}, 24132, 24131, 24128, 24142, 24151, 24148, 24159, 24162, - 24164, 24135, {f: 2, c: 24181}, [11923, 12083, 24186], 40636, - [12084, 24191], 24224, {f: 2, c: 24257}, 24264, 24272, 24271, 24278, 24291, - 24285, {f: 2, c: 24282}, 24290, 24289, {f: 2, c: 24296}, 24300, 24305, - 24307, 24304, [12085, 24308], 24312, [12086, 24318], 24323, 24329, 24413, - 24412, [12087, 24331], 24337, 24342, 24361, 24365, 24376, 24385, 24392, - 24396, 24398, 24367, [11924, 24401], {f: 2, c: 24406}, 24409, - [12090, 24417], 24429, [12091, 24435], 24439, 24451, 24450, 24447, 24458, - 24456, 24465, 24455, 24478, 24473, 24472, 24480, 24488, 24493, 24508, - 24534, 24571, 24548, 24568, 24561, 24541, 24755, 24575, 24609, 24672, - 24601, 24592, 24617, 24590, 24625, 24603, 24597, 24619, 24614, 24591, - 24634, 24666, 24641, 24682, 24695, 24671, 24650, 24646, 24653, 24675, - 24643, 24676, 24642, 24684, 24683, 24665, 24705, 24717, 24807, 24707, - 24730, 24708, 24731, {f: 2, c: 24726}, 24722, 24743, 24715, 24801, 24760, - 24800, 24787, 24756, 24560, 24765, 24774, 24757, 24792, 24909, 24853, - 24838, {f: 2, c: 24822}, 24832, 24820, 24826, 24835, 24865, 24827, 24817, - {f: 2, c: 24845}, 24903, 24894, 24872, 24871, 24906, 24895, 24892, 24876, - 24884, 24893, 24898, 24900, 24947, 24951, {f: 3, c: 24920}, 24939, 24948, - 24943, 24933, 24945, 24927, 24925, 24915, 24949, 24985, 24982, 24967, - 25004, 24980, 24986, 24970, 24977, 25003, 25006, 25036, 25034, 25033, - 25079, 25032, 25027, 25030, 25018, 25035, 32633, 25037, 25062, 25059, - 25078, 25082, 25076, 25087, 25085, 25084, 25086, 25088, [12093, 25096], - 25097, 25101, 25100, 25108, 25115, 25118, 25121, 25130, 25134, 25136, - {f: 2, c: 25138}, 25153, 25166, 25182, 25187, 25179, 25184, 25192, 25212, - 25218, 25225, 25214, {f: 2, c: 25234}, 25238, 25300, 25219, 25236, 25303, - 25297, 25275, 25295, 25343, 25286, 25812, 25288, 25308, 25292, 25290, - 25282, 25287, 25243, 25289, 25356, 25326, 25329, 25383, 25346, 25352, - 25327, 25333, 25424, 25406, 25421, 25628, 25423, 25494, 25486, 25472, - 25515, 25462, 25507, 25487, 25481, 25503, 25525, 25451, 25449, 25534, - 25577, 25536, 25542, 25571, 25545, 25554, 25590, 25540, 25622, 25652, - 25606, 25619, 25638, 25654, 25885, 25623, 25640, 25615, 25703, 25711, - 25718, 25678, 25898, 25749, 25747, 25765, 25769, 25736, 25788, 25818, - 25810, 25797, 25799, 25787, 25816, 25794, 25841, 25831, 33289, - {f: 2, c: 25824}, 25260, 25827, 25839, 25900, 25846, 25844, 25842, 25850, - 25856, 25853, 25880, 25884, 25861, 25892, 25891, 25899, [12097, 25908], - [11929, 25909], 25911, 25910, 25912, 30027, 25928, 25942, 25941, 25933, - 25944, 25950, 25949, 25970, 25976, {f: 2, c: 25986}, 35722, 26011, 26015, - 26027, 26039, 26051, 26054, 26049, 26052, 26060, 26066, 26075, 26073, - [12102, 26080], [11931, 26081], 26097, 26482, 26122, 26115, 26107, 26483, - {f: 2, c: 26165}, 26164, 26140, 26191, 26180, 26185, 26177, 26206, 26205, - 26212, {f: 2, c: 26215}, 26207, 26210, 26224, 26243, 26248, 26254, 26249, - 26244, 26264, 26269, 26305, 26297, 26313, 26302, 26300, 26308, 26296, - 26326, 26330, 26336, 26175, 26342, 26345, [12104, 26352], 26357, 26359, - 26383, 26390, 26398, {f: 2, c: 26406}, 38712, 26414, 26431, 26422, 26433, - 26424, 26423, 26438, 26462, 26464, 26457, {f: 2, c: 26467}, 26505, 26480, - 26537, 26492, 26474, 26508, 26507, 26534, 26529, 26501, 26551, 26607, - 26548, 26604, 26547, 26601, 26552, 26596, 26590, 26589, 26594, 26606, - 26553, 26574, 26566, 26599, 27292, 26654, 26694, 26665, 26688, 26701, - 26674, 26702, 26803, 26667, 26713, 26723, 26743, 26751, 26783, 26767, - 26797, 26772, 26781, 26779, 26755, 27310, 26809, 26740, 26805, 26784, - 26810, 26895, 26765, 26750, 26881, 26826, 26888, 26840, 26914, 26918, - 26849, 26892, 26829, 26836, 26855, 26837, 26934, 26898, 26884, 26839, - 26851, 26917, 26873, 26848, 26863, 26920, 26922, 26906, 26915, 26913, - 26822, 27001, 26999, 26972, 27000, 26987, 26964, 27006, 26990, 26937, - 26996, 26941, 26969, 26928, 26977, 26974, 26973, 27009, 26986, 27058, - 27054, 27088, 27071, 27073, 27091, 27070, 27086, 23528, 27082, 27101, - 27067, 27075, 27047, 27182, 27025, 27040, 27036, 27029, 27060, 27102, - 27112, 27138, 27163, 27135, 27402, 27129, 27122, 27111, 27141, 27057, - 27166, 27117, 27156, 27115, 27146, 27154, 27329, 27171, 27155, 27204, - 27148, 27250, 27190, 27256, 27207, 27234, 27225, 27238, 27208, 27192, - 27170, 27280, 27277, 27296, 27268, {f: 2, c: 27298}, 27287, 34327, 27323, - 27331, 27330, 27320, 27315, 27308, 27358, 27345, 27359, 27306, 27354, - 27370, 27387, 27397, 34326, 27386, 27410, 27414, 39729, 27423, 27448, - 27447, 30428, 27449, 39150, 27463, 27459, 27465, 27472, 27481, 27476, - 27483, 27487, 27489, 27512, [12109, 27513], {f: 2, c: 27519}, 27524, 27523, - 27533, 27544, 27541, 27550, 27556, {f: 2, c: 27562}, 27567, 27570, 27569, - [12110, 27571], 27575, 27580, 27590, [12111, 27595], 27603, 27615, 27628, - 27627, 27635, 27631, 40638, 27656, 27667, [12115, 27668], 27675, 27684, - 27683, 27742, 27733, 27746, 27754, 27778, 27789, 27802, 27777, 27803, - 27774, 27752, 27763, 27794, 27792, 27844, 27889, 27859, 27837, 27863, - 27845, 27869, 27822, 27825, 27838, 27834, 27867, 27887, 27865, 27882, - 27935, 34893, 27958, 27947, 27965, 27960, 27929, 27957, 27955, 27922, - 27916, 28003, 28051, 28004, 27994, 28025, 27993, 28046, 28053, 28644, - 28037, 28153, 28181, 28170, 28085, 28103, 28134, 28088, 28102, 28140, - 28126, 28108, 28136, 28114, 28101, 28154, 28121, 28132, 28117, 28138, - 28142, 28205, 28270, 28206, 28185, 28274, 28255, 28222, 28195, 28267, - 28203, 28278, 28237, 28191, 28227, 28218, 28238, 28196, 28415, 28189, - 28216, 28290, 28330, 28312, 28361, 28343, 28371, 28349, 28335, 28356, - 28338, {f: 2, c: 28372}, 28303, 28325, 28354, 28319, 28481, 28433, 28748, - 28396, 28408, 28414, 28479, 28402, 28465, 28399, 28466, 28364, 28478, - 28435, 28407, 28550, 28538, 28536, 28545, 28544, 28527, 28507, 28659, - 28525, 28546, 28540, 28504, 28558, 28561, 28610, 28518, 28595, 28579, - 28577, 28580, 28601, 28614, 28586, 28639, 28629, 28652, 28628, 28632, - 28657, 28654, 28635, 28681, 28683, 28666, 28689, 28673, 28687, 28670, - 28699, 28698, 28532, 28701, 28696, 28703, 28720, 28734, 28722, 28753, - 28771, 28825, 28818, 28847, 28913, 28844, 28856, 28851, 28846, 28895, - 28875, 28893, 28889, 28937, 28925, 28956, 28953, 29029, 29013, 29064, - 29030, 29026, 29004, 29014, 29036, 29071, 29179, 29060, 29077, 29096, - 29100, 29143, 29113, 29118, 29138, 29129, 29140, 29134, 29152, 29164, - 29159, 29173, 29180, 29177, 29183, 29197, 29200, 29211, 29224, 29229, - 29228, 29232, 29234, [12120, 29243], 29244, [12121, 29247], 29248, 29254, - 29259, 29272, 29300, 29310, 29314, 29313, 29319, 29330, 29334, 29346, - 29351, 29369, 29362, 29379, 29382, 29380, 29390, 29394, 29410, - {f: 2, c: 29408}, 29433, 29431, 20495, 29463, 29450, 29468, 29462, 29469, - 29492, 29487, 29481, 29477, 29502, {f: 2, c: 29518}, 40664, 29527, 29546, - 29544, 29552, 29560, 29557, 29563, 29562, 29640, 29619, 29646, 29627, - 29632, 29669, 29678, 29662, 29858, 29701, 29807, 29733, 29688, 29746, - 29754, 29781, 29759, 29791, 29785, 29761, 29788, 29801, 29808, 29795, - 29802, 29814, 29822, 29835, 29854, 29863, 29898, 29903, 29908, 29681, - 29920, 29923, 29927, 29929, 29934, 29938, {f: 2, c: 29936}, 29944, 29943, - 29956, 29955, 29957, 29964, 29966, 29965, 29973, 29971, 29982, 29990, - 29996, 30012, 30020, 30029, 30026, 30025, 30043, 30022, 30042, 30057, - 30052, 30055, 30059, 30061, 30072, 30070, {f: 2, c: 30086}, 30068, 30090, - 30089, 30082, 30100, 30106, 30109, 30117, 30115, 30146, 30131, 30147, - 30133, 30141, 30136, 30140, 30129, 30157, 30154, 30162, 30169, 30179, - 30174, {f: 2, c: 30206}, 30204, 30209, 30192, 30202, {f: 2, c: 30194}, - 30219, 30221, 30217, 30239, 30247, {f: 3, c: 30240}, 30244, 30260, 30256, - 30267, {f: 2, c: 30279}, 30278, 30300, 30296, {f: 2, c: 30305}, - {f: 3, c: 30312}, 30311, 30316, 30320, 30322, [12136, 30326], 30328, 30332, - 30336, 30339, 30344, 30347, 30350, 30358, 30355, {f: 2, c: 30361}, 30384, - 30388, {f: 3, c: 30392}, 30402, 30413, 30422, 30418, 30430, 30433, 30437, - 30439, 30442, 34351, 30459, 30472, 30471, 30468, 30505, 30500, 30494, - {f: 2, c: 30501}, 30491, {f: 2, c: 30519}, 30535, 30554, 30568, 30571, - 30555, 30565, 30591, 30590, 30585, 30606, 30603, 30609, 30624, 30622, - 30640, 30646, 30649, 30655, {f: 2, c: 30652}, 30651, 30663, 30669, 30679, - 30682, 30684, 30691, 30702, 30716, 30732, 30738, 31014, 30752, 31018, - 30789, 30862, 30836, 30854, 30844, 30874, 30860, 30883, 30901, 30890, - 30895, 30929, 30918, 30923, 30932, 30910, 30908, 30917, 30922, 30956, - 30951, 30938, 30973, 30964, 30983, 30994, 30993, 31001, 31020, 31019, - 31040, 31072, 31063, 31071, 31066, 31061, 31059, 31098, 31103, 31114, - 31133, 31143, 40779, 31146, 31150, 31155, {f: 2, c: 31161}, 31177, 31189, - 31207, 31212, 31201, 31203, 31240, 31245, {f: 2, c: 31256}, 31264, 31263, - 31104, 31281, 31291, 31294, 31287, 31299, 31319, 31305, {f: 2, c: 31329}, - 31337, 40861, 31344, 31353, 31357, 31368, 31383, 31381, 31384, 31382, - 31401, 31432, 31408, 31414, 31429, 31428, 31423, 36995, 31431, 31434, - 31437, 31439, 31445, 31443, {f: 2, c: 31449}, 31453, {f: 2, c: 31457}, - 31462, 31469, 31472, 31490, 31503, 31498, 31494, 31539, {f: 2, c: 31512}, - 31518, 31541, 31528, 31542, 31568, 31610, 31492, 31565, 31499, 31564, - 31557, 31605, 31589, 31604, 31591, {f: 2, c: 31600}, 31596, 31598, 31645, - 31640, 31647, 31629, 31644, 31642, 31627, 31634, 31631, 31581, 31641, - 31691, 31681, 31692, 31695, 31668, 31686, 31709, 31721, 31761, 31764, - 31718, 31717, 31840, 31744, 31751, 31763, 31731, 31735, 31767, 31757, - 31734, 31779, 31783, 31786, 31775, 31799, 31787, 31805, 31820, 31811, - 31828, 31823, 31808, 31824, 31832, 31839, 31844, 31830, 31845, 31852, - 31861, 31875, 31888, 31908, 31917, 31906, 31915, 31905, 31912, 31923, - 31922, 31921, 31918, 31929, 31933, 31936, 31941, 31938, 31960, 31954, - 31964, 31970, 39739, 31983, 31986, 31988, 31990, 31994, 32006, 32002, - 32028, 32021, 32010, 32069, 32075, 32046, 32050, 32063, 32053, 32070, - 32115, 32086, 32078, 32114, 32104, 32110, 32079, 32099, 32147, 32137, - 32091, 32143, 32125, 32155, 32186, 32174, 32163, 32181, 32199, 32189, - 32171, 32317, 32162, 32175, 32220, 32184, 32159, 32176, 32216, 32221, - 32228, 32222, 32251, 32242, 32225, 32261, 32266, 32291, 32289, 32274, - 32305, 32287, 32265, 32267, 32290, 32326, 32358, 32315, 32309, 32313, - 32323, 32311, 32306, 32314, 32359, 32349, 32342, 32350, {f: 2, c: 32345}, - 32377, 32362, 32361, 32380, 32379, 32387, 32213, 32381, 36782, 32383, - {f: 2, c: 32392}, 32396, 32402, 32400, {f: 2, c: 32403}, 32406, 32398, - {f: 2, c: 32411}, 32568, 32570, 32581, {f: 3, c: 32588}, 32592, - [12153, 32593], 32597, 32596, 32600, {f: 2, c: 32607}, {f: 2, c: 32616}, - 32615, 32632, 32642, 32646, 32643, 32648, 32647, 32652, 32660, 32670, - 32669, 32666, 32675, 32687, 32690, 32697, 32686, 32694, 32696, 35697, - {f: 2, c: 32709}, 32714, 32725, 32724, 32737, 32742, 32745, 32755, 32761, - 39132, 32774, 32772, 32779, [12158, 32786], {f: 2, c: 32792}, 32796, 32801, - 32808, 32831, 32827, 32842, 32838, 32850, 32856, 32858, 32863, 32866, - 32872, 32883, 32882, 32880, 32886, 32889, 32893, [12160, 32895], 32900, - 32902, 32901, 32923, 32915, 32922, 32941, 20880, 32940, 32987, 32997, - 32985, 32989, 32964, 32986, 32982, 33033, 33007, 33009, 33051, 33065, - 33059, 33071, 33099, 38539, 33094, 33086, 33107, 33105, 33020, 33137, - 33134, {f: 2, c: 33125}, 33140, 33155, 33160, 33162, 33152, 33154, 33184, - 33173, 33188, 33187, 33119, 33171, 33193, 33200, 33205, 33214, 33208, - 33213, 33216, 33218, 33210, 33225, 33229, 33233, 33241, 33240, 33224, - 33242, {f: 2, c: 33247}, 33255, {f: 2, c: 33274}, 33278, {f: 2, c: 33281}, - 33285, 33287, 33290, 33293, 33296, 33302, 33321, 33323, 33336, 33331, - 33344, 33369, 33368, 33373, 33370, 33375, 33380, 33378, 33384, - {f: 2, c: 33386}, 33326, 33393, 33399, [12171, 33400], 33406, 33421, 33426, - 33451, 33439, 33467, 33452, 33505, 33507, 33503, 33490, 33524, 33523, - 33530, 33683, 33539, 33531, 33529, 33502, 33542, 33500, 33545, 33497, - 33589, 33588, 33558, 33586, 33585, 33600, 33593, 33616, 33605, 33583, - 33579, {f: 2, c: 33559}, 33669, 33690, 33706, 33695, 33698, 33686, 33571, - 33678, 33671, 33674, 33660, 33717, 33651, 33653, 33696, 33673, 33704, - 33780, 33811, 33771, 33742, 33789, 33795, 33752, 33803, 33729, 33783, - 33799, 33760, 33778, 33805, 33826, 33824, 33725, 33848, 34054, 33787, - 33901, 33834, 33852, 34138, 33924, 33911, 33899, 33965, 33902, 33922, - 33897, 33862, 33836, 33903, 33913, 33845, 33994, 33890, 33977, 33983, - 33951, 34009, 33997, 33979, 34010, 34000, 33985, 33990, 34006, 33953, - 34081, 34047, 34036, {f: 2, c: 34071}, 34092, 34079, 34069, 34068, 34044, - 34112, 34147, 34136, 34120, 34113, 34306, 34123, 34133, 34176, 34212, - 34184, 34193, 34186, 34216, 34157, 34196, 34203, 34282, 34183, 34204, - 34167, 34174, 34192, 34249, 34234, 34255, 34233, 34256, 34261, 34269, - 34277, 34268, 34297, 34314, 34323, 34315, 34302, 34298, 34310, 34338, - 34330, 34352, 34367, [12172, 34381], 20053, 34388, 34399, 34407, 34417, - 34451, 34467, {f: 2, c: 34473}, {f: 2, c: 34443}, 34486, 34479, 34500, - 34502, 34480, 34505, 34851, 34475, 34516, 34526, 34537, 34540, 34527, - 34523, 34543, 34578, 34566, 34568, 34560, 34563, 34555, 34577, 34569, - 34573, 34553, 34570, 34612, 34623, 34615, 34619, 34597, 34601, 34586, - 34656, 34655, 34680, 34636, 34638, 34676, 34647, 34664, 34670, 34649, - 34643, 34659, 34666, 34821, 34722, 34719, 34690, 34735, 34763, 34749, - 34752, 34768, 38614, 34731, 34756, 34739, 34759, 34758, 34747, 34799, - 34802, 34784, 34831, 34829, 34814, {f: 2, c: 34806}, 34830, 34770, 34833, - 34838, 34837, 34850, 34849, 34865, 34870, 34873, 34855, 34875, 34884, - 34882, 34898, 34905, 34910, 34914, 34923, 34945, 34942, 34974, 34933, - 34941, 34997, 34930, 34946, 34967, 34962, 34990, 34969, 34978, 34957, - 34980, 34992, 35007, 34993, {f: 2, c: 35011}, 35028, {f: 2, c: 35032}, - 35037, 35065, 35074, 35068, 35060, 35048, 35058, 35076, 35084, 35082, - 35091, 35139, 35102, 35109, {f: 2, c: 35114}, 35137, 35140, 35131, 35126, - 35128, 35148, 35101, 35168, 35166, 35174, 35172, 35181, 35178, 35183, - 35188, 35191, [12177, 35198], 35203, 35208, 35210, 35219, 35224, 35233, - 35241, 35238, 35244, 35247, 35250, 35258, 35261, {f: 2, c: 35263}, 35290, - {f: 2, c: 35292}, 35303, 35316, 35320, 35331, 35350, 35344, 35340, 35355, - 35357, 35365, 35382, 35393, 35419, 35410, 35398, 35400, 35452, 35437, - 35436, 35426, 35461, 35458, 35460, 35496, 35489, 35473, {f: 2, c: 35493}, - 35482, 35491, 35524, 35533, 35522, 35546, 35563, 35571, 35559, 35556, - 35569, 35604, 35552, 35554, 35575, 35550, 35547, 35596, 35591, 35610, - 35553, 35606, 35600, 35607, 35616, 35635, 38827, 35622, 35627, 35646, - 35624, 35649, 35660, 35663, 35662, 35657, 35670, 35675, 35674, 35691, - 35679, 35692, 35695, 35700, 35709, 35712, 35724, 35726, {f: 2, c: 35730}, - 35734, {f: 2, c: 35737}, 35898, 35905, 35903, 35912, 35916, 35918, 35920, - [12183, 35925], 35938, 35948, [12184, 35960], 35962, 35970, 35977, 35973, - 35978, {f: 2, c: 35981}, 35988, 35964, 35992, 25117, 36013, 36010, 36029, - {f: 2, c: 36018}, 36014, 36022, 36040, 36033, 36068, 36067, 36058, 36093, - {f: 2, c: 36090}, {f: 2, c: 36100}, 36106, 36103, 36111, 36109, 36112, - 40782, 36115, 36045, 36116, 36118, 36199, 36205, 36209, 36211, 36225, - 36249, 36290, 36286, 36282, 36303, 36314, 36310, 36300, 36315, 36299, - {f: 2, c: 36330}, 36319, 36323, 36348, {f: 2, c: 36360}, 36351, - {f: 2, c: 36381}, 36368, 36383, 36418, 36405, 36400, 36404, 36426, 36423, - 36425, 36428, 36432, 36424, 36441, 36452, 36448, 36394, 36451, 36437, - 36470, 36466, 36476, 36481, 36487, 36485, 36484, 36491, 36490, 36499, - 36497, 36500, 36505, 36522, 36513, 36524, 36528, 36550, 36529, 36542, - 36549, 36552, 36555, 36571, 36579, 36604, 36603, 36587, 36606, 36618, - 36613, 36629, 36626, 36633, 36627, 36636, 36639, 36635, 36620, 36646, - 36659, 36667, 36665, 36677, 36674, 36670, 36684, 36681, 36678, 36686, - 36695, 36700, {f: 3, c: 36706}, 36764, 36767, 36771, 36781, 36783, 36791, - 36826, 36837, 36834, 36842, 36847, 36999, 36852, 36869, {f: 2, c: 36857}, - 36881, 36885, 36897, 36877, 36894, 36886, 36875, 36903, 36918, 36917, - 36921, 36856, {f: 4, c: 36943}, 36878, 36937, 36926, 36950, 36952, 36958, - 36968, 36975, 36982, 38568, 36978, 36994, 36989, 36993, 36992, 37002, - 37001, 37007, 37032, 37039, 37041, 37045, 37090, 37092, 25160, 37083, - 37122, 37138, 37145, 37170, 37168, 37194, 37206, 37208, 37219, 37221, - 37225, 37235, 37234, 37259, 37257, 37250, 37282, 37291, 37295, 37290, - 37301, 37300, 37306, {f: 2, c: 37312}, 37321, 37323, 37328, 37334, 37343, - 37345, 37339, 37372, {f: 2, c: 37365}, 37406, 37375, 37396, 37420, 37397, - 37393, 37470, 37463, 37445, 37449, 37476, 37448, 37525, 37439, 37451, - 37456, 37532, 37526, 37523, 37531, 37466, 37583, 37561, 37559, 37609, - 37647, 37626, 37700, 37678, 37657, 37666, 37658, 37667, 37690, 37685, - 37691, 37724, 37728, 37756, 37742, 37718, 37808, {f: 2, c: 37804}, 37780, - 37817, {f: 2, c: 37846}, 37864, 37861, 37848, 37827, 37853, 37840, 37832, - 37860, 37914, 37908, 37907, 37891, 37895, 37904, 37942, 37931, 37941, - 37921, 37946, 37953, 37970, 37956, 37979, 37984, 37986, 37982, 37994, - 37417, 38000, 38005, 38007, 38013, 37978, 38012, 38014, 38017, 38015, - 38274, 38279, 38282, 38292, 38294, {f: 2, c: 38296}, 38304, 38312, 38311, - 38317, 38332, 38331, 38329, 38334, 38346, 28662, 38339, 38349, 38348, - 38357, 38356, 38358, 38364, 38369, 38373, 38370, 38433, 38440, - {f: 2, c: 38446}, 38466, 38476, 38479, 38475, 38519, 38492, 38494, 38493, - 38495, 38502, 38514, 38508, 38541, 38552, 38549, 38551, 38570, 38567, - {f: 2, c: 38577}, 38576, 38580, [12202, 38582], 38584, [12203, 38585], - 38606, 38603, 38601, 38605, 35149, 38620, 38669, 38613, 38649, 38660, - 38662, 38664, 38675, 38670, 38673, 38671, 38678, 38681, 38692, 38698, - 38704, 38713, {f: 2, c: 38717}, 38724, 38726, 38728, 38722, 38729, 38748, - 38752, 38756, 38758, 38760, 21202, 38763, 38769, 38777, 38789, 38780, - 38785, 38778, 38790, 38795, {f: 2, c: 38799}, 38812, 38824, 38822, 38819, - {f: 2, c: 38835}, 38851, 38854, 38856, [12209, 38859], 38876, - [12210, 38893], 40783, 38898, 31455, 38902, 38901, 38927, 38924, 38968, - 38948, 38945, 38967, 38973, 38982, 38991, 38987, 39019, {f: 3, c: 39023}, - 39028, 39027, 39082, 39087, 39089, 39094, 39108, 39107, 39110, 39145, - 39147, 39171, 39177, 39186, 39188, 39192, 39201, {f: 2, c: 39197}, 39204, - 39200, 39212, 39214, {f: 2, c: 39229}, 39234, 39241, 39237, 39248, 39243, - {f: 2, c: 39249}, 39244, 39253, {f: 2, c: 39319}, 39333, {f: 2, c: 39341}, - 39356, 39391, 39387, 39389, 39384, 39377, {f: 2, c: 39405}, - {f: 2, c: 39409}, 39419, 39416, 39425, 39439, 39429, 39394, 39449, 39467, - 39479, 39493, 39490, 39488, 39491, 39486, 39509, 39501, 39515, 39511, - 39519, 39522, 39525, 39524, 39529, 39531, 39530, 39597, 39600, 39612, - 39616, 39631, 39633, {f: 2, c: 39635}, 39646, [12221, 39647], - {f: 2, c: 39650}, 39654, 39663, 39659, 39662, 39668, 39665, 39671, 39675, - 39686, 39704, 39706, 39711, {f: 2, c: 39714}, [12222, 39717], - {f: 4, c: 39719}, 39726, [12223, 39727], [12224, 39730], 39748, 39747, - 39759, {f: 2, c: 39757}, 39761, 39768, 39796, 39827, 39811, 39825, - {f: 2, c: 39830}, {f: 2, c: 39839}, 39848, 39860, 39872, 39882, 39865, - 39878, 39887, {f: 2, c: 39889}, 39907, 39906, 39908, 39892, 39905, 39994, - 39922, 39921, 39920, 39957, 39956, 39945, 39955, 39948, 39942, 39944, - 39954, 39946, 39940, 39982, 39963, 39973, 39972, 39969, 39984, 40007, - 39986, 40006, 39998, 40026, 40032, 40039, 40054, 40056, 40167, 40172, - 40176, 40201, 40200, 40171, 40195, 40198, 40234, 40230, 40367, 40227, - 40223, 40260, 40213, 40210, 40257, 40255, 40254, 40262, 40264, - {f: 2, c: 40285}, 40292, 40273, 40272, 40281, 40306, 40329, 40327, 40363, - 40303, 40314, 40346, 40356, 40361, 40370, 40388, 40385, 40379, 40376, - 40378, 40390, 40399, 40386, 40409, 40403, 40440, 40422, 40429, 40431, - 40445, {f: 2, c: 40474}, 40478, [12228, 40565], 40569, 40573, 40577, 40584, - {f: 2, c: 40587}, 40594, 40597, 40593, 40605, [12230, 40613], 40617, 40632, - 40618, 40621, 38753, 40652, {f: 3, c: 40654}, 40660, 40668, 40670, 40669, - 40672, 40677, 40680, 40687, 40692, {f: 2, c: 40694}, [12235, 40697], - {f: 2, c: 40699}, [12236, 40701], {f: 2, c: 40711}, 30391, 40725, 40737, - 40748, 40766, [12241, 40778], [12242, 40786], 40788, 40803, - {f: 3, c: 40799}, {f: 2, c: 40806}, 40812, 40810, 40823, 40818, 40822, - 40853, [12244, 40860], [12245, 40864], 22575, 27079, 36953, 29796, 0, - {f: 76, c: 9472}, {f: 20, c: 9312}, {f: 10, c: 8544}, 13129, 13076, 0, - 13133, 0, 13095, 0, 13110, 13137, 0, 13069, 13094, 0, 13099, 13130, 0, - {f: 3, c: 13212}, {f: 2, c: 13198}, 13252, 13217, 12317, 12319, 8470, - 13261, 0, {f: 5, c: 12964}, {f: 2, c: 12849}, 12857, 13182, 13181, 13180, - 8750, 8721, {s: 3}, 8735, 8895, 0, 0, 21854, {s: 7}, 167133, 0, 0, 28976, - 0, 40407, {s: 4}, 64054, 0, 0, 22169, 15694, {s: 4}, 20448, 0, 0, 36544, 0, - 194797, {s: 4}, 153716, 32363, 33606, 167670, {s: 3}, 40572, 0, 0, 26171, - 0, 40628, {s: 4}, 26629, {s: 5}, 23650, 0, 194780, 0, 32353, 0, 0, 64070, - {s: 5}, 34083, 37292, {s: 7}, 34796, {s: 8}, 25620, 0, 0, 39506, {s: 4}, - 64074, 0, 194692, {s: 4}, 31774, {s: 6}, 64016, 25681, 0, 0, 63980, 22625, - 39002, 0, 194679, {s: 3}, 31153, 0, 28678, {s: 9}, 22218, {s: 3}, 21085, 0, - 28497, 37297, {s: 10}, 64106, {s: 6}, 38960, 0, 40629, {s: 9}, 33802, - 63939, {f: 2, c: 63890}, 63897, 0, 34847, 194575, 0, 194771, 194584, - {s: 7}, 137754, 23643, {s: 4}, 25890, 0, 0, 26618, 0, 26766, 0, 148432, - 194848, {s: 21}, 34110, {s: 15}, 30562, {s: 12}, 65075, 0, - {f: 2, c: 65073}, {s: 4}, 65072, {f: 2, c: 65077}, {f: 2, c: 65081}, 0, 0, - {f: 2, c: 65079}, {f: 2, c: 65087}, {f: 2, c: 65085}, {f: 4, c: 65089}, - {f: 2, c: 65083}, {s: 41}, {f: 3, c: 12436}, 0, 0, 22099, {s: 41}, 65508, - 65287, 65282, 0, 9665, 9655, 8681, 8679, 8678, 8680, 9634, 9831, 9825, - 9828, 9826, 13216, 13218, {f: 2, c: 13220}, 13207, 8467, 13208, 13235, - 13234, 13233, 13232, {f: 3, c: 13189}, 13259, 13200, 13268, 13206, 13090, - 13078, 13080, 13077, 13059, 13091, 13143, 13122, 13113, 13115, 13056, - 13105, 13127, 13086, 13098, 0, 13183, 8481, 9742, 12342, 12320, {s: 3}, - {f: 9, c: 9352}, {f: 20, c: 9332}, 12881, {f: 10, c: 8560}, - {f: 10, c: 12882}, {f: 26, c: 9372}, 12867, 12861, 12863, 12852, 12856, - 12851, 12860, 12866, 12862, 12854, 12853, 12859, 12864, 12858, 12976, - 12973, 12969, 12975, 12948, 12970, 12952, 12971, 12946, 12945, 12947, - 12972, 12974, 12950, {s: 8}, {f: 3, c: 9131}, 0, {f: 3, c: 9127}, 0, 13260, - 13061, 0, 0, 13215, 13219, 13222, 0, 0, 12958, {f: 2, c: 13192}, 13256, - 8749, 0, 12848, {f: 6, c: 12842}, 12855, 12865, 10145, {s: 3}, 9673, 9824, - 9829, 9827, 9830, {f: 4, c: 9728}, 9758, {f: 2, c: 9756}, 9759, 12953, - 9450, {f: 2, c: 8554}, {s: 3}, {f: 8, c: 9601}, 9615, 9614, 9613, 9612, - 9611, 9610, 9609, {f: 2, c: 9620}, {f: 2, c: 9581}, 9584, 9583, 9552, 9566, - 9578, 9569, {f: 2, c: 9698}, 9701, 9700, 0, 0, {f: 3, c: 9585}, {s: 20}, - 20956, 29081, {f: 9, c: 10102}, {s: 3}, {f: 2, c: 8570}, {s: 3}, 8575, - 8458, 8457, 0, 0, 12292, 8646, {f: 2, c: 8644}, 0, {f: 4, c: 12535}, 0, 0, - 12957, {s: 3}, 13179, {s: 3}, 13107, 13134, {s: 30}, 32394, 35100, 37704, - 37512, 34012, 20425, 28859, 26161, 26824, 37625, 26363, 24389, - [12033, 20008], 20193, 20220, 20224, 20227, 20281, 20310, 20370, 20362, - 20378, 20372, 20429, 20544, 20514, 20479, 20510, 20550, 20592, 20546, - 20628, 20724, 20696, 20810, 20836, 20893, 20926, 20972, 21013, 21148, - 21158, 21184, 21211, 21248, 0, 21284, 21362, 21395, 21426, 21469, 64014, - 21660, 21642, 21673, 21759, 21894, 22361, 22373, 22444, 22472, 22471, - 64015, 0, 22686, 22706, 22795, 22867, 22875, 22877, 22883, 22948, 22970, - 23382, 23488, 29999, 23512, 0, 23582, 23718, 23738, 23797, 23847, 23891, 0, - 23874, 23917, {f: 2, c: 23992}, 24016, 24353, 24372, 24423, 24503, 24542, - 24669, 24709, 24714, 24798, 24789, 24864, 24818, 24849, 24887, 24880, - 24984, 25107, 25254, 25589, 25696, 25757, 25806, 25934, 26112, 26133, - 26121, 26158, 0, 26148, 26213, 26199, 26201, 64018, 26227, 26265, 26272, - 26290, 26303, 26362, 26382, 0, 26470, 26555, 26706, 26560, 0, 26692, 26831, - 64019, 26984, 64020, 27032, 27106, 27184, 27243, 27206, 27251, 27262, - 27362, 27364, 27606, 27711, 27740, 27782, 27759, 27866, 27908, 28039, - 28015, 28054, 28076, 28111, 28152, 28146, 28156, 28217, 28252, 28199, - 28220, 28351, 28552, 28597, 28661, 28677, 28679, 28712, 28805, 28843, - 28943, 28932, 29020, {f: 2, c: 28998}, 0, 29121, 29182, 29361, 29374, - 29476, 64022, 29559, 29629, 29641, 29654, 29667, 29650, 29703, 29685, - 29734, 29738, 29737, 29742, 0, 29833, 29855, 29953, 30063, 30338, 30364, - 30366, 30363, 30374, 64023, 30534, 21167, 30753, 30798, 30820, 30842, - 31024, {f: 3, c: 64024}, 31124, 64027, 31131, 31441, 31463, 64028, 31467, - 31646, 64029, 32072, 0, 32183, 32160, 32214, 32338, 32583, 32673, 64030, - 33537, 33634, 33663, 33735, 33782, 33864, 33972, 34131, 34137, 34155, - 64031, 34224, {f: 2, c: 64032}, 34823, 35061, 35346, 35383, 35449, 35495, - 35518, 35551, 64034, 35574, 35667, 35711, 36080, 36084, 36114, 36214, - 64035, 36559, 0, 64037, 36967, 37086, 64038, 37141, 37159, 37338, 37335, - 37342, {f: 2, c: 37357}, {f: 2, c: 37348}, 37382, 37392, 37386, 37434, - 37440, 37436, 37454, 37465, 37457, 37433, 37479, 37543, {f: 2, c: 37495}, - 37607, 37591, 37593, 37584, 64039, 37589, 37600, 37587, 37669, 37665, - 37627, 64040, 37662, 37631, 37661, 37634, 37744, 37719, 37796, 37830, - 37854, 37880, 37937, 37957, 37960, 38290, 0, 64041, 38557, 38575, 38707, - 38715, 38723, 38733, 38735, [12205, 38737], 0, 38999, 39013, - {f: 2, c: 64042}, 39207, 64044, 39326, 39502, 39641, 39644, 39797, 39794, - 39823, 39857, 39867, 39936, 40304, 40299, 64045, 40473, 40657, {s: 636}, - 8364, 8486, 0, 0, 64256, {f: 2, c: 64259}, 257, 299, 363, 275, 333, 256, - 298, 362, 274, 332, {f: 4, c: 8539}, {f: 2, c: 8531}, 8304, - {f: 6, c: 8308}, {f: 10, c: 8320}, 461, 282, 0, 7868, 463, 0, 296, 465, 0, - 467, 366, 360, 462, 283, 0, 7869, 464, 0, 297, 466, 0, 468, 367, 361, 593, - 8049, 8048, 509, 0, 596, 0, 0, 601, 0, 0, 602, 0, 0, 603, 8051, 8050, 0, - 331, 629, 652, 0, 0, 658, 643, 720, {s: 682}, {f: 10, c: 12832}, {s: 108}, - {f: 4, c: 12892}, {f: 15, c: 12977}, {s: 50}, {f: 26, c: 9424}, - {f: 26, c: 9398}, {s: 48}, {f: 47, c: 13008}, 0, {f: 10, c: 12928}, 12944, - {f: 6, c: 12938}, 0, 12959, {s: 6}, {f: 2, c: 12960}, 12955, 12954, 12963, - 12962, 12951, 0, 12956, 12949, {s: 6}, 9676, {s: 11}, 10111, - {f: 10, c: 9451}, {s: 510}, 8414, {s: 815}, 13274, {s: 3}, 8448, 13250, 0, - 0, 8453, 0, 13169, 0, 0, 13197, 13211, {s: 3}, {f: 2, c: 13271}, {s: 3}, - {f: 2, c: 13057}, 13060, 13062, 0, 13064, 0, 13063, 13066, 0, 13065, 0, - 13067, 0, 13068, {f: 6, c: 13070}, 0, 13079, 0, 13081, 0, {f: 4, c: 13082}, - {f: 3, c: 13087}, 13092, 0, 13093, 0, 0, {f: 2, c: 13096}, 0, 13101, 0, 0, - {f: 3, c: 13102}, 13106, 0, 0, {f: 2, c: 13108}, 13116, {s: 3}, 13111, 0, - 13112, 13114, 13117, 13121, {f: 3, c: 13118}, {f: 4, c: 13123}, 13128, - {f: 2, c: 13131}, {f: 2, c: 13135}, 0, 0, 13138, 13140, 0, 0, 13139, - {f: 2, c: 13141}, {s: 132}, 8501, 976, 8714, 8463, 0, 981, 987, 977, 0, - {f: 2, c: 9832}, 9836, {s: 5}, 12347, 0, {f: 3, c: 12339}, 8252, 8265, - {s: 5}, 8723, 0, 8771, {f: 2, c: 8818}, {s: 6}, {f: 2, c: 12312}, - {f: 2, c: 65375}, {s: 10}, 9115, {f: 2, c: 9117}, 9120, {s: 4}, 9121, - {f: 2, c: 9123}, 9126, {s: 12}, [9116, 9119, 9122, 9125, 9130], {s: 8}, - 9986, 0, 0, 12349, 0, 12447, 0, 0, 8709, 8864, 8854, 8856, 8853, 8855, - {s: 4}, 9664, 9654, {s: 4}, 8656, 8596, {f: 2, c: 8600}, {f: 2, c: 8598}, - 8652, 8651, {s: 10}, 12336, 8967, {s: 8}, 10048, 10047, {s: 7}, 9643, 0, - 9642, 0, 10010, {s: 12}, 9702, {s: 4}, 10070, {s: 379}, {f: 2, c: 65093}, - {s: 679}, 64103, 64098, 32227, [12232, 40643], 28331, 64082, 64061, 64069, - 64062, 27114, 28212, 64096, 64071, 64056, 64066, 64078, 34395, 64105, - 64052, 64099, 25581, 25802, 30799, 64084, 63856, 64077, 64097, 64072, - 64076, {f: 2, c: 64091}, 64081, 64067, 64090, 28041, 29376, 0, 194885, - 64086, 64080, 64049, 64059, 24034, 64063, 64101, 21373, 64055, 64095, - 24501, 64064, 0, 64083, 0, 64085, 64104, 64068, 64089, 26202, 64053, 64075, - 64100, 64065, 64048, 0, 64057, 64051, 27493, 64058, 27599, 64050, 25150, - 64079, 63773, 63964, 63798, 28122, 63952, 26310, 27511, 64087, 37706, 0, - 37636, {s: 120}, 133390, {s: 120}, 35999, 11991, [11965, 158033], {s: 5}, - 37555, 38321, 0, 0, 194812, {s: 13}, 194965, {s: 8}, 194794, 0, 26478, - 11974, 0, 194594, {s: 13}, 13314, 0, 0, 26083, {s: 4}, 134071, {s: 10}, - 171339, 0, 194611, 24378, {s: 8}, 11945, 0, 20465, {s: 7}, 63753, {s: 7}, - 11964, 0, 0, 194732, 26435, {s: 3}, 133732, 35329, 25142, 0, 0, 21555, - 23067, {s: 3}, 25221, 0, 0, 194819, {s: 6}, 21567, {s: 9}, 27506, {s: 4}, - 29986, 19256, 0, 0, 24063, {s: 6}, 194827, 29626, 134047, {s: 3}, 194600, - 0, 194849, {s: 5}, 194623, {s: 16}, 194675, {f: 2, c: 11916}, 23577, - {s: 3}, 131083, 23426, 194642, {s: 5}, 11997, [11999, 39136], - [11998, 169599], 14221, 0, [11927, 14586], 0, 194887, 0, [11909, 20155], - 131490, {s: 7}, 13599, 0, 194738, 0, 0, [11971, 35200], {s: 4}, 31237, - {s: 4}, 35498, 0, 32085, 0, 28568, {s: 7}, 25591, 30246, {s: 4}, - [11978, 163767], {s: 5}, 146686, {s: 5}, 13351, 0, 0, 33067, 0, 0, 194842, - {s: 5}, 11950, {s: 5}, 194714, {s: 3}, 194831, {s: 19}, 22305, 135741, - 194586, 0, 64003, {s: 7}, 21534, 15240, 20839, {s: 4}, 63839, {s: 9}, - 20023, {s: 13}, [11946, 150804], 24421, 23020, 194658, 0, 24217, {s: 46}, - 13416, {s: 8}, 21200, {s: 9}, 26625, 0, 195024, 195039, {s: 5}, 153215, 0, - 0, 11959, {s: 4}, 36534, 63775, {s: 3}, 63875, {s: 5}, 31867, 63906, 0, - 63898, 0, [11961, 32770], 157360, {s: 4}, [11911, 132648], 0, 0, 131210, - 194604, [11915, 13630], {s: 4}, 21589, 0, 22841, 0, 0, 23414, 194669, - 23572, 14306, 23782, 0, 20040, 0, 0, 194742, {s: 4}, 158105, 25371, 0, 0, - 26211, 0, 194779, 0, 0, 27126, 27014, {s: 3}, 27596, 0, 28183, 0, 0, 27818, - {s: 3}, [11942, 20012], 0, 0, 29935, 30069, 30188, 30286, 16305, 30570, - 30633, {s: 6}, 31571, 0, 0, 16996, {s: 3}, 194924, 0, 0, 32328, {s: 5}, - 11955, {s: 4}, 33089, 17491, 0, [11966, 33401], [11967, 64094], - [11968, 64093], 0, 20857, 33626, {s: 3}, 17701, 0, 34292, 131248, {s: 4}, - 34429, 0, 13358, 35014, {s: 6}, 18406, {s: 8}, 36808, {s: 19}, 166279, 0, - 0, 167447, 0, 0, 38969, {s: 6}, 39432, {s: 4}, 39903, {s: 10}, 148206, - {s: 5}, 21385, 0, 64017, 194785, 0, 146622, 132625, 0, {f: 2, c: 19972}, - 19999, 20011, {f: 2, c: 20015}, {f: 2, c: 20032}, 20036, [11907, 20058], - 20095, 20109, 20118, 20153, 20176, 20192, 20221, 20223, 20235, 20245, - 20320, 20283, 20297, 20308, 20346, {f: 2, c: 20349}, 20375, 20414, 20431, - 20477, {f: 2, c: 20480}, 20496, 20507, 20519, 20526, 20567, 20582, 20586, - 20539, 20623, 20630, 20636, 20684, 20710, 20713, 20719, 20744, 20747, - 20752, 20763, 20766, 20831, 20897, 20924, 0, 20974, 20980, 20993, - [11913, 20994], 21011, 21065, 21089, 21094, 21139, 21192, 21232, - {f: 2, c: 21258}, 21310, 21324, 21323, 21345, 21356, 21419, 21466, 21478, - 21493, 21543, 21581, 21606, 21611, 21620, 21645, 21654, 21665, 21677, - 21689, 21695, 21702, 21709, 21774, 21803, 21813, 21834, 21856, 0, 21896, - 21902, 22024, {f: 2, c: 22030}, 22071, 22079, 22089, 22091, 22095, 22118, - 22121, 22127, {f: 2, c: 22129}, 22165, 22170, {f: 2, c: 22188}, 22193, - 22217, 22237, 22244, 22282, 22293, 22307, 22319, {f: 2, c: 22323}, 22348, - 22384, 22412, 22428, 22456, 22502, 22509, {f: 2, c: 22517}, 22527, 22537, - 22560, 22578, 22652, 22656, 22697, 22734, 22736, 22740, 22746, 22761, - 22796, 22820, 22831, 22881, 22893, 22986, 22994, 23005, {f: 2, c: 23011}, - 23044, 23052, 23075, 23111, 23125, 23139, 23149, 23166, 23198, 23207, - 23212, 23219, 23264, 23296, 23321, 23333, 23341, 23361, 23420, - {f: 2, c: 23422}, 23434, [11919, 23587], 23595, 23600, 23651, 23657, 23676, - 23755, 23762, 23796, 23844, 23846, 23875, 23878, 23882, 23954, 23956, - 23961, 23968, 24024, 24032, 24056, 24064, 24082, {f: 2, c: 24084}, 24088, - 24110, 24152, {f: 2, c: 24171}, 24232, 24234, {f: 2, c: 24254}, 0, 24274, - 24327, 24334, {f: 2, c: 24348}, 24354, 24360, 24374, 24379, 24384, - [12089, 24400], 24408, 24420, 24457, 24476, 24487, 24484, 24495, 24504, - [11926, 24516], 24521, 24545, 24553, 24557, 24572, 24599, 24602, 24627, - 24673, 24703, 24734, 24740, 24752, 24779, 24795, 24824, {f: 3, c: 24850}, - 24860, 24956, 24973, 24991, 25000, 25026, 25055, 25109, 25129, 25155, - 25158, [11928, 25164], 25169, 25174, 25284, 25340, 25354, 25357, 25368, - 25401, {f: 2, c: 25410}, 25445, 25460, 25469, 25476, 25479, 25488, 25502, - 25553, 25564, 25609, 25616, 25634, 25684, 25691, 25709, 25723, - {f: 2, c: 25790}, 25829, 25847, 25851, 25860, 25878, 25881, 25927, 25959, - 25985, 25989, 26050, 26096, 26098, 26156, 26188, {f: 2, c: 26203}, 26209, - 26219, 0, 26276, 26312, 26348, 26373, 26387, 26419, 26440, 26444, 26486, - 26491, 26544, 26546, 26617, 26583, 26585, 26608, 26668, {f: 2, c: 26672}, - 26715, 26738, 26741, 26746, 26756, 26789, 26802, 26832, 26838, 26856, - 26861, {f: 2, c: 26864}, 26876, 26897, 26899, 26933, 26939, 26967, 26979, - 26994, {f: 2, c: 27007}, 27046, 27053, 27063, {f: 2, c: 27094}, 27137, - 27151, 27157, 27176, 27188, 27198, 27205, {f: 2, c: 27216}, 27222, 27227, - 27267, 27273, 27281, {f: 3, c: 27293}, 27356, 27367, 27372, 27422, 27428, - 27445, 27462, 27478, 27488, 27522, 27582, 27617, 27633, 27664, 27699, - [11937, 27701], 11938, 27737, 27766, 27771, 27781, 27797, 27804, 27856, - 27860, 27862, 27872, {f: 2, c: 27883}, 27886, 27914, 27918, 27921, 27950, - 27991, 27998, 28005, 28034, 28095, 28100, 28106, 28118, 28137, 28194, - 28241, 28359, 28362, 28366, 28413, 28442, 28458, 28463, 28467, 28506, - 28510, 28514, 28541, 28555, 28557, 28562, 28564, 28570, {f: 2, c: 28583}, - 28598, 28634, 28638, 0, 28729, 28732, 0, 28756, {f: 2, c: 28765}, 28772, - [11939, 28780], 28798, 28801, 28821, 28855, {f: 2, c: 28883}, 28888, 28892, - 28935, 28960, 28977, 29002, 29010, 29024, 29049, 29074, 0, 29131, 29139, - 29142, 29184, 29213, 29227, 29240, 29249, 29267, {f: 2, c: 29269}, 29276, - 29325, [11944, 29357], 29364, 29383, 29435, {f: 2, c: 29444}, 29480, 29489, - 29507, 29548, 29564, 29571, {f: 2, c: 29573}, 29589, {f: 3, c: 29598}, - 29606, 29611, 29621, 29623, 29628, 29647, 29657, 29673, 29684, 29693, - 29700, 29706, {f: 2, c: 29722}, 29732, 29736, 29740, {f: 3, c: 29743}, - 29753, 29764, 29767, 29771, 29773, 29777, 29783, 29798, 29803, 29809, - 29824, {f: 3, c: 29829}, 29840, 29848, 29852, 29856, 29859, 29864, 29867, - 29877, 29887, 29896, 29914, 29918, 30030, 30073, 30081, 30096, - [12135, 30098], 30099, 30132, 30180, 30201, 30208, 30218, {f: 2, c: 30229}, - 30233, 30238, 30253, 30261, 30275, 30283, 30309, 30317, 30319, 30321, - 30324, {f: 2, c: 30372}, 30405, 30412, 30444, 30460, 30516, 30518, 30556, - {f: 2, c: 30559}, 30578, 30589, 30613, 30634, 30694, 30704, 30708, 30726, - 30754, {f: 2, c: 30765}, 30768, 30773, 30824, 30878, 30920, 30924, 30926, - 30948, {f: 2, c: 30944}, 30962, 30967, 30971, 31025, 0, [11949, 31035], - 31037, 31045, {f: 2, c: 31067}, 31115, 31126, 31128, [12145, 31160], 31163, - 31178, 31194, 31235, 31241, 31249, 31262, 31277, 31289, 31301, 31308, - 31325, 0, 31341, 31352, 31392, 31395, 31411, {f: 2, c: 31419}, 31430, - 31495, 31508, 31527, 31537, 31559, 31566, 31584, 31593, 31597, 31602, - 31633, 31663, 31703, 31705, 31755, 31759, 31776, 31782, 31793, 31798, - 31825, 31833, 31847, 31854, 31856, 31932, 31935, {f: 2, c: 31944}, 31959, - 31961, 31965, 31979, {f: 3, c: 32007}, 32019, 32029, 32035, 32065, 32083, - 32089, 32093, 32122, 32134, {f: 2, c: 32139}, 32204, 32235, 32241, 32249, - 32264, 32273, 32277, 32288, 32327, 32354, 32366, 32371, 32397, 32401, - 32408, 32580, 32591, [11947, 11954, 32594], [11953, 32595], 32609, 32657, - 32703, 32718, 32735, 32741, 32748, {f: 2, c: 32750}, 32762, 32782, 32785, - 32788, 32804, 32806, 32826, 32828, 32864, 32881, 32885, 32926, 32934, - 32939, {f: 2, c: 32983}, 33046, 33048, 33082, 33098, 33100, 33153, 33156, - 33204, 33231, 33273, 33283, 33313, 33330, 33332, 33350, 33355, 33359, - 33422, 33454, 33463, 33470, 33478, 33534, 33603, 33617, 33621, 33670, - 33677, 33682, 33688, 33705, {f: 2, c: 33727}, 33770, 33807, 33809, 33866, - 33910, 33960, 33967, 33984, 33986, 34032, 34045, 34060, 34100, 34142, - 34191, 34231, 34254, 34221, 34322, 34345, 34386, 34403, 34412, 34415, - 34426, 34445, 34449, 34456, {f: 2, c: 34471}, 34554, 34557, 34571, 34579, - 34585, 34590, 34600, 34622, 34673, 34696, 34713, {f: 2, c: 34732}, 34741, - 34774, 34795, 34797, 34817, 0, 34822, 34827, 34836, 34844, 34902, 34911, - [11970, 34916], 34968, 34986, {f: 2, c: 35005}, 35018, 35026, 35035, - {f: 2, c: 35056}, 35078, {f: 3, c: 35096}, 35111, 35120, 35134, 35195, - 35284, 35286, 35301, 35313, 35335, 35343, 35349, 35362, 35406, 35455, - 35572, 35615, 35639, {f: 2, c: 35651}, 35668, 35740, 35742, 35911, 35924, - 35955, 36004, 36057, 36065, 36088, 36094, 36123, 36201, 36204, 36228, - 36237, 36245, 36262, 36294, 36302, 36324, 36332, 36384, 36427, 36460, - 36464, 36474, 36498, 36526, 36531, 36561, 36564, 36601, 36631, 36662, - 36774, [12193, 36789], [11981, 36790], 0, 36832, 36836, 36854, 36866, - 36908, 36932, 37000, 37013, 37017, 37019, 37026, 37044, 37079, 37085, - 37108, 37143, 37148, 37169, 37178, 37181, 37192, 37211, 37217, 37220, - 37262, 37278, 37288, {f: 2, c: 37293}, 37298, 37308, 37360, 37367, 37371, - 37383, 37416, 37427, 37432, 37443, 37447, 37455, 37472, 37570, - {f: 2, c: 37579}, 37599, 37645, 37653, 37663, 37671, 37703, 37714, 0, - 37738, 37741, 37787, 37818, 37801, 37825, 37834, 37858, 37882, 37885, - 37903, 37940, 37951, 37973, 37995, 38002, [11986, 38264], 38310, 38313, 0, - 38324, 38333, 38362, [11983, 11990, 38429], 38465, 38488, 38532, 38564, - 38569, 38610, 195060, 38622, 38633, 38641, 38658, 38665, 38746, 38755, - 38766, 38771, 38810, 38818, {f: 2, c: 38837}, 38873, 38878, 38900, 38922, - 38926, 38942, 38947, 38955, 38974, {f: 2, c: 38994}, 39001, 39020, 39096, - 39098, 39103, 39112, 39141, {f: 2, c: 39218}, 39232, 39245, 39260, 39263, - 39345, {f: 2, c: 39353}, 39369, 39426, 39446, 39460, 39463, - {f: 2, c: 39469}, 39478, 39480, 39498, 39510, {f: 2, c: 39605}, 39673, - 39683, 39712, {f: 2, c: 39731}, 39795, 39801, 39847, 39873, 39879, 39895, - 39911, 39915, 39927, 39930, 39933, 39947, 39975, 39978, 39990, 40001, - 40019, 40035, 40048, 40055, 40194, 40258, 40263, 40291, 40297, 40316, - 40318, 40333, 40369, 40387, 40391, 40406, 40415, 40427, 40436, 40469, - 40477, 40612, 40616, 40620, 40679, 40686, 40720, 40722, 40727, 40729, - 40751, 40759, 40761, 40769, 40773, 40791, 40808, 40817, 40821, 40848, - 40852, 40866, 0, 13317, 194564, 22048, 24267, 11925, 0, 144954, 0, 28665, - 28390, 29107, [11940, 64073], {s: 4}, [11980, 64102], 0, 23986, 0, 20435, - 20697, 20720, 20931, 22134, 27220, 27905, 28112, 28226, 28377, 29668, - 29729, 30060, 30801, 34805, 144382, 29608, 15091, 13531, 17420, 16010, 0, - 0, 19432, 0, 16090, 15138, 0, 17786, 16531, 0, 18021, 16643, 17043, 18094, - 13448, 140809, {f: 3, c: 63584}, 63610, 63615, {s: 23}, {f: 2, c: 8836}, - {f: 2, c: 8842}, 8713, 0, {f: 2, c: 8965}, {s: 9}, {f: 2, c: 8741}, - {s: 14}, 8802, 0, 8773, 8776, {f: 2, c: 8822}, {s: 4}, 8487, {s: 209}, - {f: 2, c: 8922}, 8533, 8984, {f: 2, c: 7742}, {f: 2, c: 504}, 470, 472, - 474, 476, 260, 728, 317, 346, 350, 356, 377, 379, 261, 731, 318, 347, 711, - 351, 357, 378, 733, 380, 340, 258, 313, 262, 268, 280, 270, 323, 327, 336, - 344, 368, 354, 341, 259, 314, 263, 269, 281, 271, 273, 324, 328, 337, 345, - 369, 355, 729, 264, 284, 292, 308, 348, 364, 265, 285, 293, 309, 349, 365, - 625, 651, 638, 620, 622, 633, 648, 598, 627, 637, 642, 656, 635, 621, 607, - 626, 669, 654, 609, 624, 641, 295, 661, 660, 614, 664, 450, 595, 599, 644, - 608, 403, 616, 649, 600, 604, 606, 592, 623, 650, 612, 594, 653, 613, 674, - 673, 597, 657, 634, 615, 865, 712, 716, 721, 8255, 783, {f: 5, c: 741}, 0, - 0, 805, 812, 825, 796, {f: 2, c: 799}, 829, 809, 815, 734, 804, 816, 828, - 820, {f: 2, c: 797}, {f: 2, c: 792}, 810, {f: 2, c: 826}, 794, {s: 3}, - {f: 2, c: 610}, 618, 628, 630, 632, 640, 655, 665, 668, 671, 688, 690, 695, - 704, {f: 2, c: 736}, {s: 6}, 8862, {s: 287}, 12348, 12543, 0, - {f: 2, c: 12310}, 9838, 9835, {f: 2, c: 10548}, 10687, 0, 12448, 0, - {f: 2, c: 10746}, {s: 13}, 962, {f: 10, c: 9461}, {f: 2, c: 9750}, 9649, - {f: 10, c: 12784}, 0, {f: 6, c: 12794}, {f: 15, c: 9150}, 0, 0, 10003, 0, - 9251, 9166, {f: 4, c: 9680}, {f: 2, c: 8263}, 0, 8273, 8258, - {f: 16, c: 12688}, {s: 13}, {f: 2, c: 9136}, {f: 12, c: 9842}, - {f: 2, c: 12441}, 8413, {s: 450}, 20296, 20319, 20330, 20332, 20494, 20504, - 20545, 20722, 20688, 20742, 20739, 20789, 20821, 20823, 13493, 20938, - 20962, 21079, 21196, 21206, 21243, 21276, 21347, 21405, 21522, 21631, - 21640, 21840, 21889, 21933, 21966, 22075, 22174, 22185, 22195, 22391, - 22396, 135963, 22479, 22500, 22628, 22665, 136302, 22738, 22752, 34369, - 22923, 22930, 22979, 23059, 23143, 23159, 23172, 23236, 137405, 23421, - 23443, 23570, 64060, 136884, 23674, 23695, 23711, 23715, 23722, 23760, - 138804, 23821, 23879, 23937, 23972, 23975, 24011, 24158, 24313, 24320, - 24322, 24355, 24381, 24404, 24445, 24589, 24596, 24600, 24629, 24647, - 24733, 24788, 24797, 24875, 25020, 25017, 25122, 25178, 25199, 25302, - 25468, 25573, 25721, 25796, 25808, 25897, 26013, 26170, 26146, 26155, - 26160, 26163, 26184, 143812, {f: 2, c: 26231}, 26253, 26299, 26331, 26344, - 26439, 26497, 26515, 26520, 26523, 26620, 26653, 26787, 26890, 26953, - 144836, 26946, 26980, 27045, 27087, 15286, 15299, 27113, 27125, 145215, - 27195, 145251, 27284, 27301, 15375, 27419, 27436, 27495, 27561, 27565, - 27607, 27647, 27653, 27764, 27800, 27899, 27846, 27953, 27961, 27967, - 27992, 28052, 28074, 28123, 28125, 28228, 28254, 28337, 28353, 28432, - 28505, 28513, 28542, 28556, 28576, 28604, 28615, 28618, 28656, 28750, - 28789, 28836, 28900, 28971, 28958, 28974, 29009, 29032, 29061, 29063, - 29114, 29124, 29205, 15935, 29339, 149489, 29479, 29520, 29542, 29602, - 29739, 29766, 29794, 29805, 29862, 29865, 29897, 29951, 29975, 16242, - 30158, 30210, 30216, 30308, 30337, 30365, 30378, 30390, 30414, 30420, - 30438, 30449, 30474, 30489, {f: 2, c: 30541}, 30586, 30592, 30612, 30688, - 152718, 30787, 30830, 30896, 152846, 30893, 30976, 31004, 31022, 31028, - 31046, 31097, 31176, 153457, 31188, 31198, 31211, 31213, 31365, 154052, - 31438, 31485, 31506, 31533, 31547, 31599, 31745, 31795, 155041, 31853, - 31865, 31887, 31892, 31904, 31957, 32049, 32092, 32131, 32166, 32194, - 32296, 32663, 32731, 32821, 32823, 32970, 32992, 33011, 33120, - {f: 2, c: 33127}, 33133, 33211, 33226, 33239, 17499, 33376, 33396, 158463, - 33441, {f: 2, c: 33443}, 33449, 33471, 33493, 33533, 33536, 33570, 33581, - 33594, 33607, 33661, 33703, 33743, 33745, 33761, 33793, 33798, 33887, - 33904, 33907, 33925, 33950, 33978, 159296, 34098, 34078, 34095, 34148, - 34170, 34188, 34210, 34251, 34285, 34303, {f: 2, c: 34308}, 34320, 159988, - 34328, 34360, 34391, 34402, 17821, 34421, 34488, 34556, 34695, 17898, - 34826, 34832, 35022, 161412, 35122, 35129, 35136, 35220, 35318, 35399, - 35421, 35425, 35445, 35536, 35654, 35673, 35689, 35741, 35913, 35944, - 36271, 36305, 36311, 36387, 36413, 36475, 164471, 18500, 36602, 36638, - 36653, 36692, 164813, 36840, 36846, 36872, 36909, 37015, 37043, 37054, - {f: 2, c: 37060}, 37063, 37103, 37140, 37142, {f: 2, c: 37154}, 37167, - 37172, 37251, 37361, 37705, {f: 2, c: 37732}, 37795, 37855, 37892, 37939, - 37962, 37987, 38001, 38286, 38303, 38316, 38326, 38347, 38352, 38355, - 18864, 38366, 38565, 38639, 38734, 38805, 38830, 38842, 38849, 38857, - 38875, 38998, 39143, 39256, 39427, 39617, 39619, 39630, 39638, 39682, - 39688, 19479, 39725, 39774, 39782, 39812, 39818, 39838, 39886, 39909, - 39928, 39971, {f: 2, c: 40015}, 40037, {f: 2, c: 40221}, 40259, 40274, - 40330, 40342, 40384, 40364, 40380, 172432, 40423, 40455, 40606, 40623, - 40855, 131209, 19970, 19983, 19986, 20009, 20014, 20039, 131234, 20049, - 13318, 131236, 20073, 20125, 13356, 20156, 20163, 20168, 20203, 20186, - 20209, 20213, 20246, 20324, 20279, 20286, 20312, 131603, {f: 2, c: 20343}, - 20354, 20357, 20454, 20402, 20421, 20427, 20434, 13418, 20466, 20499, - 20508, 20558, 20563, 20579, 20643, 20616, {f: 2, c: 20626}, 20629, 20650, - 131883, 20657, {f: 2, c: 20666}, 20676, 20679, 20723, 131969, 20686, - 131953, 20692, 20705, 13458, 132089, 20759, 132170, 20832, 132361, 20851, - 20867, 20875, 13500, 20888, 20899, 20909, 13511, 132566, 20979, 21010, - 21014, 132943, 21077, 21084, 21100, 21111, 21124, 21122, 133127, 21144, - 133178, 21156, {f: 2, c: 21178}, 21194, 21201, 133305, 21239, 21301, 21314, - 133500, 133533, 21351, 21370, 21412, 21428, 133843, 21431, 21440, 133917, - {f: 2, c: 13661}, 21461, 13667, 21492, 21540, 21544, 13678, 21571, 21602, - 21612, 21653, 21664, 21670, 21678, 21687, 21690, 21699, 134469, 21740, - 21743, 21745, 21747, {f: 2, c: 21760}, 21769, 21820, 21825, 13734, 21831, - 13736, 21860, 134625, 21885, 21890, 21905, 13765, 21970, 134805, 134765, - 21951, 21961, 21964, 21969, 21981, 13786, 21986, 134756, 21993, 22056, - 135007, 22023, 22032, 22064, 13812, 22077, 22080, 22087, 22110, 22112, - 22125, 13829, 22152, 22156, 22173, 22184, 22194, 22213, 22221, 22239, - 22248, {f: 2, c: 22262}, 135681, 135765, 22313, 135803, {f: 2, c: 22341}, - 22349, 135796, 22376, 22383, {f: 3, c: 22387}, 22395, 135908, 135895, - 22426, {f: 2, c: 22429}, 22440, 22487, 135933, 22476, 135990, 136004, - 22494, 22512, 13898, 22520, 22523, 22525, 22532, 22558, 22567, 22585, - 136132, 22601, 22604, 22631, {f: 2, c: 22666}, 22669, {f: 2, c: 22671}, - 22676, 22685, 22698, 22705, 136301, 22723, 22733, 22754, {f: 2, c: 22771}, - {f: 2, c: 22789}, 22797, 22804, 136663, 13969, 22845, 13977, 22854, 13974, - 158761, 22879, 136775, {f: 2, c: 22901}, 22908, 22943, 22958, 22972, 22984, - 22989, 23006, 23015, 23022, 136966, 137026, 14031, 23053, 23063, 23079, - 23085, 23141, 23162, 23179, 23196, {f: 2, c: 23199}, 23202, 23217, 23221, - 23226, 23231, 23258, 23260, 23269, 23280, 23278, 23285, 23304, 23319, - 23348, 23372, 23378, 23400, 23407, 23425, 23428, 137667, 23446, 23468, - {f: 2, c: 14177}, 23502, 23510, 14188, 14187, 23537, 23549, 14197, 23555, - 23593, 138326, 23647, {f: 2, c: 23655}, 23664, 138541, 138565, 138616, - 138594, 23688, 23690, 14273, 138657, 138652, 23712, 23714, 23719, 138642, - 23725, 23733, 138679, 23753, 138720, 138803, 23814, 23824, 23851, 23837, - 23840, 23857, 23865, 14312, 23905, 23914, 14324, 23920, 139038, 14333, - 23944, 14336, 23959, 23984, 23988, 139126, 24017, 24023, 139258, 24036, - 24041, 14383, 14390, 14400, 24095, 24126, 24137, 14428, 24150, 14433, - {f: 2, c: 24173}, 139643, 24229, 24236, 24249, 24262, 24281, 140062, 24317, - 24328, 140205, 24350, 24391, 24419, 24434, 24446, 24463, 24482, 24519, - 24523, {f: 3, c: 24530}, 24546, {f: 2, c: 24558}, 24563, 14615, 24610, - 24612, 14618, 24652, 24725, 24744, 141043, 24753, 24766, 24776, 24793, - 24814, 24821, 24848, 24857, 24862, 24890, 14703, 24897, 24902, 24928, - 141403, {f: 2, c: 24978}, 24983, 24997, 25005, 141483, 25045, 25053, 25077, - 141711, 25123, 25170, 25185, 25188, 25211, 25197, 25203, 25241, 25301, - 142008, 25341, 25347, 25360, {f: 2, c: 142159}, 25394, 25397, - {f: 2, c: 25403}, 25409, 25412, 25422, 142150, 25433, 142365, 142246, - 25452, 25497, 142372, 25492, 25533, {f: 2, c: 25556}, 25568, - {f: 2, c: 25579}, 25586, 25630, 25637, 25641, 25647, 25690, 25693, 25715, - 25725, 25735, 25745, 25759, {f: 2, c: 25803}, 25813, 25815, 142817, 25828, - 25855, 14958, 25871, 25876, 14963, 25886, 25906, 25924, 25940, 25963, - 25978, 25988, 25994, 26034, 26037, 26040, 26047, 26057, 26068, 15062, - 26105, 26108, 26116, 26120, 26145, 26154, 26181, 26193, 26190, 15082, - 143811, 143861, 143798, 26218, {f: 2, c: 26220}, 26235, 26240, 26256, - 26258, 15118, 26285, 26289, 26293, 15130, 15132, 15063, 26369, 26386, - 144242, 26393, 144339, 144338, 26445, 26452, 26461, 144336, 144356, 144341, - 26484, 144346, 26514, 144351, 33635, 26640, 26563, 26568, 26578, 26587, - 26615, 144458, 144465, 144459, 26648, 26655, 26669, 144485, 26675, 26683, - 26686, 26693, 26697, 26700, 26709, 26711, 15223, 26731, 26734, 26748, - 26754, 26768, 26774, 15213, {f: 3, c: 26776}, 26780, {f: 2, c: 26794}, - 26804, 26811, 26875, 144612, 144730, 26819, 26821, 26828, 26841, - {f: 2, c: 26852}, 26860, 26871, 26883, 26887, 15239, 144788, 15245, 26950, - 26985, 26988, 27002, 27026, 15268, 27030, 27056, 27066, 27068, 27072, - 27089, 144953, 144967, 144952, 27107, {f: 2, c: 27118}, 27123, 15309, - 27124, 27134, 27153, 27162, 27165, 145180, {f: 2, c: 27186}, 27199, 27209, - 27258, 27214, 27218, 27236, 145164, 27275, 15344, 27297, 145252, 27307, - 27325, 27334, 27348, 27344, 27357, 145407, 145383, {f: 3, c: 27377}, 27389, - 145444, 27403, {f: 3, c: 27407}, 145469, 27415, 15398, 27439, 27466, 27480, - 27500, 27509, [11934, 27514], 27521, 27547, 27566, 146072, 27581, - {f: 3, c: 27591}, 27610, {f: 2, c: 27622}, 27630, 27650, 27658, 27662, - 27702, 146559, 27725, 27739, 27757, 27780, 27785, 15555, 27796, 27799, - 27821, 27842, 15570, 27868, 27881, 27885, 146688, 27904, 27940, - {f: 2, c: 27942}, 27751, 27951, 27964, 27995, 28000, 28016, - {f: 2, c: 28032}, 28042, 28045, 28049, 28056, 146752, 146938, 146937, - 146899, 28075, 28078, 28084, 28098, 27956, 28104, 28110, 28127, 28150, - 28214, 28190, 15633, 28210, {f: 2, c: 28232}, {f: 2, c: 28235}, 28239, - {f: 2, c: 28243}, 28247, 28259, 15646, 28307, 28327, 28340, 28355, 28469, - 28395, 28409, 28411, 28426, 28428, 28440, 28453, 28470, 28476, 147326, - 28498, 28503, 28512, 28520, 28560, 28566, 28606, 28575, 28581, 28591, - 15716, {f: 2, c: 28616}, 28649, 147606, 28668, 28672, 28682, 28707, 147715, - 28730, 28739, 28743, 28747, 15770, 28773, 28777, 28782, 28790, 28806, - 28823, 147910, 28831, 28849, 147966, 28908, 28874, 28881, 28931, 28934, - 28936, 28940, 15808, 28975, 29008, 29011, 29022, 15828, 29078, 29056, - 29083, 29088, 29090, {f: 2, c: 29102}, 148412, 29145, 29148, 29191, 15877, - 29236, 29241, 29250, 29271, 29283, 149033, {f: 2, c: 29294}, 29304, 29311, - 29326, 149157, 29358, 29360, 29377, 15968, 29388, 15974, 15976, 29427, - 29434, 29447, 29458, {f: 2, c: 29464}, 16003, 29497, 29484, 29491, 29501, - 29522, 16020, 29547, 149654, {f: 2, c: 29550}, 29553, 29569, 29578, 29588, - 29592, 29596, 29605, 29625, 29631, 29637, 29643, 29665, 29671, 29689, - 29715, 29690, 29697, 29779, 29760, 29763, 29778, 29789, 29825, 29832, - 150093, 29842, 29847, 29849, 29857, 29861, 29866, 29881, 29883, 29882, - 29910, 29912, 29931, 150358, 29946, 150383, 29984, 29988, 29994, 16215, - 150550, {f: 2, c: 30013}, 30016, 30024, 30032, 30034, 30066, 30065, 30074, - {f: 2, c: 30077}, 30092, 16245, 30114, 16247, 30128, 30135, - {f: 2, c: 30143}, 30150, 30159, 30163, 30173, {f: 2, c: 30175}, 30183, - 30190, 30193, 30211, 30232, 30215, 30223, 16302, 151054, 30227, - {f: 2, c: 30235}, 151095, 30245, 30248, 30268, 30259, 151146, 16329, 30273, - 151179, 30281, 30293, 16343, 30318, 30357, 30369, 30368, {f: 2, c: 30375}, - 30383, 151626, 30409, 151637, 30440, 151842, 30487, 30490, 30509, 30517, - 151977, 16441, 152037, 152013, 30552, 152094, 30588, 152140, 16472, 30618, - 30623, 30626, 30628, {f: 2, c: 30686}, 30692, 30698, 30700, 30715, 152622, - 30725, 30729, 30733, 30745, 30764, 30791, 30826, 152793, 30858, 30868, - 30884, 30877, 30879, 30907, 30933, 30950, {f: 2, c: 30969}, 30974, 152999, - 30992, 31003, 31013, 31050, 31064, 16645, 31079, 31090, 31125, 31137, - 31145, 31156, 31170, 31175, {f: 2, c: 31180}, 31190, 16712, 153513, 153524, - 16719, 31242, 31253, 31259, 16739, 31288, 31303, 31318, 31321, 31324, - 31327, 31335, 31338, 31349, 31362, 31370, 31376, 31404, 154068, 16820, - 31417, 31422, 16831, 31436, 31464, 31476, 154340, 154339, 154353, 31549, - 31530, {f: 2, c: 31534}, 16870, 16883, 31615, 31553, 16878, 31573, 31609, - 31588, 31590, 31603, 154546, 16903, 31632, 31643, 16910, 31669, 31676, - 31685, 31690, 154699, 154724, 31700, 31702, 31706, 31722, 31728, 31747, - 31758, 31813, 31818, 31831, 31838, 31841, 31849, 31855, 155182, 155222, - 155237, 31910, 155234, {f: 2, c: 31926}, 155352, 31940, 155330, 31949, - 155368, 155427, 31974, 155484, 31989, 32003, 17094, 32018, 32030, 155616, - 155604, {f: 2, c: 32061}, 32064, 32071, 155660, 155643, 17110, 32090, - 32106, 32112, 17117, 32127, 155671, 32136, 32151, 155744, 32157, 32167, - 32170, 32182, 32192, 32215, 32217, 32230, 17154, 155885, 64088, 32272, - 32279, 32285, 32295, 32300, 32325, 32373, 32382, {f: 2, c: 32390}, 17195, - 32410, 17219, 32572, 32571, 32574, 32579, 13505, 156272, 156294, - {f: 2, c: 32611}, 32621, {f: 2, c: 32637}, 32656, 20859, 146702, 32662, - 32668, 32685, 156674, 32707, 32719, 32739, 32754, 32778, 32776, 32790, - 32812, 32816, 32835, 32870, 32891, 32921, 32924, 32932, 32935, 32952, - 157310, 32965, 32981, 32998, 33037, 33013, 33019, 17390, 33077, 33054, - 17392, 33060, 33063, 33068, 157469, 33085, 17416, 33129, 17431, 17436, - 33157, 17442, 33176, 33202, 33217, 33219, 33238, 33243, 157917, 33252, - 157930, 33260, 33277, 33279, 158063, 33284, 158173, 33305, 33314, 158238, - 33340, 33353, 33349, 158296, 17526, 17530, 33367, 158348, 33372, 33379, - 158391, 17553, 33405, 33407, 33411, 33418, 33427, {f: 2, c: 33447}, 33458, - 33460, 33466, 33468, 33506, 33512, 33527, {f: 2, c: 33543}, 33548, 33620, - 33563, 33565, 33584, 33596, 33604, 33623, 17598, 17620, 17587, - {f: 2, c: 33684}, 33691, 33693, 33737, 33744, 33748, 33757, 33765, 33785, - 33813, 158835, 33815, 33849, 33871, {f: 2, c: 33873}, {f: 2, c: 33881}, - 33884, 158941, 33893, 33912, 33916, 33921, 17677, 33943, 33958, 33982, - 17672, {f: 2, c: 33998}, 34003, 159333, 34023, 34026, 34031, 34033, 34042, - 34075, {f: 2, c: 34084}, 34091, 34127, 34159, 17731, 34129, - {f: 2, c: 34145}, 159636, 34171, 34173, 34175, 34177, 34182, 34195, 34205, - 34207, 159736, {f: 2, c: 159734}, 34236, 34247, 34250, {f: 2, c: 34264}, - 34271, 34273, 34278, 34294, 34304, 34321, 34334, 34337, 34340, 34343, - 160013, 34361, 34364, 160057, 34368, 34387, 34390, 34423, 34439, 34441, - {f: 2, c: 34460}, 34481, 34483, 34497, 34499, 34513, 34517, 34519, 34531, - 34534, 17848, 34565, 34567, 34574, 34576, 34591, 34593, 34595, 34609, - 34618, 34624, 34627, 34641, 34648, {f: 2, c: 34660}, 34674, 34684, 160731, - 160730, 34727, 34697, 34699, 34707, 34720, 160766, 17893, 34750, 160784, - 34753, 34766, 34783, 160841, 34787, {f: 2, c: 34789}, 34794, 34835, 34856, - 34862, 34866, 34876, 17935, 34890, 34904, 161301, 161300, 34921, 161329, - 34927, 34976, 35004, 35008, 161427, 35025, 35027, 17985, 35073, 161550, - 35127, 161571, 35138, 35141, 35145, 161618, 35170, 35209, 35216, 35231, - 35248, 35255, 35288, 35307, 18081, 35315, 35325, 35327, 18095, 35345, - 35348, 162181, 35361, 35381, 35390, 35397, 35405, 35416, 35502, 35472, - 35511, 35543, 35580, 162436, 35594, 35589, 35597, 35612, 35629, 18188, - 35665, 35678, 35702, 35713, 35723, {f: 2, c: 35732}, 35897, 162739, 35901, - 162750, 162759, 35909, 35919, 35927, 35945, 35949, 163000, 35987, 35986, - 35993, 18276, 35995, 36054, 36053, 163232, 36081, 163344, 36105, 36110, - 36296, 36313, 36364, 18429, 36349, 36358, 163978, 36372, 36374, - {f: 2, c: 36385}, 36391, 164027, 18454, 36406, 36409, 36436, 36450, 36461, - 36463, 36504, 36510, 36533, 36539, 164482, 18510, 164595, 36608, 36616, - 36651, 36672, 36682, 36696, 164876, 36772, 36788, 164949, 36801, 36806, - 64036, 36810, 36813, 36819, 36821, 36849, 36853, 36859, 36876, 36919, - 165227, 36931, 36957, {f: 2, c: 165320}, 36997, 37004, 37008, 37025, 18613, - 37040, 37046, 37059, 37064, 165591, 37084, 37087, 165626, 37110, 37106, - 37120, 37099, {f: 2, c: 37118}, 37124, 37126, 37144, 37150, 37175, 37177, - {f: 2, c: 37190}, 37207, 37209, 37236, 37241, 37253, 37299, 37302, - {f: 2, c: 37315}, 166217, 166214, 37356, 37377, {f: 2, c: 37398}, 166251, - 37442, 37450, 37462, 37473, 37477, 37480, 166280, {f: 2, c: 37500}, 37503, - 37513, 37517, 37527, 37529, 37535, 37547, {f: 2, c: 166330}, 37554, - {f: 2, c: 37567}, 37574, 37582, 37605, 37649, 166430, 166441, 37623, 37673, - 166513, 166467, 37713, 37722, 37739, 37745, 37747, 37793, 166553, 166605, - 37768, 37771, 37775, 37790, 37877, 166628, 166621, 37873, 37831, 37852, - 37863, 37897, {f: 2, c: 37910}, 37883, 37938, 37947, 166849, 166895, 37997, - 37999, 38265, 38278, {f: 2, c: 38284}, 167184, 167281, 38344, 167419, - 167455, 38444, {f: 2, c: 38451}, 167478, 38460, 38497, 167561, 38530, - 167659, 38554, 167730, 18919, 38579, 38586, 38589, 18938, 167928, 38616, - 38618, 38621, 18948, 38676, 38691, 18985, 38710, 38721, 38727, 38743, - 38747, 38762, 168608, 168625, 38806, 38814, {f: 2, c: 38833}, 38846, 38860, - 38865, 38868, 38872, 38881, 38897, 38916, 38925, 38932, 38934, 19132, - 169104, {f: 2, c: 38962}, 38949, 38983, 39014, 39083, 39085, 39088, 169423, - 39095, {f: 2, c: 39099}, 39106, 39111, 39115, 39137, 39139, 39146, - {f: 2, c: 39152}, 39155, 39176, 19259, 169712, {f: 2, c: 39190}, 169753, - {f: 3, c: 39194}, 169808, 39217, {f: 3, c: 39226}, 39233, 39238, 39246, - 39264, 39331, 39334, 39357, 39359, 39363, 39380, 39385, 39390, 170182, - 39408, 39417, 39420, 39434, 39441, 39450, 39456, 39473, 39492, 39500, - 39512, 19394, 39599, 19402, 39607, 19410, 39609, 170610, 39622, 39632, - 39634, 39637, 39648, 39653, 39657, 39692, 39696, 39698, 39702, 39708, - 39723, 39741, 19488, 39755, 39779, 39781, {f: 2, c: 39787}, - {f: 2, c: 39798}, 39846, 39852, 171483, 39858, 39864, 39870, 39923, 39896, - 39901, 39914, 39919, 39918, 171541, 171658, 171593, 39958, - {f: 3, c: 39960}, 39965, 39970, 39977, 171716, 39985, 39991, 40005, 40028, - 171753, {f: 2, c: 40009}, 171739, 40020, 40024, 40027, 40029, 40031, - {f: 3, c: 40041}, {f: 2, c: 40045}, 40050, 40053, 40058, 40166, 40178, - 40203, [171982, 171991], 40209, {f: 2, c: 40215}, 172079, 19652, 172058, - 40242, 19665, 40266, 40287, 40290, 172281, 172162, 40307, {f: 2, c: 40310}, - 40324, 40345, 40353, 40383, 40373, 40377, 40381, 40393, 40410, 40416, - 40419, 19719, 40458, 40450, 40461, 40476, 40571, 139800, 40576, 40581, - 40603, 172940, 40637, 173111, 40671, 40703, 40706, 19831, 40707, 40762, - 40765, 40774, 40787, 40789, 40792, 173553, 40797, 173570, 40809, 40813, - 40816, 173746, 11948, 13844, 14509, 15820, 16348, 17854, 17936, 19326, - 19512, 19681, 19980, {f: 2, c: 20003}, 20089, 20211, 20236, 20249, 20267, - 20270, 20273, 20356, 20382, 20407, 20484, 20492, 20556, 20575, 20578, - 20599, 20622, 20638, 20642, 20675, 20712, 20721, 20734, 20743, - {f: 3, c: 20748}, 20787, 20792, 20852, 20868, 20920, 20922, 20936, 20943, - 20945, {f: 2, c: 20947}, 20952, 20959, 20997, 21030, 21032, 21035, - {f: 2, c: 21041}, 21045, 21052, 21082, 21088, 21102, {f: 2, c: 21112}, - 21130, 21132, 21217, 21225, 21233, 21251, 21265, 21279, 21293, 21298, - 21309, 21349, 21357, 21369, 21374, 21396, 21401, 21418, 21423, 21434, - 21441, {f: 2, c: 21444}, 21472, 21523, 21546, 21553, {f: 2, c: 21556}, - 21580, 21671, 21674, 21681, 21691, 21710, 21738, 21756, 21765, 21768, - 21781, 21799, 21802, 21814, 21841, 21862, 21903, 21906, 21908, 21924, - 21938, 21955, 21958, 21971, 21979, 21996, 21998, 22001, 22006, 22008, - 22021, 22029, {f: 2, c: 22033}, 22060, 22069, 22073, 22093, 22100, 22149, - 22175, 22182, 22199, 22220, 22223, 22233, 22241, 22251, 22253, 22257, - 22279, 22284, {f: 2, c: 22298}, 22301, 22316, 22318, {f: 2, c: 22333}, - 22367, 22379, 22381, 22394, 22403, 22423, 22446, 22485, 22503, 22541, - 22566, 22605, 22607, 22623, 22637, 22655, 22657, 22680, 22716, 22815, - 22819, 22873, 22905, 22935, 22959, 22963, 23007, 23025, 23032, 23218, - 23224, 23274, 23286, 23323, 23325, 23329, 23352, 23479, 23511, 23520, - 23583, 23594, 23596, 23606, 23641, 23644, 23661, 23773, 23809, 23860, - 23869, 23897, 23934, 23939, 24007, 24057, 24104, 24114, 24117, 24155, - 24168, 24170, 24183, 24192, 24203, 24243, 24253, 24273, {f: 2, c: 24276}, - 24397, 24492, 24554, 24583, 24649, 24660, 24679, 24763, 24772, 24829, - 24842, 24854, 24874, 24886, 24926, 24932, 24955, 24957, 24959, 24989, - 25016, 25052, 25058, 25061, 25064, 25092, 25095, 25137, 25145, 25149, - 25210, 25232, 25256, 25306, 25332, 25366, 25386, 25398, 25414, 25419, - 25427, 25457, 25461, 25471, 25474, 25482, {f: 2, c: 25518}, 25578, - {f: 2, c: 25592}, 25618, 25624, 25632, 25636, 25642, 25653, 25661, 25663, - 25682, 25695, 25716, 25744, {f: 2, c: 25752}, 25772, 25779, 25837, 25840, - 25883, 25887, 25902, 25929, 25952, 26002, 26005, 26036, 26046, 26056, - 26062, 26064, 26079, 26238, {f: 2, c: 26251}, 26291, 26304, 26319, 26405, - 26421, 26453, 26496, 26511, 26513, 26532, 26545, 26549, 26558, 26664, - 26758, 26859, 26869, 26903, 26931, 26936, 26971, 26981, 27048, 27051, - 27055, 27109, 27121, 27210, 27221, 27239, 27249, 27311, {f: 2, c: 27336}, - 27395, 27451, 27455, {f: 2, c: 27517}, 27568, 27639, 27641, 27652, 27657, - 27661, 27692, 27722, 27730, 27732, 27769, 27820, 27828, 27858, 28001, - 28028, 28089, 28144, 28229, 28275, 28283, 28285, 28297, 28348, - {f: 2, c: 28378}, 28454, 28457, 28464, 28551, 28573, 28590, 28599, 28685, - 28704, 28745, 28824, 28848, {f: 2, c: 28885}, 28997, 29106, 29172, 29207, - 29215, 29251, {f: 2, c: 29263}, 29274, 29280, 29288, 29303, 29316, 29385, - 29413, 29428, 29442, 29451, 29470, 29474, {f: 2, c: 29498}, 29517, 29528, - 29543, 29810, 29871, 29919, 29924, 29940, 29947, 29974, 29985, 30015, - 30046, 30105, 30116, 30145, 30148, 30156, 30167, 30172, 30177, 30191, - 30212, 30220, 30237, 30258, 30264, 30277, 30282, 30303, 30381, 30397, - 30425, 30443, 30448, 30457, 30464, 30478, 30498, 30504, 30511, 30521, - 30526, 30533, 30538, 30543, 30558, 30564, 30567, 30572, 30596, - {f: 2, c: 30604}, 30614, 30631, 30639, 30647, 30654, 30665, 30673, 30681, - 30705, 30775, 30812, 30846, 30872, 30881, 30897, 30899, 30921, 30931, - 30988, 31007, {f: 2, c: 31015}, 31039, 31042, 31060, 31083, 31100, 31147, - 31172, 31210, 31234, 31244, 31280, 31290, 31300, 31360, 31366, 31380, - 31413, 31421, 31486, 31531, 31607, 31648, 31660, 31664, 31720, 31730, - 31736, 31740, 31742, 31753, 31784, 31791, 31810, {f: 2, c: 31826}, - {f: 3, c: 31835}, 31858, 31869, 31879, 31902, 31930, 31943, 31955, 31962, - 32060, 32077, 32130, 32133, 32141, 32145, 32158, 32179, 32185, 32208, - 32229, {f: 2, c: 32245}, 32303, 32310, 32324, 32367, 32376, 32385, 32573, - 32603, 32605, 32613, 32625, {f: 2, c: 32639}, 32651, 32674, - {f: 3, c: 32765}, 32775, 32781, 32798, 32825, 32904, 32910, 32975, 32980, - 33005, 33008, 33015, 33018, 33022, 33027, 33047, 33072, 33111, 33135, - 33139, 33163, 33168, 33179, 33182, 33227, 33237, {f: 2, c: 33245}, 33249, - 33263, 33270, 33280, 33291, {f: 2, c: 33299}, 33306, 33338, 33348, 33389, - 33412, 33417, 33425, 33450, 33456, 33488, 33514, 33519, 33526, 33622, - 33656, 33784, 33788, 33880, 33939, 33969, 33981, 34043, 34118, 34134, - 34141, 34181, 34200, 34370, 34374, 34496, 34580, 34594, 34606, 34617, - 34653, 34683, 34700, 34702, {f: 2, c: 34711}, 34718, 34723, 34734, 34751, - 34761, 34778, 34840, 34843, 34861, 34874, 34885, 34891, 34894, 34901, - 34906, 34926, {f: 3, c: 34970}, 35021, 35040, 35055, {f: 2, c: 35086}, - 35110, 35125, 35162, 35164, 35179, 35184, 35196, 35237, 35253, 35260, - 35285, 35401, 35415, 35431, 35454, 35462, 35478, 35510, 35529, 35537, - 35549, 35564, 35573, 35590, 35599, 35601, 35653, 35666, 35693, 35704, - 35708, 35710, 35717, 35743, 35915, 35923, 35963, 36026, 36037, 36041, - 36050, 36076, 36085, 36087, 36097, 36099, 36119, 36124, 36206, 36241, - 36255, 36267, 36274, 36309, 36327, {f: 2, c: 36337}, 36340, 36353, 36363, - 36390, 36401, {f: 2, c: 36416}, 36429, 36431, 36444, 36449, 36457, 36465, - 36469, 36471, 36489, 36496, 36501, 36506, 36519, 36521, 36525, 36584, - 36592, 36615, 36632, 36645, 36647, 36652, 36661, 36666, 36675, 36679, - 36689, 36693, {f: 3, c: 36768}, 36773, 36868, 36891, 36911, 36940, 36955, - 36976, 36980, 36985, 37003, 37016, 37024, 37042, 37053, 37065, 37104, - 37125, 37157, 37210, 37223, 37242, 37258, 37265, 37269, 37296, 37307, - 37309, 37314, 37317, 37376, 37385, 37411, 37494, 37518, 37551, - {f: 2, c: 37563}, 37569, 37571, 37573, 37576, 37652, 37683, 37686, 37720, - 37759, 37762, 37770, 37819, 37836, 37862, 37881, 37890, {f: 2, c: 37901}, - 37934, 37964, 38280, 38305, 38335, 38342, 38345, {f: 2, c: 38353}, 38368, - 38372, 38374, 38436, 38449, 38456, 38461, 38484, 38516, 38523, 38527, - 38529, 38531, 38537, 38550, 38574, 38659, 38683, {f: 2, c: 38689}, 38696, - 38705, 38759, 38774, 38781, 38783, 38809, 38815, 38828, 38841, 38861, - 38880, 38895, 38919, 38950, 38958, {f: 2, c: 39010}, 39092, 39109, 39170, - 39185, 39189, 39221, 39240, 39252, 39262, 39393, 39436, 39440, 39459, - 39489, 39505, {f: 2, c: 39613}, 39681, 39689, 39691, {f: 2, c: 39693}, - 39705, 39733, 39752, 39765, 39784, 39808, 39814, 39824, 39837, 39856, - 39871, 39880, 39935, 39938, 39964, 39989, 40004, 40022, 40033, 40040, - 40240, 40253, 40298, 40315, 40421, 40425, 40435, 40570, {f: 3, c: 40578}, - 40624, 40676, 40688, 40690, 40713, 40719, 40724, 40731, 40738, 40742, - {f: 2, c: 40746}, 40756, 40794, 40815, 40862, 40869, 131317, 151044, - 151538, 163187, 194581, 194630, 194713, 194726, 194789, 195038, 13790, - {s: 4}, 172722, 0, 0, 131416, {s: 4}, 132529, 0, 0, 132844, {s: 6}, 134488, - {s: 21}, 154060, {s: 9}, 14756, 14776, 142914, 0, 0, 14940, 0, 0, 143339, - 0, 0, 162228, 0, 15044, 15051, {s: 5}, 14981, {s: 8}, 15347, 27384, {s: 5}, - 15665, {s: 9}, 147531, 0, 15936, 14497, {s: 34}, 158878, {s: 12}, 18207, - 162876, {s: 4}, 18462, {s: 71}, 39709, 39724, 20482, 20958, 21255, 23532, - 63784, 26142, 63785, 28746, 64021, 21857, 27706, 31328, 156492, 34819, - 38315, 38741, 171581, 173594], - 'Adobe-Korea1': [{f: 95, c: 32}, 8361, 8208, 169, 0, 0, [12288, 12644], - {f: 2, c: 12289}, 12539, 8229, [8230, 8943], 168, 12291, {f: 2, c: 8211}, - 8214, 65340, 65374, {f: 2, c: 8216}, {f: 2, c: 8220}, {f: 2, c: 12308}, - {f: 10, c: 12296}, 177, 215, 247, 8800, {f: 2, c: 8804}, 8734, 8756, 176, - {f: 2, c: 8242}, 8451, 8491, {f: 2, c: 65504}, 65509, 9794, 9792, 8736, - 8869, 8978, 8706, 8711, 8801, 8786, 167, 8251, 9734, 9733, 9675, 9679, - 9678, 9671, 9670, 9633, 9632, 9651, 9650, 9661, 9660, 8594, - {f: 2, c: 8592}, {f: 2, c: 8595}, 12307, 171, 187, 8730, 8765, 8733, 8757, - {f: 2, c: 8747}, 8712, 8715, {f: 2, c: 8838}, {f: 2, c: 8834}, 8746, 8745, - {f: 2, c: 8743}, 65506, 8658, 8660, 8704, 8707, 180, 732, 711, 728, 733, - 730, 729, 184, 731, 161, 191, 8758, 8750, 8721, 8719, 164, 8457, 8240, - 9665, 9664, 9655, 9654, 9828, {f: 2, c: 9824}, 9829, 9831, 9827, 9673, - 9672, 9635, {f: 2, c: 9680}, 9618, {f: 2, c: 9636}, 9640, 9639, 9638, 9641, - 9832, 9743, 9742, 9756, 9758, 182, {f: 2, c: 8224}, 8597, 8599, 8601, 8598, - 8600, 9837, {f: 2, c: 9833}, 9836, 12927, 12828, 8470, 13255, 8482, 13250, - 13272, 8481, {f: 59, c: 65281}, 65510, {f: 33, c: 65341}, 65507, - {f: 51, c: 12593}, {f: 42, c: 12645}, {f: 10, c: 8560}, {f: 10, c: 8544}, - {f: 17, c: 913}, {f: 7, c: 931}, {f: 17, c: 945}, {f: 7, c: 963}, 9472, - 9474, 9484, 9488, 9496, 9492, 9500, 9516, 9508, 9524, 9532, 9473, 9475, - 9487, 9491, 9499, 9495, 9507, 9523, 9515, 9531, 9547, 9504, 9519, 9512, - 9527, 9535, 9501, 9520, 9509, 9528, 9538, 9490, 9489, 9498, 9497, 9494, - 9493, 9486, 9485, {f: 2, c: 9502}, {f: 2, c: 9505}, {f: 2, c: 9510}, - {f: 2, c: 9513}, {f: 2, c: 9517}, {f: 2, c: 9521}, {f: 2, c: 9525}, - {f: 2, c: 9529}, {f: 2, c: 9533}, {f: 2, c: 9536}, {f: 8, c: 9539}, - {f: 3, c: 13205}, 8467, 13208, 13252, {f: 4, c: 13219}, {f: 10, c: 13209}, - 13258, {f: 3, c: 13197}, 13263, {f: 2, c: 13192}, 13256, {f: 2, c: 13223}, - {f: 10, c: 13232}, {f: 5, c: 13184}, {f: 6, c: 13242}, {f: 5, c: 13200}, - 8486, {f: 2, c: 13248}, {f: 3, c: 13194}, 13270, 13253, {f: 3, c: 13229}, - 13275, {f: 4, c: 13225}, 13277, 13264, 13267, 13251, 13257, 13276, 13254, - 198, 208, 170, 294, 306, 319, 321, 216, 338, 186, 222, 358, 330, - {f: 28, c: 12896}, {f: 26, c: 9424}, {f: 15, c: 9312}, 189, - {f: 2, c: 8531}, 188, 190, {f: 4, c: 8539}, 230, 273, 240, 295, 305, 307, - 312, 320, 322, 248, 339, 223, 254, 359, 331, 329, {f: 28, c: 12800}, - {f: 26, c: 9372}, {f: 15, c: 9332}, 185, {f: 2, c: 178}, 8308, 8319, - {f: 4, c: 8321}, {f: 83, c: 12353}, {f: 86, c: 12449}, {f: 6, c: 1040}, - 1025, {f: 32, c: 1046}, 1105, {f: 26, c: 1078}, {f: 2, c: 44032}, 44036, - {f: 4, c: 44039}, {f: 8, c: 44048}, {f: 5, c: 44057}, 44064, 44068, - {f: 2, c: 44076}, {f: 3, c: 44079}, {f: 2, c: 44088}, 44092, 44096, 44107, - 44109, 44116, 44120, 44124, {f: 2, c: 44144}, 44148, {f: 2, c: 44151}, - 44154, {f: 2, c: 44160}, {f: 4, c: 44163}, {f: 4, c: 44169}, 44176, 44180, - {f: 2, c: 44188}, {f: 3, c: 44191}, {f: 3, c: 44200}, 44204, - {f: 2, c: 44207}, {f: 2, c: 44216}, {f: 3, c: 44219}, 44225, 44228, 44232, - 44236, 44245, 44247, {f: 2, c: 44256}, 44260, {f: 2, c: 44263}, 44266, - 44268, {f: 3, c: 44271}, 44275, {f: 2, c: 44277}, {f: 2, c: 44284}, 44288, - 44292, 44294, {f: 2, c: 44300}, 44303, 44305, 44312, 44316, 44320, 44329, - {f: 2, c: 44332}, {f: 2, c: 44340}, 44344, 44348, {f: 2, c: 44356}, 44359, - 44361, 44368, 44372, 44376, 44385, 44387, {f: 2, c: 44396}, 44400, - {f: 4, c: 44403}, {f: 3, c: 44411}, 44415, {f: 2, c: 44417}, - {f: 2, c: 44424}, 44428, 44432, {f: 2, c: 44444}, 44452, 44471, - {f: 2, c: 44480}, 44484, 44488, {f: 2, c: 44496}, 44499, 44508, 44512, - 44516, {f: 2, c: 44536}, 44540, {f: 3, c: 44543}, {f: 2, c: 44552}, 44555, - 44557, 44564, {f: 2, c: 44592}, 44596, {f: 2, c: 44599}, 44602, - {f: 2, c: 44608}, 44611, {f: 2, c: 44613}, 44618, {f: 3, c: 44620}, 44624, - 44628, 44630, {f: 2, c: 44636}, {f: 3, c: 44639}, 44645, {f: 2, c: 44648}, - 44652, 44656, {f: 2, c: 44664}, {f: 3, c: 44667}, {f: 2, c: 44676}, 44684, - {f: 3, c: 44732}, 44736, 44740, {f: 2, c: 44748}, {f: 3, c: 44751}, - {f: 2, c: 44760}, 44764, 44776, 44779, 44781, 44788, 44792, 44796, - {f: 2, c: 44807}, 44813, 44816, {f: 2, c: 44844}, 44848, 44850, 44852, - {f: 2, c: 44860}, 44863, {f: 3, c: 44865}, {f: 2, c: 44872}, 44880, - {f: 2, c: 44892}, {f: 2, c: 44900}, 44921, 44928, 44932, 44936, - {f: 2, c: 44944}, 44949, 44956, {f: 2, c: 44984}, 44988, 44992, - {f: 3, c: 44999}, 45003, {f: 2, c: 45005}, 45012, 45020, {f: 2, c: 45032}, - {f: 2, c: 45040}, 45044, 45048, {f: 2, c: 45056}, 45060, 45068, 45072, - 45076, {f: 2, c: 45084}, 45096, {f: 2, c: 45124}, 45128, 45130, 45132, - 45134, {f: 3, c: 45139}, 45143, 45145, 45149, {f: 2, c: 45180}, 45184, - 45188, {f: 2, c: 45196}, 45199, 45201, {f: 3, c: 45208}, 45212, - {f: 4, c: 45215}, {f: 2, c: 45224}, {f: 5, c: 45227}, 45233, - {f: 3, c: 45235}, 45240, 45244, {f: 2, c: 45252}, {f: 3, c: 45255}, - {f: 2, c: 45264}, 45268, 45272, 45280, 45285, {f: 2, c: 45320}, - {f: 2, c: 45323}, 45328, {f: 2, c: 45330}, {f: 2, c: 45336}, - {f: 3, c: 45339}, {f: 3, c: 45347}, 45352, 45356, {f: 2, c: 45364}, - {f: 3, c: 45367}, {f: 2, c: 45376}, 45380, 45384, {f: 2, c: 45392}, - {f: 2, c: 45396}, 45400, 45404, 45408, {f: 2, c: 45432}, 45436, 45440, - 45442, {f: 2, c: 45448}, 45451, 45453, {f: 3, c: 45458}, 45464, 45468, - 45480, 45516, 45520, 45524, {f: 2, c: 45532}, 45535, {f: 2, c: 45544}, - 45548, 45552, 45561, 45563, 45565, {f: 2, c: 45572}, 45576, - {f: 2, c: 45579}, {f: 2, c: 45588}, 45591, 45593, 45600, 45620, 45628, - 45656, 45660, 45664, {f: 2, c: 45672}, {f: 2, c: 45684}, 45692, - {f: 2, c: 45700}, 45705, {f: 2, c: 45712}, 45716, {f: 3, c: 45720}, - {f: 2, c: 45728}, 45731, {f: 2, c: 45733}, 45738, 45740, 45744, 45748, - {f: 2, c: 45768}, 45772, 45776, 45778, {f: 2, c: 45784}, 45787, 45789, - 45794, {f: 3, c: 45796}, 45800, {f: 5, c: 45803}, {f: 3, c: 45811}, - {f: 5, c: 45815}, {f: 3, c: 45823}, 45828, 45832, {f: 2, c: 45840}, - {f: 3, c: 45843}, 45852, {f: 3, c: 45908}, 45912, {f: 2, c: 45915}, - {f: 2, c: 45918}, {f: 2, c: 45924}, 45927, 45929, 45931, 45934, - {f: 2, c: 45936}, 45940, 45944, {f: 2, c: 45952}, {f: 3, c: 45955}, 45964, - 45968, 45972, {f: 2, c: 45984}, 45992, 45996, {f: 2, c: 46020}, 46024, - {f: 2, c: 46027}, 46030, 46032, {f: 2, c: 46036}, 46039, 46041, 46043, - 46045, 46048, 46052, 46056, 46076, 46096, 46104, 46108, 46112, - {f: 2, c: 46120}, 46123, 46132, {f: 2, c: 46160}, 46164, 46168, - {f: 2, c: 46176}, 46179, 46181, 46188, 46208, 46216, 46237, 46244, 46248, - 46252, 46261, 46263, 46265, 46272, 46276, 46280, 46288, 46293, - {f: 2, c: 46300}, 46304, {f: 2, c: 46307}, 46310, {f: 2, c: 46316}, 46319, - 46321, 46328, {f: 2, c: 46356}, 46360, {f: 2, c: 46363}, {f: 2, c: 46372}, - {f: 4, c: 46375}, {f: 2, c: 46384}, 46388, 46392, {f: 2, c: 46400}, - {f: 3, c: 46403}, {f: 3, c: 46411}, 46416, 46420, {f: 2, c: 46428}, - {f: 3, c: 46431}, {f: 2, c: 46496}, 46500, 46504, {f: 2, c: 46506}, - {f: 2, c: 46512}, {f: 3, c: 46515}, {f: 3, c: 46523}, 46528, 46532, - {f: 2, c: 46540}, {f: 3, c: 46543}, 46552, 46572, {f: 2, c: 46608}, 46612, - 46616, 46629, 46636, 46644, 46664, 46692, 46696, {f: 2, c: 46748}, 46752, - 46756, {f: 2, c: 46763}, 46769, 46804, 46832, 46836, 46840, - {f: 2, c: 46848}, 46853, {f: 2, c: 46888}, 46892, {f: 2, c: 46895}, - {f: 2, c: 46904}, 46907, 46916, 46920, 46924, {f: 2, c: 46932}, 46944, - 46948, 46952, {f: 2, c: 46960}, 46963, 46965, {f: 2, c: 46972}, 46976, - 46980, {f: 2, c: 46988}, {f: 4, c: 46991}, {f: 4, c: 46998}, 47004, 47008, - {f: 2, c: 47016}, {f: 3, c: 47019}, {f: 2, c: 47028}, 47032, 47047, 47049, - {f: 2, c: 47084}, 47088, 47092, {f: 2, c: 47100}, {f: 3, c: 47103}, - {f: 3, c: 47111}, 47116, 47120, {f: 2, c: 47128}, 47131, 47133, - {f: 2, c: 47140}, 47144, 47148, {f: 2, c: 47156}, {f: 3, c: 47159}, 47168, - 47172, 47185, 47187, {f: 2, c: 47196}, 47200, 47204, {f: 2, c: 47212}, - 47215, 47217, 47224, 47228, 47245, 47272, 47280, 47284, 47288, - {f: 2, c: 47296}, 47299, 47301, 47308, 47312, 47316, 47325, 47327, 47329, - {f: 2, c: 47336}, 47340, 47344, {f: 2, c: 47352}, 47355, 47357, 47364, - 47384, 47392, {f: 2, c: 47420}, 47424, 47428, 47436, 47439, 47441, - {f: 2, c: 47448}, 47452, 47456, {f: 2, c: 47464}, 47467, 47469, - {f: 2, c: 47476}, 47480, 47484, {f: 2, c: 47492}, 47495, {f: 2, c: 47497}, - {f: 2, c: 47501}, {f: 2, c: 47532}, 47536, 47540, {f: 2, c: 47548}, 47551, - 47553, {f: 2, c: 47560}, 47564, {f: 5, c: 47566}, {f: 2, c: 47576}, 47579, - {f: 2, c: 47581}, 47585, {f: 3, c: 47587}, 47592, 47596, {f: 2, c: 47604}, - {f: 4, c: 47607}, {f: 2, c: 47616}, 47624, 47637, {f: 2, c: 47672}, 47676, - 47680, 47682, {f: 2, c: 47688}, 47691, {f: 2, c: 47693}, {f: 3, c: 47699}, - 47704, 47708, {f: 2, c: 47716}, {f: 3, c: 47719}, {f: 2, c: 47728}, 47732, - 47736, {f: 3, c: 47747}, 47751, 47756, {f: 2, c: 47784}, {f: 2, c: 47787}, - 47792, 47794, {f: 2, c: 47800}, 47803, 47805, 47812, 47816, - {f: 2, c: 47832}, 47868, 47872, 47876, 47885, 47887, 47889, 47896, 47900, - 47904, 47913, 47915, {f: 3, c: 47924}, 47928, {f: 4, c: 47931}, - {f: 2, c: 47940}, 47943, 47945, 47949, {f: 2, c: 47951}, 47956, 47960, - 47969, 47971, 47980, 48008, 48012, 48016, 48036, 48040, 48044, 48052, - 48055, 48064, 48068, 48072, 48080, 48083, {f: 2, c: 48120}, 48124, - {f: 2, c: 48127}, 48130, {f: 2, c: 48136}, {f: 3, c: 48139}, 48143, 48145, - {f: 5, c: 48148}, {f: 5, c: 48155}, {f: 2, c: 48164}, 48167, 48169, 48173, - {f: 2, c: 48176}, 48180, 48184, {f: 2, c: 48192}, {f: 3, c: 48195}, 48201, - {f: 2, c: 48204}, 48208, 48221, {f: 2, c: 48260}, 48264, {f: 2, c: 48267}, - 48270, {f: 2, c: 48276}, 48279, {f: 2, c: 48281}, {f: 2, c: 48288}, 48292, - {f: 2, c: 48295}, {f: 2, c: 48304}, {f: 3, c: 48307}, {f: 2, c: 48316}, - 48320, 48324, 48333, {f: 3, c: 48335}, 48341, 48344, 48348, - {f: 3, c: 48372}, 48376, 48380, {f: 2, c: 48388}, 48391, 48393, 48400, - 48404, 48420, 48428, 48448, {f: 2, c: 48456}, 48460, 48464, - {f: 2, c: 48472}, 48484, 48488, {f: 2, c: 48512}, 48516, {f: 4, c: 48519}, - {f: 2, c: 48528}, 48531, 48533, {f: 2, c: 48537}, 48540, 48548, 48560, - 48568, {f: 2, c: 48596}, 48600, 48604, 48617, 48624, 48628, 48632, 48640, - 48643, 48645, {f: 2, c: 48652}, 48656, 48660, {f: 2, c: 48668}, 48671, - {f: 2, c: 48708}, 48712, 48716, 48718, {f: 2, c: 48724}, 48727, - {f: 3, c: 48729}, {f: 2, c: 48736}, 48740, 48744, 48746, {f: 2, c: 48752}, - {f: 3, c: 48755}, {f: 3, c: 48763}, 48768, 48772, {f: 2, c: 48780}, - {f: 3, c: 48783}, {f: 2, c: 48792}, 48808, {f: 2, c: 48848}, 48852, - {f: 2, c: 48855}, 48864, {f: 3, c: 48867}, 48876, 48897, {f: 2, c: 48904}, - {f: 2, c: 48920}, {f: 3, c: 48923}, {f: 2, c: 48960}, 48964, 48968, - {f: 2, c: 48976}, 48981, 49044, 49072, 49093, {f: 2, c: 49100}, 49104, - 49108, 49116, 49119, 49121, 49212, 49233, 49240, 49244, 49248, - {f: 2, c: 49256}, {f: 2, c: 49296}, 49300, 49304, {f: 2, c: 49312}, 49315, - 49317, {f: 2, c: 49324}, {f: 2, c: 49327}, {f: 4, c: 49331}, - {f: 2, c: 49340}, {f: 3, c: 49343}, 49349, {f: 2, c: 49352}, 49356, 49360, - {f: 2, c: 49368}, {f: 3, c: 49371}, {f: 2, c: 49380}, 49384, 49388, - {f: 2, c: 49396}, 49399, 49401, 49408, 49412, 49416, 49424, 49429, - {f: 5, c: 49436}, {f: 2, c: 49443}, {f: 2, c: 49446}, {f: 2, c: 49452}, - {f: 3, c: 49455}, 49462, {f: 2, c: 49464}, 49468, 49472, {f: 2, c: 49480}, - {f: 3, c: 49483}, {f: 2, c: 49492}, 49496, 49500, {f: 2, c: 49508}, - {f: 3, c: 49511}, 49520, 49524, 49528, 49541, {f: 3, c: 49548}, 49552, - 49556, 49558, {f: 2, c: 49564}, 49567, 49569, 49573, {f: 2, c: 49576}, - 49580, 49584, 49597, 49604, 49608, 49612, 49620, {f: 2, c: 49623}, 49632, - 49636, 49640, {f: 2, c: 49648}, 49651, {f: 2, c: 49660}, 49664, 49668, - {f: 2, c: 49676}, 49679, 49681, {f: 2, c: 49688}, 49692, {f: 2, c: 49695}, - {f: 2, c: 49704}, 49707, 49709, 49711, {f: 2, c: 49713}, 49716, 49736, - {f: 2, c: 49744}, 49748, 49752, 49760, 49765, {f: 2, c: 49772}, 49776, - 49780, {f: 2, c: 49788}, 49791, 49793, {f: 2, c: 49800}, 49808, 49816, - 49819, 49821, {f: 2, c: 49828}, 49832, {f: 2, c: 49836}, {f: 2, c: 49844}, - 49847, 49849, {f: 2, c: 49884}, 49888, {f: 2, c: 49891}, {f: 3, c: 49899}, - 49903, 49905, 49910, {f: 2, c: 49912}, {f: 2, c: 49915}, 49920, - {f: 2, c: 49928}, {f: 2, c: 49932}, {f: 3, c: 49939}, 49944, 49948, - {f: 2, c: 49956}, {f: 2, c: 49960}, 49989, {f: 2, c: 50024}, 50028, 50032, - 50034, {f: 2, c: 50040}, {f: 2, c: 50044}, 50052, 50056, 50060, 50112, - {f: 2, c: 50136}, 50140, {f: 2, c: 50143}, 50146, {f: 2, c: 50152}, 50157, - {f: 2, c: 50164}, 50168, 50184, 50192, 50212, 50220, 50224, 50228, - {f: 2, c: 50236}, 50248, {f: 2, c: 50276}, 50280, 50284, {f: 2, c: 50292}, - 50297, 50304, 50324, 50332, 50360, 50364, 50409, {f: 2, c: 50416}, 50420, - 50424, 50426, {f: 3, c: 50431}, 50444, 50448, 50452, 50460, - {f: 2, c: 50472}, 50476, 50480, {f: 2, c: 50488}, 50491, 50493, - {f: 2, c: 50500}, {f: 3, c: 50504}, {f: 3, c: 50508}, {f: 3, c: 50515}, - {f: 3, c: 50519}, {f: 2, c: 50525}, {f: 2, c: 50528}, 50532, 50536, - {f: 2, c: 50544}, {f: 3, c: 50547}, {f: 2, c: 50556}, 50560, 50564, 50567, - {f: 2, c: 50572}, 50575, 50577, 50581, {f: 2, c: 50583}, 50588, 50592, - 50601, {f: 2, c: 50612}, {f: 2, c: 50616}, {f: 4, c: 50619}, - {f: 7, c: 50628}, 50636, 50638, {f: 2, c: 50640}, 50644, 50648, - {f: 2, c: 50656}, 50659, 50661, {f: 3, c: 50668}, 50672, 50676, - {f: 2, c: 50678}, {f: 6, c: 50684}, {f: 4, c: 50693}, 50700, 50704, - {f: 2, c: 50712}, {f: 2, c: 50715}, {f: 2, c: 50724}, 50728, - {f: 3, c: 50732}, 50736, {f: 3, c: 50739}, 50743, 50745, 50747, - {f: 2, c: 50752}, 50756, 50760, {f: 2, c: 50768}, {f: 3, c: 50771}, - {f: 2, c: 50780}, 50784, 50796, 50799, 50801, {f: 2, c: 50808}, 50812, - 50816, {f: 2, c: 50824}, 50827, 50829, {f: 2, c: 50836}, 50840, 50844, - {f: 2, c: 50852}, 50855, 50857, {f: 2, c: 50864}, 50868, {f: 3, c: 50872}, - {f: 2, c: 50880}, 50883, 50885, {f: 2, c: 50892}, 50896, 50900, - {f: 2, c: 50908}, {f: 2, c: 50912}, {f: 2, c: 50920}, 50924, 50928, - {f: 2, c: 50936}, 50941, {f: 2, c: 50948}, 50952, 50956, {f: 2, c: 50964}, - 50967, 50969, {f: 2, c: 50976}, 50980, 50984, {f: 2, c: 50992}, 50995, - 50997, 50999, {f: 2, c: 51004}, 51008, 51012, 51018, {f: 2, c: 51020}, - 51023, {f: 8, c: 51025}, 51036, 51040, 51048, 51051, {f: 2, c: 51060}, - 51064, {f: 3, c: 51068}, {f: 3, c: 51075}, {f: 4, c: 51079}, 51086, - {f: 2, c: 51088}, 51092, {f: 3, c: 51094}, 51098, {f: 2, c: 51104}, - {f: 4, c: 51107}, {f: 2, c: 51116}, 51120, 51124, {f: 2, c: 51132}, - {f: 3, c: 51135}, {f: 2, c: 51144}, 51148, 51150, 51152, 51160, 51165, - 51172, 51176, 51180, {f: 2, c: 51200}, 51204, 51208, 51210, - {f: 2, c: 51216}, 51219, {f: 2, c: 51221}, {f: 2, c: 51228}, 51232, 51236, - {f: 2, c: 51244}, 51247, 51249, 51256, 51260, 51264, {f: 2, c: 51272}, - {f: 2, c: 51276}, 51284, {f: 2, c: 51312}, 51316, 51320, 51322, - {f: 2, c: 51328}, 51331, {f: 3, c: 51333}, {f: 3, c: 51339}, 51348, 51357, - 51359, 51361, 51368, {f: 2, c: 51388}, 51396, 51400, 51404, - {f: 2, c: 51412}, 51415, 51417, {f: 2, c: 51424}, 51428, 51445, - {f: 2, c: 51452}, 51456, {f: 3, c: 51460}, {f: 2, c: 51468}, 51471, 51473, - 51480, 51500, 51508, {f: 2, c: 51536}, 51540, 51544, {f: 2, c: 51552}, - 51555, 51564, 51568, 51572, 51580, {f: 2, c: 51592}, 51596, 51600, - {f: 2, c: 51608}, 51611, 51613, {f: 2, c: 51648}, 51652, {f: 2, c: 51655}, - 51658, {f: 2, c: 51664}, 51667, {f: 2, c: 51669}, {f: 2, c: 51673}, - {f: 2, c: 51676}, 51680, 51682, 51684, 51687, {f: 2, c: 51692}, - {f: 3, c: 51695}, {f: 2, c: 51704}, 51708, 51712, {f: 2, c: 51720}, - {f: 3, c: 51723}, 51732, 51736, 51753, {f: 2, c: 51788}, 51792, 51796, - {f: 2, c: 51804}, {f: 3, c: 51807}, 51816, 51837, 51844, 51864, - {f: 2, c: 51900}, 51904, 51908, {f: 2, c: 51916}, 51919, 51921, 51923, - {f: 2, c: 51928}, 51936, 51948, 51956, 51976, 51984, 51988, 51992, - {f: 2, c: 52000}, 52033, {f: 2, c: 52040}, 52044, 52048, {f: 2, c: 52056}, - 52061, 52068, {f: 2, c: 52088}, 52124, 52152, 52180, 52196, 52199, 52201, - {f: 2, c: 52236}, 52240, 52244, {f: 2, c: 52252}, {f: 2, c: 52257}, - {f: 3, c: 52263}, 52268, 52270, 52272, {f: 2, c: 52280}, {f: 4, c: 52283}, - {f: 2, c: 52292}, 52296, 52300, {f: 2, c: 52308}, {f: 3, c: 52311}, 52320, - 52324, 52326, 52328, 52336, 52341, {f: 2, c: 52376}, 52380, 52384, - {f: 2, c: 52392}, {f: 3, c: 52395}, {f: 2, c: 52404}, 52408, 52412, - {f: 2, c: 52420}, 52423, 52425, 52432, 52436, 52452, 52460, 52464, 52481, - {f: 2, c: 52488}, 52492, 52496, {f: 2, c: 52504}, 52507, 52509, 52516, - 52520, 52524, 52537, 52572, 52576, 52580, {f: 2, c: 52588}, 52591, 52593, - 52600, 52616, {f: 2, c: 52628}, 52632, 52636, {f: 2, c: 52644}, 52647, - 52649, 52656, 52676, 52684, 52688, 52712, 52716, 52720, {f: 2, c: 52728}, - 52731, 52733, 52740, 52744, 52748, 52756, 52761, {f: 2, c: 52768}, 52772, - 52776, {f: 2, c: 52784}, 52787, 52789, {f: 2, c: 52824}, 52828, - {f: 3, c: 52831}, {f: 2, c: 52840}, 52843, 52845, {f: 2, c: 52852}, 52856, - 52860, {f: 2, c: 52868}, 52871, 52873, {f: 2, c: 52880}, 52884, 52888, - {f: 2, c: 52896}, {f: 3, c: 52899}, {f: 2, c: 52908}, 52929, - {f: 2, c: 52964}, 52968, {f: 2, c: 52971}, {f: 2, c: 52980}, - {f: 3, c: 52983}, {f: 2, c: 52992}, 52996, 53000, {f: 2, c: 53008}, 53011, - 53013, 53020, 53024, 53028, {f: 2, c: 53036}, {f: 3, c: 53039}, 53048, - {f: 2, c: 53076}, 53080, 53084, {f: 2, c: 53092}, 53095, 53097, - {f: 2, c: 53104}, 53108, 53112, 53120, 53125, 53132, 53153, 53160, 53168, - 53188, {f: 2, c: 53216}, 53220, 53224, {f: 2, c: 53232}, 53235, 53237, - 53244, 53248, 53252, 53265, 53272, 53293, {f: 2, c: 53300}, 53304, 53308, - {f: 2, c: 53316}, 53319, 53321, 53328, 53332, 53336, 53344, - {f: 2, c: 53356}, 53360, 53364, {f: 2, c: 53372}, 53377, {f: 2, c: 53412}, - 53416, 53420, {f: 2, c: 53428}, 53431, 53433, {f: 2, c: 53440}, 53444, - {f: 2, c: 53448}, {f: 2, c: 53456}, {f: 3, c: 53459}, {f: 2, c: 53468}, - 53472, 53476, {f: 2, c: 53484}, {f: 3, c: 53487}, 53496, 53517, - {f: 2, c: 53552}, 53556, 53560, 53562, {f: 2, c: 53568}, {f: 3, c: 53571}, - {f: 2, c: 53580}, 53584, 53588, {f: 2, c: 53596}, 53599, 53601, 53608, - 53612, 53628, 53636, 53640, {f: 2, c: 53664}, 53668, 53672, - {f: 2, c: 53680}, 53683, 53685, 53690, 53692, 53696, 53720, 53748, 53752, - 53767, 53769, 53776, {f: 2, c: 53804}, 53808, 53812, {f: 2, c: 53820}, - 53823, 53825, 53832, 53852, 53860, {f: 2, c: 53888}, 53892, 53896, - {f: 2, c: 53904}, 53909, 53916, 53920, 53924, 53932, 53937, - {f: 2, c: 53944}, 53948, {f: 2, c: 53951}, 53954, {f: 2, c: 53960}, 53963, - 53972, 53976, 53980, {f: 2, c: 53988}, {f: 2, c: 54000}, 54004, 54008, - {f: 2, c: 54016}, 54019, 54021, {f: 3, c: 54028}, 54032, 54036, 54038, - {f: 2, c: 54044}, {f: 3, c: 54047}, 54053, {f: 2, c: 54056}, 54060, 54064, - {f: 2, c: 54072}, {f: 3, c: 54075}, {f: 2, c: 54084}, {f: 2, c: 54140}, - 54144, 54148, {f: 2, c: 54156}, {f: 3, c: 54159}, {f: 2, c: 54168}, 54172, - 54176, {f: 2, c: 54184}, 54187, 54189, 54196, 54200, 54204, - {f: 2, c: 54212}, {f: 2, c: 54216}, 54224, 54232, 54241, 54243, - {f: 2, c: 54252}, 54256, 54260, {f: 2, c: 54268}, 54271, 54273, 54280, - 54301, 54336, 54340, 54364, 54368, 54372, 54381, 54383, {f: 2, c: 54392}, - 54396, {f: 2, c: 54399}, 54402, {f: 2, c: 54408}, 54411, 54413, 54420, - 54441, 54476, 54480, 54484, 54492, 54495, 54504, 54508, 54512, 54520, - 54523, 54525, 54532, 54536, 54540, {f: 2, c: 54548}, 54551, - {f: 2, c: 54588}, 54592, 54596, {f: 2, c: 54604}, 54607, 54609, - {f: 2, c: 54616}, 54620, 54624, 54629, {f: 2, c: 54632}, 54635, 54637, - {f: 2, c: 54644}, 54648, 54652, {f: 2, c: 54660}, {f: 3, c: 54663}, 54672, - 54693, {f: 2, c: 54728}, 54732, 54736, 54738, {f: 2, c: 54744}, 54747, - 54749, {f: 2, c: 54756}, 54760, 54764, {f: 2, c: 54772}, 54775, 54777, - {f: 2, c: 54784}, 54788, 54792, {f: 2, c: 54800}, {f: 3, c: 54803}, 54812, - 54816, 54820, 54829, {f: 2, c: 54840}, 54844, 54848, 54853, - {f: 2, c: 54856}, 54859, 54861, 54865, {f: 2, c: 54868}, 54872, 54876, - 54887, 54889, {f: 2, c: 54896}, 54900, 54915, 54917, {f: 2, c: 54924}, - 54928, 54932, 54941, 54943, 54945, 54952, 54956, 54960, 54969, 54971, - {f: 2, c: 54980}, 54984, 54988, 54993, 54996, 54999, 55001, 55008, 55012, - 55016, 55024, 55029, {f: 2, c: 55036}, 55040, 55044, 55057, - {f: 2, c: 55064}, 55068, 55072, {f: 2, c: 55080}, 55083, 55085, - {f: 2, c: 55092}, 55096, 55100, 55108, 55111, 55113, {f: 2, c: 55120}, - 55124, {f: 4, c: 55126}, {f: 2, c: 55136}, 55139, 55141, 55145, 55148, - 55152, 55156, {f: 2, c: 55164}, 55169, {f: 2, c: 55176}, 55180, 55184, - {f: 2, c: 55192}, 55195, 55197, 20285, 20339, 20551, 20729, 21152, 21487, - 21621, 21733, 22025, 23233, 23478, 26247, {f: 2, c: 26550}, 26607, 27468, - 29634, 30146, 31292, 33499, 33540, 34903, 34952, 35382, [36040, 63747], - 36303, 36603, 36838, 39381, 21051, 21364, 21508, 24682, 24932, 27580, - 29647, 33050, 35258, [12179, 35282], 38307, 20355, 21002, 22718, 22904, - 23014, [12082, 24178], 24185, 25031, 25536, 26438, 26604, 26751, 28567, - 30286, 30475, 30965, 31240, 31487, 31777, 32925, [12169, 33390], 33393, - 35563, 38291, 20075, 21917, 26359, 28212, 30883, 31469, 33883, 35088, - 34638, 38824, 21208, 22350, 22570, 23884, 24863, 25022, 25121, 25954, - 26577, 27204, 28187, [12130, 29976], 30131, 30435, 30640, 32058, 37039, - {f: 2, c: 37969}, 40853, 21283, 23724, 30002, 32987, 37440, 38296, 21083, - 22536, 23004, 23713, 23831, 24247, 24378, 24394, 24951, 27743, 30074, - 30086, 31968, 32115, 32177, 32652, 33108, 33313, 34193, 35137, 35611, - 37628, [38477, 64009], 40007, 20171, 20215, 20491, 20977, 22607, 24887, - 24894, 24936, 25913, 27114, 28433, 30117, 30342, 30422, 31623, 33445, - 33995, 37799, 38283, 21888, 23458, 22353, 31923, 32697, 37301, 20520, - 21435, 23621, 24040, 25298, 25454, 25818, 25831, 28192, 28844, 31067, - 36317, 36382, 36989, 37445, 37624, 20094, 20214, 20581, [12081, 24062], - 24314, 24838, 26967, 33137, 34388, 36423, 37749, 39467, 20062, 20625, - 26480, 26688, 20745, 21133, 21138, 27298, 30652, 37392, 40660, 21163, - 24623, 36850, 20552, 25001, 25581, 25802, 26684, 27268, 28608, 33160, - 35233, 38548, 22533, 29309, [12125, 29356], 29956, 32121, 32365, 32937, - [12178, 35211, 64010], 35700, 36963, 40273, 25225, 27770, 28500, 32080, - 32570, 35363, 20860, 24906, 31645, 35609, 37463, 37772, 20140, 20435, - 20510, 20670, 20742, 21185, 21197, 21375, 22384, 22659, 24218, 24465, - 24950, 25004, 25806, 25964, 26223, 26299, [26356, 63745], 26775, 28039, - 28805, 28913, 29855, 29861, 29898, 30169, 30828, 30956, 31455, 31478, - 32069, 32147, 32789, 32831, 33051, 33686, 35686, 36629, 36885, 37857, - 38915, 38968, 39514, 39912, 20418, 21843, 22586, [22865, 63753], 23395, - 23622, 24760, 25106, 26690, 26800, 26856, 28330, 30028, 30328, 30926, - 31293, 31995, 32363, 32380, 35336, 35489, 35903, 38542, 40388, 21476, - 21481, 21578, 21617, 22266, 22993, 23396, 23611, 24235, 25335, 25911, - 25925, 25970, 26272, 26543, 27073, 27837, 30204, 30352, 30590, 31295, - 32660, 32771, 32929, 33167, 33510, 33533, 33776, 34241, 34865, 34996, - 35493, 36764, 37678, 38599, 39015, [12220, 39640], [12238, 40723], 21741, - 26011, 26354, 26767, 31296, [12181, 35895], 40288, 22256, 22372, 23825, - 26118, 26801, 26829, 28414, 29736, 34974, 39908, 27752, [12219, 39592], - 20379, 20844, 20849, 21151, 23380, [12079, 24037], 24656, 24685, 25329, - 25511, 25915, 29657, 31354, 34467, 36002, 38799, [20018, 63749], 23521, - [12093, 25096], 26524, [12128, 29916], 31185, 33747, 35463, 35506, 36328, - 36942, 37707, 38982, [24275, 64011], 27112, 34303, 37101, 20896, 23448, - 23532, 24931, 26874, 27454, 28748, 29743, 29912, 31649, 32592, 33733, - 35264, 36011, 38364, 39208, 21038, 24669, 25324, 36866, 20362, 20809, - 21281, 22745, 24291, 26336, 27960, 28826, 29378, 29654, 31568, 33009, - 37979, 21350, 25499, 32619, 20054, 20608, 22602, 22750, 24618, 24871, - 25296, 27088, 39745, 23439, 32024, 32945, 36703, 20132, 20689, 21676, - 21932, 23308, 23968, 24039, 25898, 25934, 26657, 27211, 29409, 30350, - 30703, 32094, 32761, 33184, 34126, 34527, 36611, 36686, 37066, 39171, - 39509, 39851, 19992, 20037, 20061, 20167, 20465, 20855, 21246, 21312, - [12061, 21475], [21477, 63750], 21646, 22036, 22389, 22434, 23495, 23943, - 24272, 25084, 25304, 25937, 26552, 26601, 27083, 27472, 27590, 27628, - 27714, 28317, 28792, 29399, 29590, 29699, 30655, 30697, 31350, 32127, - 32777, [12165, 33276], 33285, 33290, 33503, 34914, 35635, 36092, 36544, - 36881, 37041, 37476, 37558, 39378, 39493, 40169, 40407, - [12244, 40860, 63751, 63752], 22283, 23616, 33738, 38816, 38827, 40628, - 21531, 31384, 32676, 35033, 36557, 37089, 22528, 23624, 25496, 31391, - 23470, [12088, 24339], 31353, 31406, 33422, 36524, 20518, 21048, 21240, - 21367, 22280, 25331, 25458, 27402, 28099, 30519, 21413, 29527, 34152, - 36470, 38357, 26426, 27331, 28528, 35437, 36556, 39243, 26231, 27512, - 36020, [12225, 39740], 21483, 22317, 22862, 25542, 27131, 29674, 30789, - 31418, 31429, 31998, 33909, 35215, 36211, 36917, 38312, 21243, 22343, - 30023, 31584, 33740, 37406, 27224, 20811, 21067, 21127, 25119, 26840, - 26997, 38553, 20677, 21156, 21220, 25027, [12100, 26020], 26681, 27135, - 29822, 31563, 33465, 33771, 35250, 35641, 36817, 39241, 20170, 22935, - 25810, 26129, 27278, 29748, 31105, 31165, 33449, {f: 2, c: 34942}, 35167, - 37670, 20235, 21450, 24613, 25201, 27762, 32026, 32102, 20120, 20834, - 30684, 32943, 20225, 20238, 20854, 20864, 21980, 22120, 22331, 22522, - 22524, 22804, 22855, 22931, 23492, 23696, 23822, [12080, 24049], 24190, - 24524, 25216, 26071, 26083, {f: 2, c: 26398}, 26462, 26827, 26820, 27231, - 27450, 27683, 27773, 27778, 28103, 29592, 29734, 29738, 29826, 29859, - 30072, 30079, 30849, 30959, 31041, {f: 2, c: 31047}, 31098, 31637, 32000, - 32186, 32648, 32774, 32813, 32908, 35352, 35663, [35912, 63744], 36215, - 37665, 37668, 39138, 39249, {f: 2, c: 39438}, 39525, 40594, 32202, 20342, - 21513, 25326, 26708, [12198, 37329, 63754], 21931, 20794, 23068, 25062, - [25295, 63835], 25343, 37027, [35582, 63837], 26262, 29014, 38627, 25423, - 25466, 21335, 26511, 26976, 28275, 30007, 32013, 34930, 22218, 23064, - 20035, 20839, [22856, 63756], 26608, 32784, [12069, 22899, 63873], - [24180, 63886], [25754, 63889], [31178, 63893], [24565, 63907], 24684, - 25288, [25467, 63908], [23527, 63839, 63914], 23511, 21162, 22900, 24361, - [24594, 63840], 29785, 39377, 28611, 33215, 36786, 24817, 33126, - [23615, 63933], 23273, 35365, [26491, 63944], [32016, 63951], 33021, 23612, - [27877, 63971], [21311, 63979], [28346, 63980], 22810, [33590, 63998], - [20025, 63838], 20150, 20294, 21934, 22296, 22727, 24406, 26039, 26086, - 27264, 27573, 28237, 30701, 31471, 31774, 32222, 34507, 34962, 37170, - 37723, 25787, 28606, 29562, 30136, 36948, 21846, 22349, 25018, 25812, - 26311, 28129, 28251, 28525, 28601, 30192, 32835, 33213, 34113, 35203, - 35527, 35674, 37663, 27795, 30035, 31572, 36367, 36957, 21776, 22530, - 22616, 24162, 25095, 25758, 26848, 30070, [31958, 64003], 34739, 40680, - 20195, 22408, 22382, [12068, 22823], 23565, 23729, 24118, 24453, 25140, - 25825, 29619, 33274, 34955, 36024, 38538, 40667, [23429, 64004], 24503, - 24755, 20498, [12049, 20992], 21040, 22294, 22581, 22615, 23566, 23648, - 23798, 23947, [24230, 64001], 24466, 24764, 25361, 25481, 25623, 26691, - 26873, 27330, 28120, 28193, 28372, 28644, 29182, 30428, 30585, 31153, - 31291, 33796, 35241, 36077, 36339, 36424, 36867, 36884, 36947, 37117, - 37709, 38518, 38876, 27602, 28678, 29272, 29346, 29544, 30563, 31167, - 31716, 32411, [35712, 63834], 22697, 24775, 25958, 26109, 26302, 27788, - 28958, 29129, 35930, 38931, 20077, 31361, 20189, 20908, 20941, 21205, - 21516, 24999, 26481, 26704, 26847, [27934, 64005], 28540, 30140, 30643, - 31461, 33012, 33891, 37509, 20828, [12099, 26007], 26460, 26515, 30168, - 31431, 33651, [12182, 35910], 36887, 38957, 23663, 33216, 33434, 36929, - 36975, 37389, 24471, 23965, 27225, 29128, 30331, 31561, 34276, 35588, - 37159, 39472, [21895, 63755], [25078, 63757], [30313, 63758], - [32645, 63759], [34367, 63760], [34746, 63761], [35064, 63762], - [37007, 63763], [27931, 63765], [28889, 63766], [29662, 63767], 32097, - [33853, 63768], [37226, 63769], [39409, 63770], [20098, 63771], - [21365, 63772], [27396, 63773], 27410, 28734, [29211, 63774], - [34349, 63775], [40478, 63776], 21068, 36771, [23888, 63777], 25829, 25900, - 27414, [28651, 63778], 31811, 32412, [34253, 63779], [35172, 63780], 35261, - [25289, 63781], [33240, 63782], [34847, 63783], [24266, 63784], - [26391, 63785], [28010, 63786], [29436, 63787], 29701, 29807, 34690, - [37086, 63788], [20358, 63789], 23821, 24480, 33802, [20919, 63790], - [25504, 63861], [30053, 63862], [20142, 63863], 20486, [20841, 63864], - [20937, 63865], [26753, 63866], 27153, 31918, 31921, [31975, 63867], - [33391, 63868], [35538, 63869], 36635, [37327, 63870], 20406, 20791, - [21237, 63871], [21570, 63872], [24300, 63874], 24942, 25150, - [26053, 63875], 27354, [28670, 63876], [31018, 63877], 34268, 34851, - [38317, 63878], 39522, [39530, 63879], [40599, 63880], [40654, 63881], - [12050, 21147, 63882], [26310, 63883], [27511, 63884], 28701, 31019, - [36706, 63885], 38722, [24976, 63887], [25088, 63888], 25891, - [28451, 63890], [29001, 63891], [29833, 63892], [32244, 63894], - [32879, 63895], [34030, 63897], [36646, 63896], [36899, 63898], - [37706, 63899], 20925, [21015, 63900], [21155, 63901], 27916, - [28872, 63903], [35010, 63904], [24265, 63906], 25986, [27566, 63909], - 28610, [31806, 63910], [29557, 63911], [20196, 63912], 20278, - [22265, 63913], 23738, [23994, 63915], [24604, 63916], [29618, 63917], - 31533, [32666, 63919], 32718, [32838, 63920], 36894, [37428, 63921], - [38646, 63922], [38728, 63923], [38936, 63924], 40801, [20363, 63925], - 28583, [31150, 63926], [37300, 63927], [38583, 63928], [21214, 63791], - 25736, [25796, 63792], [27347, 63793], 28510, 28696, [29200, 63794], - [30439, 63795], [12156, 32769, 63796], [34310, 63797], [34396, 63798], - [36335, 63799], 36613, [38706, 63800], [39791, 63801], [40442, 63802], - [12228, 40565], [30860, 63803], [31103, 63804], [32160, 63805], - [33737, 63806], [37636, 63807], [12229, 40575, 63808], 40595, - [35542, 63809], [22751, 63810], [24324, 63811], 26407, 28711, 29903, - [31840, 63812], [32894, 63813], 20769, 28712, [29282, 63814], - [30922, 63815], [36034, 63816], 36058, 36084, [38647, 63817], - [20102, 63930], [20698, 63931], [23534, 63932], 24278, [26009, 63934], - [29134, 63936], [30274, 63937], 30637, 32842, [34044, 63938], - [36988, 63939], 39719, [12243, 40845, 63940], [22744, 63818], 23105, - [23650, 63819], [27155, 63820], [28122, 63821], [28431, 63822], 30267, - [32047, 63823], [32311, 63824], 34078, 35128, 37860, [38475, 63825], - [21129, 63943], 26066, [26611, 63945], 27060, [27969, 63946], - [28316, 63947], 28687, [29705, 63948], 29792, [30041, 63949], 30244, - [30827, 63950], 35628, [39006, 63952], [20845, 63953], [25134, 63954], - [38520, 63955], 20374, [20523, 63956], [23833, 63957], [28138, 63958], - 32184, [36650, 63959], [24459, 63960], [24900, 63961], [26647, 63962], - [38534, 63964], [21202, 63826], [32907, 63827], [20956, 63828], - [20940, 63829], 26974, [31260, 63830], [32190, 63831], [33777, 63832], - [38517, 63833], 20442, [21033, 63965], 21400, [21519, 63966], 21774, - [23653, 63967], 24743, [26446, 63969], [26792, 63970], 28012, 29313, 29432, - [29702, 63972], 29827, [30178, 63973], 31852, [32633, 63974], 32696, 33673, - [35023, 63975], [35041, 63976], [12197, 37324, 63977], 37328, - [38626, 63978], 39881, [21533, 63981], 28542, [29136, 63982], - [29848, 63983], [34298, 63984], 36522, [38563, 63985], [40023, 63986], - [40607, 63987], [26519, 63988], [28107, 63989], 29747, [33256, 63990], - 38678, 30764, [12148, 31435, 63991], [31520, 63992], [31890, 63993], 25705, - 29802, 30194, 30908, 30952, [12218, 39340], 39764, [12231, 40635], 23518, - 24149, 28448, 33180, 33707, 37000, 19975, 21325, 23081, 24018, 24398, - 24930, 25405, 26217, 26364, 28415, 28459, 28771, 30622, 33836, 34067, - 34875, 36627, 39237, 39995, 21788, 25273, 26411, 27819, 33545, 35178, - 38778, 20129, 22916, {f: 2, c: 24536}, 26395, 32178, 32596, 33426, 33579, - 33725, 36638, 37017, 22475, 22969, 23186, 23504, 26151, 26522, 26757, - 27599, 29028, 32629, 36023, 36067, 36993, 39749, 33032, 35978, 38476, - 39488, [12230, 40613], 23391, 27667, 29467, 30450, 30431, 33804, 20906, - 35219, 20813, 20885, 21193, 26825, 27796, 30468, 30496, 32191, 32236, - [12207, 38754], 40629, 28357, 34065, 20901, 21517, 21629, 26126, 26269, - 26919, 28319, [12139, 30399], 30609, 33559, 33986, 34719, 37225, 37528, - 40180, 34946, 20398, 20882, 21215, 22982, 24125, 24917, {f: 2, c: 25720}, - 26286, 26576, 27169, 27597, [12113, 27611], 29279, 29281, 29761, 30520, - [12141, 30683], 32791, 33468, 33541, 35584, 35624, 35980, [12106, 26408], - 27792, 29287, [12140, 30446], 30566, 31302, 40361, 27519, 27794, 22818, - 26406, 33945, 21359, 22675, 22937, 24287, 25551, 26164, 26483, 28218, - 29483, 31447, 33495, 37672, 21209, 24043, 25006, 25035, 25098, 25287, - 25771, [12102, 26080], 26969, 27494, [12111, 27595], 28961, 29687, 30045, - 32326, 33310, 33538, 34154, 35491, 36031, 38695, 40289, 22696, 40664, - 20497, 21006, 21563, 21839, [12098, 25991], 27766, {f: 2, c: 32010}, 32862, - 34442, [12200, 38272], 38639, 21247, 27797, 29289, 21619, 23194, 23614, - 23883, 24396, 24494, 26410, 26806, 26979, 28220, 28228, 30473, - [12150, 31859], 32654, 34183, 35598, 36855, 38753, 40692, 23735, 24758, - 24845, 25003, 25935, {f: 2, c: 26107}, 27665, 27887, 29599, 29641, 32225, - 38292, 23494, 34588, 35600, 21085, 21338, 25293, 25615, 25778, 26420, - 27192, 27850, 29632, 29854, 31636, 31893, 32283, 33162, 33334, 34180, - 36843, 38649, 39361, 20276, 21322, 21453, 21467, 25292, 25644, 25856, - 26001, 27075, 27886, 28504, 29677, 30036, 30242, 30436, 30460, 30928, - [30971, 63844], 31020, 32070, 33324, 34784, 36820, 38930, 39151, 21187, - 25300, 25765, 28196, 28497, 30332, 36299, 37297, 37474, 39662, 39747, - 20515, 20621, 22346, 22952, 23592, 24135, 24439, 25151, 25918, - [12101, 26041], 26049, 26121, 26507, 27036, 28354, 30917, 32033, 32938, - 33152, 33323, 33459, 33953, 34444, 35370, 35607, 37030, 38450, 40848, - 20493, 20467, 22521, 24472, 25308, 25490, 26479, 28227, 28953, 30403, - 32972, 32986, {f: 2, c: 35060}, 35097, 36064, 36649, 37197, 38506, 20271, - 20336, 24091, 26575, 26658, [12137, 30333], 30334, 39748, 24161, 27146, - 29033, 29140, 30058, 32321, 34115, 34281, 39132, 20240, 31567, 32624, - 38309, 20961, 24070, 26805, 27710, 27726, 27867, 29359, 31684, 33539, - 27861, 29754, 20731, 21128, 22721, 25816, 27287, 29863, 30294, 30887, - 34327, 38370, 38713, 21342, 24321, 35722, 36776, 36783, 37002, 21029, - 30629, 40009, 40712, 19993, 20482, 20853, 23643, 24183, 26142, 26170, - 26564, 26821, 28851, 29953, 30149, 31177, 31453, 36647, 39200, 39432, - 20445, 22561, 22577, 23542, 26222, 27493, 27921, 28282, 28541, 29668, - 29995, 33769, 35036, 35091, 35676, 36628, 20239, 20693, 21264, - [12056, 21340], 23443, [24489, 63846], 26381, 31119, 33145, 33583, 34068, - 35079, 35206, 36665, [36667, 64007], 39333, 39954, 26412, 20086, 20472, - 22857, 23553, {f: 2, c: 23791}, 25447, 26834, 28925, 29090, 29739, 32299, - 34028, 34562, 36898, 37586, 40179, [19981, 63847], 20184, 20463, 20613, - 21078, 21103, 21542, 21648, 22496, 22827, 23142, 23386, 23413, 23500, - 24220, 25206, 25975, 26023, 28014, 28325, [12119, 29238], 31526, 31807, - [12152, 32566], {f: 2, c: 33104}, 33178, 33344, 33433, 33705, 35331, 36000, - 36070, 36091, 36212, 36282, 37096, 37340, [12201, 38428], 38468, 39385, - 40167, [21271, 63843], 20998, 21545, 22132, 22707, 22868, 22894, 24575, - 24996, 25198, 26128, 27774, 28954, 30406, 31881, 31966, 32027, 33452, - 36033, 38640, 20315, 24343, 24447, 25282, 23849, 26379, 26842, 30844, - 32323, 40300, 19989, 20633, [12052, 21269], 21290, 21329, 22915, 23138, - 24199, 24754, 24970, 25161, 25209, 26000, 26503, 27047, [12112, 27604], - {f: 3, c: 27606}, 27832, 29749, 30202, 30738, 30865, 31189, 31192, 31875, - 32203, 32737, 32933, 33086, 33218, 33778, 34586, 35048, 35513, 35692, - 36027, 37145, [12206, 38750], [12214, 39131], [12240, 40763], 22188, 23338, - 24428, 25996, 27315, 27567, 27996, 28657, 28693, 29277, 29613, 36007, - 36051, 38971, 24977, 27703, 32856, 39425, 20045, 20107, 20123, 20181, - 20282, 20284, 20351, 20447, 20735, 21490, 21496, 21766, 21987, 22235, - [12064, 22763], 22882, 23057, 23531, 23546, 23556, 24051, 24107, 24473, - 24605, 25448, 26012, 26031, 26614, 26619, 26797, 27515, 27801, 27863, - 28195, 28681, 29509, 30722, 31038, 31040, 31072, 31169, 31721, 32023, - 32114, 32902, 33293, 33678, 34001, 34503, 35039, 35408, 35422, 35613, - 36060, 36198, 36781, 37034, 39164, 39391, 40605, 21066, 26388, 20632, - 21034, [12077, 23665], 25955, 27733, 29642, 29987, 30109, 31639, 33948, - 37240, 38704, 20087, 25746, [27578, 63856], 29022, 34217, 19977, 26441, - 26862, 28183, 33439, 34072, 34923, 25591, 28545, 37394, 39087, 19978, - 20663, 20687, 20767, 21830, 21930, 22039, 23360, 23577, 23776, 24120, - 24202, 24224, 24258, 24819, 26705, 27233, 28248, 29245, 29248, - [29376, 63994], 30456, 31077, 31665, 32724, 35059, 35316, 35443, 35937, - 36062, 38684, [22622, 63852], 29885, 36093, 21959, 31329, [32034, 63850], - [12170, 33394], 29298, [12131, 29983], 29989, 31513, 22661, 22779, 23996, - 24207, 24246, 24464, 24661, 25234, 25471, 25933, 26257, 26329, 26360, - 26646, 26866, 29312, 29790, 31598, 32110, 32214, 32626, 32997, 33298, - 34223, 35199, 35475, 36893, 37604, [12233, 40653], [12239, 40736], - [12067, 22805], 22893, 24109, 24796, 26132, 26227, 26512, 27728, 28101, - 28511, [12143, 30707], 30889, 33990, 37323, 37675, 20185, 20682, 20808, - 21892, 23307, 23459, 25159, 25982, 26059, 28210, 29053, 29697, 29764, - 29831, 29887, 30316, 31146, 32218, 32341, 32680, 33146, 33203, 33337, - 34330, 34796, 35445, 36323, 36984, 37521, 37925, 39245, 39854, 21352, - 23633, 26964, 27844, 27945, 28203, [12166, 33292], 34203, 35131, 35373, - [35498, 63855, 63905], 38634, 40807, 21089, 26297, 27570, 32406, 34814, - 36109, 38275, 38493, 25885, 28041, 29166, 22478, 22995, 23468, 24615, - 24826, 25104, 26143, 26207, 29481, 29689, 30427, [30465, 63853], 31596, - 32854, 32882, 33125, 35488, 37266, 19990, 21218, 27506, 27927, 31237, - 31545, 32048, 36016, 21484, 22063, 22609, 23477, [12073, 23567], 23569, - 24034, 25152, 25475, 25620, 26157, 26803, 27836, 28040, 28335, 28703, - 28836, 29138, 29990, 30095, 30094, 30233, 31505, 31712, 31787, 32032, - 32057, 34092, 34157, 34311, 35380, 36877, 36961, 37045, 37559, 38902, - 39479, 20439, 23660, 26463, 28049, 31903, 32396, 35606, 36118, 36895, - 23403, 24061, 25613, 33984, 36956, 39137, [29575, 63841, 63963], 23435, - 24730, 26494, 28126, 35359, 35494, 36865, 38924, 21047, 28753, 30862, - 37782, 34928, 37335, 20462, 21463, 22013, 22234, 22402, 22781, 23234, - 23432, 23723, 23744, 24101, 24833, 25101, [12095, 25163], 25480, 25628, - 25910, [25976, 63849], 27193, 27530, [12116, 27700], 27929, 28465, 29159, - 29417, 29560, 29703, 29874, 30246, 30561, 31168, 31319, 31466, 31929, - 32143, 32172, 32353, 32670, 33065, 33585, 33936, 34010, 34282, 34966, - 35504, 35728, 36664, 36930, 36995, 37228, 37526, 37561, 38539, - {f: 2, c: 38567}, 38614, 38656, 38920, [12216, 39318], 39635, 39706, 21460, - 22654, 22809, 23408, 23487, 28113, 28506, 29087, 29729, 29881, 32901, - 33789, 24033, 24455, 24490, 24642, 26092, 26642, 26991, 27219, 27529, - 27957, 28147, 29667, 30462, 30636, 31565, 32020, 33059, 33308, 33600, - 34036, 34147, 35426, 35524, 37255, 37662, 38918, 39348, 25100, 34899, - 36848, 37477, 23815, 23847, 23913, 29791, 33181, 34664, 28629, - [25342, 63859], 32722, 35126, 35186, 19998, 20056, 20711, 21213, 21319, - 25215, 26119, 32361, 34821, 38494, 20365, 21273, 22070, 22987, 23204, - [12075, 23608], 23630, 23629, 24066, 24337, 24643, 26045, 26159, 26178, - 26558, 26612, 29468, [12142, 30690], [12144, 31034], 32709, 33940, 33997, - 35222, 35430, 35433, 35553, [12183, 35925], 35962, 22516, 23508, 24335, - 24687, 25325, 26893, 27542, 28252, 29060, 31698, 34645, [35672, 63996], - 36606, [12215, 39135], 39166, 20280, 20353, 20449, 21627, 23072, 23480, - 24892, 26032, 26216, 29180, 30003, 31070, 32051, 33102, [12162, 33251], - 33688, 34218, 34254, 34563, 35338, [12189, 36523], [12191, 36763], 36805, - 22833, 23460, 23526, 24713, 23529, 23563, [12092, 24515], 27777, 28145, - 28683, 29978, 33455, 35574, [20160, 63997], [12055, 21313], 38617, - [12114, 27663], 20126, 20420, 20818, 21854, 23077, 23784, 25105, - [12123, 29273], 33469, 33706, 34558, 34905, 35357, 38463, 38597, 39187, - 40201, 40285, 22538, 23731, 23997, 24132, [24801, 63929], 24853, 25569, - [27138, 63764, 63836, 63935], 28197, 37122, 37716, 38990, 39952, 40823, - 23433, 23736, 25353, 26191, 26696, 30524, 38593, 38797, 38996, 39839, - 26017, 35585, 36555, 38332, 21813, 23721, 24022, 24245, 26263, 30284, - 33780, 38343, 22739, 25276, 29390, 40232, 20208, 22830, 24591, 26171, - 27523, 31207, 40230, 21395, 21696, 22467, 23830, 24859, 26326, 28079, - 30861, 33406, 38552, 38724, 21380, 25212, 25494, 28082, 32266, 33099, - 38989, 27387, 32588, 40367, 40474, 20063, 20539, 20918, 22812, 24825, - 25590, 26928, 29242, 32822, 37326, 24369, 32004, [33509, 63860], 33903, - 33979, 34277, 36493, 20335, 22756, 23363, 24665, 25562, 25880, 25965, - 26264, 26954, 27171, 27915, 28673, 29036, 30162, 30221, 31155, 31344, - [12154, 32650], 35140, 35731, 37312, 38525, 39178, 22276, 24481, 26044, - 28417, 30208, 31142, 35486, 39341, [12226, 39770], 40812, 20740, 25014, - 25233, 27277, 33222, 20547, 22576, 24422, 28937, [12180, 35328], 35578, - 23420, 34326, 20474, 20796, 22196, 22852, 25513, 28153, 23978, 26989, - 20870, 20104, 20313, 22914, 27487, 27741, 29877, 30998, 33287, 33349, - 33593, 36671, 36701, 39192, 20134, 22495, 24441, [26131, 63968], 30123, - 32377, 35695, 36870, 39515, 22181, 22567, 23032, 23071, 23476, 24310, - 25424, 25403, 26941, 27783, 27839, 28046, 28051, 28149, 28436, 28895, - 28982, 29017, 29123, 29141, 30799, 30831, 31605, 32227, 32303, 34893, - 36575, 37467, 40182, 24709, 28037, 29105, 38321, 21421, 26579, 28814, - 28976, 29744, 33398, 33490, 38331, 39653, 40573, 26308, 29121, - [33865, 63854], 22603, 23992, 24433, 26144, 26254, 27001, 27054, 27704, - 27891, 28214, 28481, 28634, 28699, 28719, 29008, 29151, 29552, 29787, - 29908, 30408, 31310, 32403, 33521, 35424, 36814, 37704, 38681, 20034, - 20522, 21000, 21473, 26355, 27757, 28618, 29450, 30591, 31330, 33454, - 34269, 34306, 35028, 35427, 35709, 35947, 37555, 38675, 38928, 20116, - 20237, 20425, 20658, 21320, 21566, 21555, 21978, 22626, 22714, 22887, - 23067, 23524, 24735, 25034, 25942, 26111, 26212, 26791, 27738, 28595, - 28879, 29100, 29522, 31613, 34568, 35492, 39986, 40711, 23627, 27779, - 29508, [12127, 29577], 37434, 28331, 29797, 30239, 31337, 32277, 34314, - 20800, 22725, 25793, 29934, 29973, 30320, 32705, 37013, 38605, 39252, - 28198, [12129, 29926], {f: 2, c: 31401}, 33253, 34521, 34680, 35355, 23113, - 23436, 23451, 26785, 26880, 28003, 29609, 29715, 29740, 30871, 32233, - 32747, 33048, 33109, 33694, 35916, [38446, 63942], 38929, [12104, 26352], - 24448, 26106, 26505, 27754, 29579, 20525, 23043, 27498, 30702, 22806, - 23916, 24013, 29477, 30031, 20709, 20985, 22575, 22829, 22934, 23002, - 23525, 23970, 25303, 25622, 25747, 25854, 26332, 27208, 29183, 29796, - 31368, 31407, 32327, 32350, 32768, 33136, 34799, 35201, 35616, 36953, - 36992, 39250, 24958, 27442, 28020, 32287, 35109, 36785, 20433, 20653, - 20887, 21191, 22471, 22665, 23481, 24248, 24898, 27029, 28044, 28263, - 28342, 29076, 29794, [12132, 29992], 29996, 32883, 33592, 33993, 36362, - 37780, 37854, 20110, 20305, 20598, 20778, [12060, 21448], 21451, 21491, - 23431, 23507, 23588, 24858, 24962, 26100, [12124, 29275], 29591, 29760, - 30402, 31056, 31121, 31161, 32006, [12155, 32701], 33419, 34261, 34398, - 36802, 36935, 37109, 37354, 38533, [12204, 38632], 38633, 21206, 24423, - 26093, 26161, 26671, 29020, 31286, 37057, 38922, 20113, 27218, 27550, - 28560, 29065, 32792, 33464, 34131, 36939, 38549, 38642, 38907, 34074, - 39729, 20112, 29066, 38596, 20803, 21407, 21729, 22291, 22290, 22435, - 23195, 23236, 23491, 24616, 24895, 25588, 27781, 27961, 28274, 28304, - 29232, 29503, 29783, 33489, 34945, 36677, 36960, 38498, 39000, 40219, - [12105, 26376], 36234, 37470, 20301, 20553, 20702, 21361, 22285, 22996, - 23041, 23561, 24944, 26256, 28205, 29234, 29771, 32239, 32963, 33806, - 33894, 34111, 34655, 34907, 35096, 35586, 36949, [12209, 38859], 39759, - 20083, 20369, 20754, 20842, 21807, 21929, 23418, 23461, {f: 2, c: 24188}, - 24254, 24736, 24799, {f: 2, c: 24840}, 25540, 25912, 26377, 26580, 26586, - {f: 2, c: 26977}, 27833, 27943, 28216, 28641, {f: 2, c: 29494}, 29788, - 30001, 30290, 32173, 33278, 33848, 35029, 35480, 35547, 35565, 36400, - 36418, 36938, 36926, 36986, [12195, 37193], 37321, 37742, 22537, 27603, - [12161, 32905], 32946, 20801, 22891, 23609, 28516, 29607, 32996, 36103, - 37399, 38287, [12160, 32895], 25102, 28700, 32104, 34701, 22432, 24681, - 24903, 27575, 35518, 37504, 38577, [12036, 20057], 21535, 28139, 34093, - 38512, [12211, 38899], 39150, 25558, 27875, [12194, 37009], 20957, 25033, - 33210, 40441, 20381, 20506, 20736, 23452, 24847, 25087, 25836, 26885, - 27589, 30097, 30691, 32681, 33380, 34191, 34811, [12176, 34915], 35516, - 35696, 37291, [12038, 20108], 20197, 20234, 22839, 23016, 24050, 24347, - 24411, 24609, 29246, 29669, [30064, 63842], 30157, 31227, [12157, 32780], - [12159, 32819], 32900, 33505, 33617, 36029, 36019, 36999, 39156, 39180, - 28727, 30410, 32714, 32716, 32764, 35610, [12040, 20154], 20161, 20995, - 21360, [21693, 63902], 22240, 23035, 23493, 24341, 24525, 28270, 32106, - 33589, 34451, 35469, 38765, 38775, [12032, 19968], 20314, 20350, 22777, - [12103, 26085], 28322, 36920, 37808, 39353, 20219, 22764, 22922, 23001, - 24641, 31252, 33615, 36035, [12042, 20837], 21316, 20173, 21097, 23381, - 33471, 20180, [21050, 63999], 21672, 22985, 23039, [12070, 23376], 23383, - 23388, 24675, 24904, 28363, [28825, 63995], 29038, 29574, 29943, 30133, - 30913, 32043, 32773, [12163, 33258], 33576, 34071, 34249, 35566, 36039, - 38604, 20316, 21242, 22204, 26027, 26152, 28796, 28856, 29237, 32189, - 33421, 37196, 38592, 40306, 23409, 26855, 27544, 28538, 30430, 23697, - 26283, 28507, 31668, 31786, 34870, 38620, 19976, 20183, 21280, 22580, - 22715, 22767, 22892, 23559, 24115, 24196, 24373, 25484, 26290, 26454, - 27167, 27299, 27404, 28479, 29254, 29520, 29835, 31456, 31911, 33144, - 33247, 33255, 33674, 33900, 34083, 34196, 34255, 35037, 36115, 37292, - [12199, 38263], 38556, 20877, 21705, 22312, 23472, 25165, 26448, 26685, - 26771, 28221, 28371, 28797, 32289, 35009, 36001, 36617, 40779, 40782, - 29229, 31631, 35533, 37658, 20295, 20302, 20786, 21632, 22992, 24213, - 25269, 26485, 26990, 27159, 27822, 28186, 29401, 29482, 30141, 31672, - 32053, 33511, 33785, 33879, 34295, 35419, 36015, 36487, 36889, 37048, - 38606, 40799, 21219, 21514, 23265, 23490, 25688, 25973, 28404, 29380, - 30340, 31309, 31515, 31821, 32318, 32735, 33659, 35627, 36042, - [12186, 36196], 36321, 36447, 36842, 36857, 36969, 37841, 20291, 20346, - 20659, 20840, 20856, 21069, 21098, 22625, 22652, 22880, 23560, 23637, - 24283, 24731, 25136, 26643, 27583, 27656, 28593, 29006, 29728, - [12133, 30000], 30008, 30033, 30322, 31564, 31627, 31661, 31686, 32399, - 35438, 36670, 36681, 37439, 37523, 37666, 37931, 38651, 39002, 39019, - 39198, [20999, 64000], 25130, 25240, 27993, 30308, 31434, 31680, 32118, - 21344, 23742, 24215, 28472, 28857, 31896, 38673, 39822, 40670, 25509, - 25722, 34678, 19969, 20117, 20141, 20572, 20597, 21576, 22979, 23450, - 24128, 24237, 24311, 24449, 24773, 25402, 25919, 25972, 26060, 26230, - 26232, 26622, 26984, 27273, 27491, 27712, 28096, 28136, 28191, 28254, - 28702, 28833, 29582, 29693, 30010, 30555, 30855, 31118, 31243, 31357, - 31934, 32142, 33351, 35330, 35562, 35998, 37165, 37194, 37336, 37478, - 37580, 37664, 38662, 38742, 38748, 38914, [12237, 40718], 21046, 21137, - 21884, 22564, 24093, 24351, 24716, 25552, 26799, 28639, 31085, 31532, - 33229, 34234, 35069, 35576, 36420, 37261, 38500, 38555, 38717, 38988, - [12241, 40778], 20430, 20806, 20939, 21161, 22066, 24340, 24427, 25514, - 25805, 26089, 26177, 26362, 26361, 26397, 26781, 26839, 27133, 28437, - 28526, 29031, 29157, [12118, 29226], 29866, 30522, 31062, 31066, 31199, - 31264, 31381, 31895, 31967, 32068, 32368, 32903, 34299, 34468, 35412, - 35519, 36249, 36481, 36896, 36973, 37347, 38459, 38613, [12227, 40165], - 26063, 31751, [12188, 36275], 37827, 23384, 23562, 21330, 25305, 29469, - 20519, 23447, 24478, 24752, 24939, 26837, 28121, 29742, 31278, 32066, - 32156, 32305, 33131, 36394, 36405, 37758, 37912, 20304, 22352, 24038, - 24231, 25387, 32618, 20027, 20303, 20367, 20570, 23005, 32964, 21610, - 21608, 22014, 22863, 23449, 24030, 24282, 26205, 26417, 26609, 26666, - 27880, 27954, 28234, 28557, 28855, 29664, 30087, 31820, 32002, 32044, - 32162, [12168, 33311], 34523, 35387, 35461, [12187, 36208], 36490, 36659, - 36913, 37198, 37202, 37956, 39376, [12149, 31481], 31909, 20426, 20737, - 20934, 22472, 23535, 23803, 26201, 27197, 27994, 28310, 28652, 28940, - 30063, 31459, 34850, 36897, 36981, 38603, 39423, 33537, 20013, 20210, - 34886, 37325, 21373, 27355, 26987, 27713, 33914, 22686, 24974, 26366, - 25327, 28893, 29969, 30151, 32338, 33976, 35657, 36104, 20043, 21482, - 21675, 22320, 22336, 24535, 25345, 25351, 25711, [12096, 25903], 26088, - 26234, 26525, 26547, [12108, 27490], 27744, 27802, 28460, 30693, 30757, - 31049, 31063, 32025, 32930, 33026, [12164, 33267], 33437, 33463, 34584, - 35468, 36100, 36286, 36978, 30452, 31257, 31287, 32340, 32887, 21767, - 21972, 22645, 25391, 25634, 26185, 26187, 26733, 27035, 27524, 27941, - 28337, 29645, 29800, 29857, 30043, 30137, 30433, 30494, 30603, 31206, - 32265, 32285, 33275, 34095, 34967, 35386, 36049, 36587, - [12192, 36784, 63857], 36914, 37805, 38499, 38515, 38663, 20356, 21489, - 23018, 23241, 24089, 26702, 29894, 30142, 31209, 31378, 33187, 34541, - 36074, 36300, 36845, 26015, 26389, 22519, 28503, 32221, 36655, 37878, - 38598, 24501, 25074, 28548, 19988, 20376, 20511, 21449, 21983, 23919, - 24046, 27425, 27492, 30923, 31642, 36425, [12190, 36554, 63746], 36974, - 25417, 25662, 30528, 31364, 37679, 38015, 40810, 25776, 28591, 29158, - 29864, 29914, 31428, 31762, 32386, 31922, 32408, 35738, 36106, 38013, - 39184, 39244, 21049, 23519, 25830, 26413, 32046, 20717, [21443, 63851], - 22649, {f: 2, c: 24920}, 25082, 26028, 31449, 35730, 35734, 20489, 20513, - 21109, 21809, 23100, 24288, 24432, 24884, 25950, 26124, 26166, 26274, - 27085, 28356, 28466, 29462, 30241, 31379, 33081, 33369, 33750, 33980, - 20661, 22512, 23488, 23528, 24425, 25505, 30758, 32181, 33756, 34081, - 37319, 37365, 20874, 26613, 31574, 36012, 20932, 22971, 24765, 34389, - 20508, 21076, 23610, 24957, 25114, [25299, 64002], 25842, 26021, 28364, - 30240, 33034, 36448, 38495, 38587, 20191, 21315, 21912, 22825, 24029, - 25797, 27849, 28154, 29588, 31359, [12167, 33307], 34214, 36068, 36368, - 36983, 37351, 38369, 38433, 38854, 20984, 21746, 21894, 24505, 25764, - 28552, 32180, 36639, 36685, 37941, 20681, 23574, 27838, 28155, 29979, - 30651, 31805, 31844, 35449, 35522, 22558, 22974, 24086, 25463, 29266, - 30090, 30571, 35548, 36028, 36626, 24307, 26228, 28152, 32893, 33729, - 35531, [12205, 38737], 39894, 21059, 26367, 28053, 28399, 32224, 35558, - 36910, 36958, 39636, 21021, 21119, 21736, 24980, 25220, 25307, 26786, - 26898, 26970, 27189, 28818, 28966, 30813, 30977, 30990, 31186, 31245, - 32918, [12171, 33400], 33493, 33609, 34121, 35970, 36229, 37218, 37259, - 37294, 20419, 22225, 29165, 30679, 34560, 35320, [12072, 23544], 24534, - 26449, 37032, 21474, 22618, 23541, 24740, 24961, 25696, 32317, 32880, - 34085, 37507, 25774, 20652, 23828, 26368, 22684, 25277, 25512, 26894, - 27000, 27166, 28267, 30394, 31179, 33467, 33833, 35535, 36264, 36861, - 37138, 37195, 37276, 37648, 37656, 37786, 38619, 39478, 39949, 19985, - 30044, 31069, 31482, 31569, 31689, 32302, 33988, 36441, 36468, 36600, - 36880, 26149, 26943, 29763, 20986, 26414, 40668, 20805, 24544, 27798, - 34802, 34909, 34935, 24756, 33205, 33795, 36101, 21462, 21561, 22068, - 23094, 23601, 28810, 32736, 32858, 33030, 33261, 36259, 37257, 39519, - 40434, 20596, 20164, 21408, 24827, 28204, 23652, 20360, 20516, 21988, - 23769, 24159, 24677, 26772, 27835, 28100, 29118, 30164, 30196, 30305, - 31258, 31305, 32199, 32251, 32622, 33268, 34473, 36636, 38601, 39347, - [12242, 40786], 21063, 21189, 39149, 35242, 19971, 26578, 28422, 20405, - 23522, 26517, [27784, 63858], 28024, 29723, 30759, 37341, 37756, 34756, - 31204, 31281, 24555, 20182, 21668, 21822, 22702, 22949, 24816, 25171, - 25302, 26422, 26965, 33333, 38464, 39345, 39389, 20524, 21331, 21828, - 22396, 25176, 25826, 26219, 26589, 28609, 28655, 29730, 29752, 35351, - 37944, 21585, 22022, 22374, 24392, 24986, 27470, 28760, 28845, 32187, - 35477, 22890, 33067, 25506, 30472, 32829, 36010, 22612, 25645, 27067, - 23445, 24081, 28271, 34153, 20812, 21488, 22826, 24608, 24907, 27526, - 27760, 27888, 31518, 32974, 33492, 36294, 37040, 39089, 25799, 28580, - 25745, 25860, 20814, 21520, [12063, 22303], 35342, 24927, 26742, 30171, - 31570, 32113, 36890, 22534, 27084, 33151, 35114, 36864, 38969, 20600, - 22871, 22956, 25237, 36879, 39722, 24925, 29305, 38358, 22369, 23110, - 24052, 25226, 25773, 25850, 26487, 27874, 27966, 29228, 29750, 30772, - 32631, 33453, 36315, 38935, 21028, 22338, 26495, 29256, 29923, 36009, - 36774, 37393, 38442, [12043, 20843], 21485, 25420, 20329, 21764, 24726, - 25943, 27803, 28031, 29260, 29437, 31255, 35207, [12185, 35997], 24429, - 28558, 28921, 33192, 24846, [20415, 63845], 20559, 25153, [12122, 29255], - 31687, 32232, 32745, 36941, 38829, 39449, 36022, 22378, 24179, 26544, - 33805, 35413, 21536, 23318, 24163, 24290, 24330, 25987, 32954, 34109, - 38281, 38491, 20296, 21253, 21261, 21263, 21638, 21754, 22275, 24067, - 24598, 25243, 25265, 25429, 27873, 28006, 30129, 30770, 32990, 33071, - 33502, 33889, 33970, 34957, 35090, 36875, 37610, 39165, 39825, 24133, - [26292, 64006], 26333, 28689, 29190, 20469, 21117, 24426, 24915, 26451, - 27161, 28418, 29922, 31080, 34920, 35961, 39111, 39108, 39491, 21697, - 31263, 26963, 35575, 35914, [12213, 39080], 39342, 24444, 25259, 30130, - [12138, 30382], 34987, 36991, 38466, 21305, 24380, 24517, [27852, 63848], - 29644, 30050, [12134, 30091], 31558, 33534, 39325, 20047, 36924, 19979, - 20309, 21414, 22799, 24264, 26160, 27827, 29781, 33655, 34662, 36032, - 36944, 38686, 39957, 22737, 23416, 34384, 35604, 40372, 23506, 24680, - 24717, 26097, 27735, 28450, 28579, 28698, 32597, 32752, {f: 2, c: 38289}, - 38480, 38867, 21106, 36676, 20989, 21547, 21688, 21859, 21898, 27323, - 28085, 32216, 33382, 37532, 38519, 40569, 21512, 21704, 30418, 34532, - 38308, 38356, 38492, 20130, 20233, 23022, 23270, 24055, 24658, 25239, - 26477, 26689, 27782, 28207, 32568, 32923, 33322, 38917, 20133, 20565, - 21683, 22419, 22874, 23401, 23475, 25032, 26999, 28023, 28707, 34809, - 35299, 35442, 35559, 36994, 39405, 39608, 21182, 26680, 20502, 24184, - 26447, 33607, [12175, 34892, 64008], 20139, 21521, 22190, 29670, 37141, - 38911, 39177, 39255, [12217, 39321], 22099, 22687, 34395, 35377, 25010, - 27382, 29563, 36562, 27463, 38570, 39511, 22869, 29184, 36203, - [12208, 38761], 20436, 23796, 24358, 25080, 26203, 27883, 28843, - [12126, 29572], 29625, 29694, 30505, 30541, 32067, 32098, 32291, 33335, - 34898, 36066, 37449, 39023, 23377, [12147, 31348], [12174, 34880], - [12212, 38913], 23244, 20448, 21332, 22846, 23805, 25406, 28025, 29433, - 33029, 33031, 33698, 37583, 38960, 20136, 20804, 21009, 22411, 24418, - 27842, 28366, 28677, 28752, 28847, 29074, 29673, [29801, 63918], 33610, - 34722, 34913, 36872, 37026, 37795, 39336, 20846, 24407, 24800, 24935, - 26291, 34137, 36426, 37295, 38795, 20046, 20114, 21628, 22741, 22778, - 22909, 23733, 24359, [12094, 25142], 25160, 26122, 26215, 27627, 28009, - 28111, 28246, 28408, 28564, 28640, 28649, 28765, 29392, 29733, 29786, - 29920, 30355, 31068, 31946, 32286, 32993, 33446, 33899, 33983, 34382, - 34399, 34676, 35703, 35946, 37804, 38912, 39013, 24785, 25110, 37239, - 23130, 26127, 28151, 28222, 29759, 39746, 24573, 24794, 31503, 21700, - 24344, 27742, 27859, 27946, 28888, 32005, 34425, 35340, 40251, 21270, - 21644, 23301, 27194, [12117, 28779], 30069, 31117, [12146, 31166], 33457, - 33775, 35441, 35649, 36008, 38772, 25844, 25899, {f: 2, c: 30906}, 31339, - 20024, 21914, 22864, 23462, 24187, 24739, 25563, 27489, 26213, 26707, - 28185, 29029, 29872, 32008, 36996, 39529, 39973, 27963, [28369, 63748], - 29502, 35905, 38346, 20976, 24140, 24488, 24653, 24822, 24880, 24908, - {f: 2, c: 26179}, 27045, 27841, 28255, 28361, 28514, 29004, 29852, 30343, - 31681, 31783, 33618, 34647, 36945, 38541, [12232, 40643], 21295, 22238, - 24315, 24458, 24674, 24724, 25079, 26214, 26371, 27292, 28142, 28590, - 28784, 29546, 32362, 33214, 33588, 34516, 35496, 36036, 21123, 29554, - 23446, 27243, 37892, 21742, 22150, 23389, 25928, 25989, 26313, 26783, - 28045, 28102, [12120, 29243], 32948, 37237, 39501, 20399, 20505, 21402, - 21518, 21564, 21897, 21957, 24127, 24460, 26429, 29030, 29661, 36869, - 21211, 21235, 22628, 22734, 28932, 29071, 29179, 34224, 35347, - [26248, 63941], 34216, 21927, 26244, 29002, 33841, 21321, 21913, 27585, - 24409, 24509, 25582, 26249, 28999, 35569, 36637, 40638, 20241, 25658, - 28875, 30054, 34407, 24676, 35662, 40440, 20807, 20982, 21256, 27958, - 33016, [12234, 40657], 26133, 27427, 28824, 30165, 21507, 23673, 32007, - 35350, [12107, 27424], 27453, 27462, 21560, 24688, 27965, 32725, 33288, - 20694, 20958, 21916, 22123, 22221, 23020, 23305, 24076, 24985, 24984, - 25137, 26206, 26342, 29081, {f: 2, c: 29113}, 29351, 31143, 31232, 32690, - 35440, {s: 163}, {f: 4, c: 12310}, {s: 14}, 8223, 8219, {f: 2, c: 8314}, - {s: 7}, 8316, 0, {f: 2, c: 8317}, {s: 23}, 700, {s: 44}, 8942, 8759, - {s: 20}, {f: 10, c: 10122}, {s: 36}, {f: 26, c: 9398}, {s: 61}, - {f: 2, c: 8826}, {f: 2, c: 8910}, {f: 2, c: 8832}, {f: 4, c: 8816}, 0, - 8842, 0, 8843, {f: 2, c: 8822}, 8825, {f: 2, c: 8922}, {s: 5}, 8773, 8771, - 8776, 0, 8868, {s: 78}, 8244, {s: 11}, 9839, {s: 4}, 8258, {s: 4}, 10045, - 0, 0, 8226, {s: 4}, {f: 2, c: 8249}, {s: 16}, 10010, 10006, 0, 9711, - {s: 3}, 10070, 0, 9676, {s: 24}, 9775, {s: 6}, 12320, 0, {f: 10, c: 10102}, - {s: 17}, 12306, 12342, {s: 13}, 8710, 0, 8735, 0, {f: 2, c: 8741}, 0, 8787, - 8785, {f: 2, c: 8806}, 8723, {f: 3, c: 8853}, 0, 8980, 0, 0, 8802, 0, 9649, - 0, 8738, 8784, 0, 0, 8867, 0, 0, {f: 2, c: 8814}, 8837, 8836, 8713, 8716, - {f: 2, c: 8891}, 8794, 8966, {s: 6}, 12958, 0, 8252, {s: 11}, 9702, {s: 3}, - 9663, 9653, 9657, 9667, {s: 4}, 9674, 12849, 12857, 13259, {f: 5, c: 9327}, - {s: 18}, 8656, 8655, 8653, {s: 37}, 8657, 8659, {s: 8}, 8626, 8625, 0, - 8628, 8624, 8627, {s: 14}, 8636, 8640, {s: 10}, {f: 2, c: 8644}, {s: 144}, - {f: 5, c: 9347}, {s: 33}, 12948, {s: 15}, 12965, {s: 93}, 8672, 8674, 8673, - 8675, {s: 4}, 8678, 8680, 8679, 8681, {s: 20}, 9757, 9759, {s: 76}, 12944, - {f: 6, c: 12938}, {s: 15}, {f: 2, c: 12318}, 8246, 0, 8245, {s: 3}, 12540, - 0, 0, {f: 2, c: 44034}, {f: 2, c: 44037}, {f: 5, c: 44043}, 44056, - {f: 2, c: 44062}, {f: 3, c: 44065}, {f: 7, c: 44069}, 44078, - {f: 6, c: 44082}, {f: 2, c: 44090}, {f: 3, c: 44093}, {f: 10, c: 44097}, - 44108, {f: 6, c: 44110}, {f: 3, c: 44117}, {f: 3, c: 44121}, - {f: 19, c: 44125}, {f: 2, c: 44146}, {f: 2, c: 44149}, 44153, - {f: 5, c: 44155}, 44162, {f: 2, c: 44167}, {f: 3, c: 44173}, - {f: 3, c: 44177}, {f: 7, c: 44181}, 44190, {f: 6, c: 44194}, 44203, - {f: 2, c: 44205}, {f: 7, c: 44209}, 44218, {f: 3, c: 44222}, - {f: 2, c: 44226}, {f: 3, c: 44229}, {f: 3, c: 44233}, {f: 8, c: 44237}, - 44246, {f: 8, c: 44248}, {f: 2, c: 44258}, {f: 2, c: 44261}, 44265, 44267, - {f: 2, c: 44269}, 44274, 44276, {f: 5, c: 44279}, {f: 2, c: 44286}, - {f: 3, c: 44289}, 44293, {f: 5, c: 44295}, 44302, 44304, {f: 6, c: 44306}, - {f: 3, c: 44313}, {f: 3, c: 44317}, {f: 8, c: 44321}, {f: 2, c: 44330}, - {f: 6, c: 44334}, {f: 2, c: 44342}, {f: 3, c: 44345}, {f: 7, c: 44349}, - 44358, 44360, {f: 6, c: 44362}, {f: 3, c: 44369}, {f: 3, c: 44373}, - {f: 8, c: 44377}, 44386, {f: 8, c: 44388}, {f: 2, c: 44398}, - {f: 2, c: 44401}, {f: 4, c: 44407}, 44414, 44416, {f: 5, c: 44419}, - {f: 2, c: 44426}, {f: 3, c: 44429}, {f: 11, c: 44433}, {f: 6, c: 44446}, - {f: 18, c: 44453}, {f: 8, c: 44472}, {f: 2, c: 44482}, {f: 3, c: 44485}, - {f: 7, c: 44489}, 44498, {f: 8, c: 44500}, {f: 3, c: 44509}, - {f: 3, c: 44513}, {f: 19, c: 44517}, {f: 2, c: 44538}, {f: 2, c: 44541}, - {f: 6, c: 44546}, 44554, 44556, {f: 6, c: 44558}, {f: 27, c: 44565}, - {f: 2, c: 44594}, {f: 2, c: 44597}, 44601, {f: 5, c: 44603}, 44610, 44612, - {f: 3, c: 44615}, 44619, 44623, {f: 3, c: 44625}, 44629, {f: 5, c: 44631}, - 44638, {f: 3, c: 44642}, {f: 2, c: 44646}, {f: 2, c: 44650}, - {f: 3, c: 44653}, {f: 7, c: 44657}, 44666, {f: 6, c: 44670}, - {f: 6, c: 44678}, {f: 47, c: 44685}, 44735, {f: 3, c: 44737}, - {f: 7, c: 44741}, 44750, {f: 6, c: 44754}, {f: 2, c: 44762}, - {f: 11, c: 44765}, {f: 2, c: 44777}, 44780, {f: 6, c: 44782}, - {f: 3, c: 44789}, {f: 3, c: 44793}, {f: 10, c: 44797}, {f: 4, c: 44809}, - {f: 2, c: 44814}, {f: 27, c: 44817}, {f: 2, c: 44846}, 44849, 44851, - {f: 7, c: 44853}, 44862, 44864, {f: 4, c: 44868}, {f: 6, c: 44874}, - {f: 11, c: 44881}, {f: 6, c: 44894}, {f: 19, c: 44902}, {f: 6, c: 44922}, - {f: 3, c: 44929}, {f: 3, c: 44933}, {f: 7, c: 44937}, {f: 3, c: 44946}, - {f: 6, c: 44950}, {f: 27, c: 44957}, {f: 2, c: 44986}, {f: 3, c: 44989}, - {f: 6, c: 44993}, 45002, 45004, {f: 5, c: 45007}, {f: 7, c: 45013}, - {f: 11, c: 45021}, {f: 6, c: 45034}, {f: 2, c: 45042}, {f: 3, c: 45045}, - {f: 7, c: 45049}, {f: 2, c: 45058}, {f: 7, c: 45061}, {f: 3, c: 45069}, - {f: 3, c: 45073}, {f: 7, c: 45077}, {f: 10, c: 45086}, {f: 27, c: 45097}, - {f: 2, c: 45126}, 45129, 45131, 45133, {f: 4, c: 45135}, 45142, 45144, - {f: 3, c: 45146}, {f: 30, c: 45150}, {f: 2, c: 45182}, {f: 3, c: 45185}, - {f: 7, c: 45189}, 45198, 45200, {f: 6, c: 45202}, 45211, {f: 2, c: 45213}, - {f: 5, c: 45219}, 45226, 45232, 45234, {f: 2, c: 45238}, {f: 3, c: 45241}, - {f: 7, c: 45245}, 45254, {f: 6, c: 45258}, {f: 2, c: 45266}, - {f: 3, c: 45269}, {f: 7, c: 45273}, {f: 4, c: 45281}, {f: 34, c: 45286}, - 45322, {f: 3, c: 45325}, 45329, {f: 4, c: 45332}, 45338, {f: 5, c: 45342}, - {f: 2, c: 45350}, {f: 3, c: 45353}, {f: 7, c: 45357}, 45366, - {f: 6, c: 45370}, {f: 2, c: 45378}, {f: 3, c: 45381}, {f: 7, c: 45385}, - {f: 2, c: 45394}, {f: 2, c: 45398}, {f: 3, c: 45401}, {f: 3, c: 45405}, - {f: 23, c: 45409}, {f: 2, c: 45434}, {f: 3, c: 45437}, 45441, - {f: 5, c: 45443}, 45450, 45452, {f: 4, c: 45454}, {f: 3, c: 45461}, - {f: 3, c: 45465}, {f: 11, c: 45469}, {f: 35, c: 45481}, {f: 3, c: 45517}, - {f: 3, c: 45521}, {f: 7, c: 45525}, 45534, {f: 8, c: 45536}, - {f: 2, c: 45546}, {f: 3, c: 45549}, {f: 8, c: 45553}, 45562, 45564, - {f: 6, c: 45566}, {f: 2, c: 45574}, {f: 2, c: 45577}, {f: 7, c: 45581}, - 45590, 45592, {f: 6, c: 45594}, {f: 19, c: 45601}, {f: 7, c: 45621}, - {f: 27, c: 45629}, {f: 3, c: 45657}, {f: 3, c: 45661}, {f: 7, c: 45665}, - {f: 10, c: 45674}, {f: 6, c: 45686}, {f: 7, c: 45693}, {f: 3, c: 45702}, - {f: 6, c: 45706}, {f: 2, c: 45714}, {f: 3, c: 45717}, {f: 5, c: 45723}, - 45730, 45732, {f: 3, c: 45735}, 45739, {f: 3, c: 45741}, {f: 3, c: 45745}, - {f: 19, c: 45749}, {f: 2, c: 45770}, {f: 3, c: 45773}, 45777, - {f: 5, c: 45779}, 45786, 45788, {f: 4, c: 45790}, 45795, 45799, - {f: 2, c: 45801}, {f: 3, c: 45808}, 45814, {f: 3, c: 45820}, - {f: 2, c: 45826}, {f: 3, c: 45829}, {f: 7, c: 45833}, 45842, - {f: 6, c: 45846}, {f: 55, c: 45853}, 45911, {f: 2, c: 45913}, 45917, - {f: 4, c: 45920}, 45926, 45928, 45930, {f: 2, c: 45932}, 45935, - {f: 2, c: 45938}, {f: 3, c: 45941}, {f: 7, c: 45945}, 45954, - {f: 6, c: 45958}, {f: 3, c: 45965}, {f: 3, c: 45969}, {f: 11, c: 45973}, - {f: 6, c: 45986}, {f: 3, c: 45993}, {f: 23, c: 45997}, {f: 2, c: 46022}, - {f: 2, c: 46025}, 46029, 46031, {f: 3, c: 46033}, 46038, 46040, 46042, - 46044, {f: 2, c: 46046}, {f: 3, c: 46049}, {f: 3, c: 46053}, - {f: 19, c: 46057}, {f: 19, c: 46077}, {f: 7, c: 46097}, {f: 3, c: 46105}, - {f: 3, c: 46109}, {f: 7, c: 46113}, 46122, {f: 8, c: 46124}, - {f: 27, c: 46133}, {f: 2, c: 46162}, {f: 3, c: 46165}, {f: 7, c: 46169}, - 46178, 46180, {f: 6, c: 46182}, {f: 19, c: 46189}, {f: 7, c: 46209}, - {f: 20, c: 46217}, {f: 6, c: 46238}, {f: 3, c: 46245}, {f: 3, c: 46249}, - {f: 8, c: 46253}, 46262, 46264, {f: 6, c: 46266}, {f: 3, c: 46273}, - {f: 3, c: 46277}, {f: 7, c: 46281}, {f: 4, c: 46289}, {f: 6, c: 46294}, - {f: 2, c: 46302}, {f: 2, c: 46305}, 46309, {f: 5, c: 46311}, 46318, 46320, - {f: 6, c: 46322}, {f: 27, c: 46329}, {f: 2, c: 46358}, {f: 2, c: 46361}, - {f: 7, c: 46365}, 46374, {f: 5, c: 46379}, {f: 2, c: 46386}, - {f: 3, c: 46389}, {f: 7, c: 46393}, 46402, {f: 5, c: 46406}, - {f: 2, c: 46414}, {f: 3, c: 46417}, {f: 7, c: 46421}, 46430, - {f: 62, c: 46434}, {f: 2, c: 46498}, {f: 3, c: 46501}, 46505, - {f: 4, c: 46508}, 46514, {f: 5, c: 46518}, {f: 2, c: 46526}, - {f: 3, c: 46529}, {f: 7, c: 46533}, 46542, {f: 6, c: 46546}, - {f: 19, c: 46553}, {f: 35, c: 46573}, {f: 2, c: 46610}, {f: 3, c: 46613}, - {f: 12, c: 46617}, {f: 6, c: 46630}, {f: 7, c: 46637}, {f: 19, c: 46645}, - {f: 27, c: 46665}, {f: 3, c: 46693}, {f: 51, c: 46697}, {f: 2, c: 46750}, - {f: 3, c: 46753}, {f: 6, c: 46757}, {f: 4, c: 46765}, {f: 34, c: 46770}, - {f: 27, c: 46805}, {f: 3, c: 46833}, {f: 3, c: 46837}, {f: 7, c: 46841}, - {f: 3, c: 46850}, {f: 34, c: 46854}, {f: 2, c: 46890}, {f: 2, c: 46893}, - {f: 7, c: 46897}, 46906, {f: 8, c: 46908}, {f: 3, c: 46917}, - {f: 3, c: 46921}, {f: 7, c: 46925}, {f: 10, c: 46934}, {f: 3, c: 46945}, - {f: 3, c: 46949}, {f: 7, c: 46953}, 46962, 46964, {f: 6, c: 46966}, - {f: 2, c: 46974}, {f: 3, c: 46977}, {f: 7, c: 46981}, 46990, - {f: 3, c: 46995}, {f: 2, c: 47002}, {f: 3, c: 47005}, {f: 7, c: 47009}, - 47018, {f: 6, c: 47022}, {f: 2, c: 47030}, {f: 14, c: 47033}, 47048, - {f: 34, c: 47050}, {f: 2, c: 47086}, {f: 3, c: 47089}, {f: 7, c: 47093}, - 47102, {f: 5, c: 47106}, {f: 2, c: 47114}, {f: 3, c: 47117}, - {f: 7, c: 47121}, 47130, 47132, {f: 6, c: 47134}, {f: 2, c: 47142}, - {f: 3, c: 47145}, {f: 7, c: 47149}, 47158, {f: 6, c: 47162}, - {f: 3, c: 47169}, {f: 12, c: 47173}, 47186, {f: 8, c: 47188}, - {f: 2, c: 47198}, {f: 3, c: 47201}, {f: 7, c: 47205}, 47214, 47216, - {f: 6, c: 47218}, {f: 3, c: 47225}, {f: 16, c: 47229}, {f: 26, c: 47246}, - {f: 7, c: 47273}, {f: 3, c: 47281}, {f: 3, c: 47285}, {f: 7, c: 47289}, - 47298, 47300, {f: 6, c: 47302}, {f: 3, c: 47309}, {f: 3, c: 47313}, - {f: 8, c: 47317}, 47326, 47328, {f: 6, c: 47330}, {f: 2, c: 47338}, - {f: 3, c: 47341}, {f: 7, c: 47345}, 47354, 47356, {f: 6, c: 47358}, - {f: 19, c: 47365}, {f: 7, c: 47385}, {f: 27, c: 47393}, {f: 2, c: 47422}, - {f: 3, c: 47425}, {f: 7, c: 47429}, {f: 2, c: 47437}, 47440, - {f: 6, c: 47442}, {f: 2, c: 47450}, {f: 3, c: 47453}, {f: 7, c: 47457}, - 47466, 47468, {f: 6, c: 47470}, {f: 2, c: 47478}, {f: 3, c: 47481}, - {f: 7, c: 47485}, 47494, 47496, {f: 2, c: 47499}, {f: 29, c: 47503}, - {f: 2, c: 47534}, {f: 3, c: 47537}, {f: 7, c: 47541}, 47550, 47552, - {f: 6, c: 47554}, {f: 2, c: 47562}, 47565, {f: 5, c: 47571}, 47578, 47580, - {f: 2, c: 47583}, 47586, {f: 2, c: 47590}, {f: 3, c: 47593}, - {f: 7, c: 47597}, 47606, {f: 5, c: 47611}, {f: 6, c: 47618}, - {f: 12, c: 47625}, {f: 34, c: 47638}, {f: 2, c: 47674}, {f: 3, c: 47677}, - 47681, {f: 5, c: 47683}, 47690, 47692, {f: 4, c: 47695}, {f: 2, c: 47702}, - {f: 3, c: 47705}, {f: 7, c: 47709}, 47718, {f: 6, c: 47722}, - {f: 2, c: 47730}, {f: 3, c: 47733}, {f: 10, c: 47737}, 47750, - {f: 4, c: 47752}, {f: 27, c: 47757}, 47786, {f: 3, c: 47789}, 47793, - {f: 5, c: 47795}, 47802, 47804, {f: 6, c: 47806}, {f: 3, c: 47813}, - {f: 15, c: 47817}, {f: 34, c: 47834}, {f: 3, c: 47869}, {f: 3, c: 47873}, - {f: 8, c: 47877}, 47886, 47888, {f: 6, c: 47890}, {f: 3, c: 47897}, - {f: 3, c: 47901}, {f: 8, c: 47905}, 47914, {f: 8, c: 47916}, 47927, - {f: 2, c: 47929}, {f: 5, c: 47935}, 47942, 47944, {f: 3, c: 47946}, 47950, - {f: 3, c: 47953}, {f: 3, c: 47957}, {f: 8, c: 47961}, 47970, - {f: 8, c: 47972}, {f: 27, c: 47981}, {f: 3, c: 48009}, {f: 3, c: 48013}, - {f: 19, c: 48017}, {f: 3, c: 48037}, {f: 3, c: 48041}, {f: 7, c: 48045}, - {f: 2, c: 48053}, {f: 8, c: 48056}, {f: 3, c: 48065}, {f: 3, c: 48069}, - {f: 7, c: 48073}, {f: 2, c: 48081}, {f: 36, c: 48084}, {f: 2, c: 48122}, - {f: 2, c: 48125}, 48129, {f: 5, c: 48131}, 48138, 48142, 48144, - {f: 2, c: 48146}, {f: 2, c: 48153}, {f: 4, c: 48160}, 48166, 48168, - {f: 3, c: 48170}, {f: 2, c: 48174}, {f: 2, c: 48178}, {f: 3, c: 48181}, - {f: 7, c: 48185}, 48194, {f: 3, c: 48198}, {f: 2, c: 48202}, - {f: 2, c: 48206}, {f: 12, c: 48209}, {f: 38, c: 48222}, {f: 2, c: 48262}, - {f: 2, c: 48265}, 48269, {f: 5, c: 48271}, 48278, 48280, {f: 5, c: 48283}, - {f: 2, c: 48290}, {f: 2, c: 48293}, {f: 7, c: 48297}, 48306, - {f: 6, c: 48310}, {f: 2, c: 48318}, {f: 3, c: 48321}, {f: 8, c: 48325}, - 48334, {f: 3, c: 48338}, {f: 2, c: 48342}, {f: 3, c: 48345}, - {f: 23, c: 48349}, 48375, {f: 3, c: 48377}, {f: 7, c: 48381}, 48390, 48392, - {f: 6, c: 48394}, {f: 3, c: 48401}, {f: 15, c: 48405}, {f: 7, c: 48421}, - {f: 19, c: 48429}, {f: 7, c: 48449}, {f: 2, c: 48458}, {f: 3, c: 48461}, - {f: 7, c: 48465}, {f: 10, c: 48474}, {f: 3, c: 48485}, {f: 23, c: 48489}, - {f: 2, c: 48514}, {f: 2, c: 48517}, {f: 5, c: 48523}, 48530, 48532, - {f: 3, c: 48534}, 48539, {f: 7, c: 48541}, {f: 11, c: 48549}, - {f: 7, c: 48561}, {f: 27, c: 48569}, {f: 2, c: 48598}, {f: 3, c: 48601}, - {f: 12, c: 48605}, {f: 6, c: 48618}, {f: 3, c: 48625}, {f: 3, c: 48629}, - {f: 7, c: 48633}, {f: 2, c: 48641}, 48644, {f: 6, c: 48646}, - {f: 2, c: 48654}, {f: 3, c: 48657}, {f: 7, c: 48661}, 48670, - {f: 36, c: 48672}, {f: 2, c: 48710}, {f: 3, c: 48713}, 48717, - {f: 5, c: 48719}, 48726, 48728, {f: 4, c: 48732}, {f: 2, c: 48738}, - {f: 3, c: 48741}, 48745, {f: 5, c: 48747}, 48754, {f: 5, c: 48758}, - {f: 2, c: 48766}, {f: 3, c: 48769}, {f: 7, c: 48773}, 48782, - {f: 6, c: 48786}, {f: 14, c: 48794}, {f: 39, c: 48809}, {f: 2, c: 48850}, - {f: 2, c: 48853}, {f: 7, c: 48857}, {f: 2, c: 48865}, {f: 6, c: 48870}, - {f: 20, c: 48877}, {f: 6, c: 48898}, {f: 14, c: 48906}, 48922, - {f: 34, c: 48926}, {f: 2, c: 48962}, {f: 3, c: 48965}, {f: 7, c: 48969}, - {f: 3, c: 48978}, {f: 62, c: 48982}, {f: 27, c: 49045}, {f: 20, c: 49073}, - {f: 6, c: 49094}, {f: 2, c: 49102}, {f: 3, c: 49105}, {f: 7, c: 49109}, - {f: 2, c: 49117}, 49120, {f: 90, c: 49122}, {f: 20, c: 49213}, - {f: 6, c: 49234}, {f: 3, c: 49241}, {f: 3, c: 49245}, {f: 7, c: 49249}, - {f: 38, c: 49258}, {f: 2, c: 49298}, {f: 3, c: 49301}, {f: 7, c: 49305}, - 49314, 49316, {f: 6, c: 49318}, 49326, {f: 2, c: 49329}, {f: 5, c: 49335}, - 49342, {f: 3, c: 49346}, {f: 2, c: 49350}, {f: 2, c: 49354}, - {f: 3, c: 49357}, {f: 7, c: 49361}, 49370, {f: 6, c: 49374}, - {f: 2, c: 49382}, {f: 3, c: 49385}, {f: 7, c: 49389}, 49398, 49400, - {f: 6, c: 49402}, {f: 3, c: 49409}, {f: 3, c: 49413}, {f: 7, c: 49417}, - {f: 4, c: 49425}, {f: 6, c: 49430}, {f: 2, c: 49441}, 49445, - {f: 4, c: 49448}, 49454, {f: 4, c: 49458}, 49463, {f: 2, c: 49466}, - {f: 3, c: 49469}, {f: 7, c: 49473}, 49482, {f: 6, c: 49486}, - {f: 2, c: 49494}, {f: 3, c: 49497}, {f: 7, c: 49501}, 49510, - {f: 6, c: 49514}, {f: 3, c: 49521}, {f: 3, c: 49525}, {f: 12, c: 49529}, - {f: 6, c: 49542}, 49551, {f: 3, c: 49553}, 49557, {f: 5, c: 49559}, 49566, - 49568, {f: 3, c: 49570}, {f: 2, c: 49574}, {f: 2, c: 49578}, - {f: 3, c: 49581}, {f: 12, c: 49585}, {f: 6, c: 49598}, {f: 3, c: 49605}, - {f: 3, c: 49609}, {f: 7, c: 49613}, {f: 2, c: 49621}, {f: 7, c: 49625}, - {f: 3, c: 49633}, {f: 3, c: 49637}, {f: 7, c: 49641}, 49650, - {f: 8, c: 49652}, {f: 2, c: 49662}, {f: 3, c: 49665}, {f: 7, c: 49669}, - 49678, 49680, {f: 6, c: 49682}, {f: 2, c: 49690}, {f: 2, c: 49693}, - {f: 7, c: 49697}, 49706, 49708, 49710, 49712, 49715, {f: 19, c: 49717}, - {f: 7, c: 49737}, {f: 2, c: 49746}, {f: 3, c: 49749}, {f: 7, c: 49753}, - {f: 4, c: 49761}, {f: 6, c: 49766}, {f: 2, c: 49774}, {f: 3, c: 49777}, - {f: 7, c: 49781}, 49790, 49792, {f: 6, c: 49794}, {f: 6, c: 49802}, - {f: 7, c: 49809}, {f: 2, c: 49817}, 49820, {f: 6, c: 49822}, - {f: 2, c: 49830}, {f: 3, c: 49833}, {f: 6, c: 49838}, 49846, 49848, - {f: 34, c: 49850}, {f: 2, c: 49886}, {f: 2, c: 49889}, {f: 6, c: 49893}, - 49902, 49904, {f: 4, c: 49906}, 49911, 49914, {f: 3, c: 49917}, - {f: 7, c: 49921}, {f: 2, c: 49930}, {f: 5, c: 49934}, {f: 2, c: 49942}, - {f: 3, c: 49945}, {f: 7, c: 49949}, {f: 2, c: 49958}, {f: 27, c: 49962}, - {f: 34, c: 49990}, {f: 2, c: 50026}, {f: 3, c: 50029}, 50033, - {f: 5, c: 50035}, {f: 2, c: 50042}, {f: 6, c: 50046}, {f: 3, c: 50053}, - {f: 3, c: 50057}, {f: 51, c: 50061}, {f: 23, c: 50113}, {f: 2, c: 50138}, - {f: 2, c: 50141}, 50145, {f: 5, c: 50147}, {f: 3, c: 50154}, - {f: 6, c: 50158}, {f: 2, c: 50166}, {f: 15, c: 50169}, {f: 7, c: 50185}, - {f: 19, c: 50193}, {f: 7, c: 50213}, {f: 3, c: 50221}, {f: 3, c: 50225}, - {f: 7, c: 50229}, {f: 10, c: 50238}, {f: 27, c: 50249}, {f: 2, c: 50278}, - {f: 3, c: 50281}, {f: 7, c: 50285}, {f: 3, c: 50294}, {f: 6, c: 50298}, - {f: 19, c: 50305}, {f: 7, c: 50325}, {f: 27, c: 50333}, {f: 3, c: 50361}, - {f: 44, c: 50365}, {f: 6, c: 50410}, {f: 2, c: 50418}, {f: 3, c: 50421}, - 50425, {f: 4, c: 50427}, {f: 10, c: 50434}, {f: 3, c: 50445}, - {f: 3, c: 50449}, {f: 7, c: 50453}, {f: 11, c: 50461}, {f: 2, c: 50474}, - {f: 3, c: 50477}, {f: 7, c: 50481}, 50490, 50492, {f: 6, c: 50494}, - {f: 2, c: 50502}, 50507, {f: 4, c: 50511}, 50518, {f: 3, c: 50522}, 50527, - {f: 2, c: 50530}, {f: 3, c: 50533}, {f: 7, c: 50537}, 50546, - {f: 6, c: 50550}, {f: 2, c: 50558}, {f: 3, c: 50561}, {f: 2, c: 50565}, - {f: 4, c: 50568}, 50574, 50576, {f: 3, c: 50578}, 50582, {f: 3, c: 50585}, - {f: 3, c: 50589}, {f: 8, c: 50593}, {f: 10, c: 50602}, {f: 2, c: 50614}, - 50618, {f: 5, c: 50623}, 50635, 50637, 50639, {f: 2, c: 50642}, - {f: 3, c: 50645}, {f: 7, c: 50649}, 50658, 50660, {f: 6, c: 50662}, 50671, - {f: 3, c: 50673}, 50677, {f: 4, c: 50680}, {f: 3, c: 50690}, - {f: 3, c: 50697}, {f: 3, c: 50701}, {f: 7, c: 50705}, 50714, - {f: 7, c: 50717}, {f: 2, c: 50726}, {f: 3, c: 50729}, 50735, - {f: 2, c: 50737}, 50742, 50744, 50746, {f: 4, c: 50748}, {f: 2, c: 50754}, - {f: 3, c: 50757}, {f: 7, c: 50761}, 50770, {f: 6, c: 50774}, - {f: 2, c: 50782}, {f: 11, c: 50785}, {f: 2, c: 50797}, 50800, - {f: 6, c: 50802}, {f: 2, c: 50810}, {f: 3, c: 50813}, {f: 7, c: 50817}, - 50826, 50828, {f: 6, c: 50830}, {f: 2, c: 50838}, {f: 3, c: 50841}, - {f: 7, c: 50845}, 50854, 50856, {f: 6, c: 50858}, {f: 2, c: 50866}, - {f: 3, c: 50869}, {f: 5, c: 50875}, 50882, 50884, {f: 6, c: 50886}, - {f: 2, c: 50894}, {f: 3, c: 50897}, {f: 7, c: 50901}, {f: 2, c: 50910}, - {f: 6, c: 50914}, {f: 2, c: 50922}, {f: 3, c: 50925}, {f: 7, c: 50929}, - {f: 3, c: 50938}, {f: 6, c: 50942}, {f: 2, c: 50950}, {f: 3, c: 50953}, - {f: 7, c: 50957}, 50966, 50968, {f: 6, c: 50970}, {f: 2, c: 50978}, - {f: 3, c: 50981}, {f: 7, c: 50985}, 50994, 50996, 50998, {f: 4, c: 51000}, - {f: 2, c: 51006}, {f: 3, c: 51009}, {f: 5, c: 51013}, 51019, 51022, 51024, - {f: 3, c: 51033}, {f: 3, c: 51037}, {f: 7, c: 51041}, {f: 2, c: 51049}, - {f: 8, c: 51052}, {f: 2, c: 51062}, {f: 3, c: 51065}, {f: 4, c: 51071}, - 51078, {f: 3, c: 51083}, 51087, {f: 2, c: 51090}, 51093, 51097, - {f: 5, c: 51099}, 51106, {f: 5, c: 51111}, {f: 2, c: 51118}, - {f: 3, c: 51121}, {f: 7, c: 51125}, 51134, {f: 6, c: 51138}, - {f: 2, c: 51146}, 51149, 51151, {f: 7, c: 51153}, {f: 4, c: 51161}, - {f: 6, c: 51166}, {f: 3, c: 51173}, {f: 3, c: 51177}, {f: 19, c: 51181}, - {f: 2, c: 51202}, {f: 3, c: 51205}, 51209, {f: 5, c: 51211}, 51218, 51220, - {f: 5, c: 51223}, {f: 2, c: 51230}, {f: 3, c: 51233}, {f: 7, c: 51237}, - 51246, 51248, {f: 6, c: 51250}, {f: 3, c: 51257}, {f: 3, c: 51261}, - {f: 7, c: 51265}, {f: 2, c: 51274}, {f: 6, c: 51278}, {f: 27, c: 51285}, - {f: 2, c: 51314}, {f: 3, c: 51317}, 51321, {f: 5, c: 51323}, 51330, 51332, - {f: 3, c: 51336}, {f: 6, c: 51342}, {f: 8, c: 51349}, 51358, 51360, - {f: 6, c: 51362}, {f: 19, c: 51369}, {f: 6, c: 51390}, {f: 3, c: 51397}, - {f: 3, c: 51401}, {f: 7, c: 51405}, 51414, 51416, {f: 6, c: 51418}, - {f: 2, c: 51426}, {f: 16, c: 51429}, {f: 6, c: 51446}, {f: 2, c: 51454}, - {f: 3, c: 51457}, {f: 5, c: 51463}, 51470, 51472, {f: 6, c: 51474}, - {f: 19, c: 51481}, {f: 7, c: 51501}, {f: 27, c: 51509}, {f: 2, c: 51538}, - {f: 3, c: 51541}, {f: 7, c: 51545}, 51554, {f: 8, c: 51556}, - {f: 3, c: 51565}, {f: 3, c: 51569}, {f: 7, c: 51573}, {f: 11, c: 51581}, - {f: 2, c: 51594}, {f: 3, c: 51597}, {f: 7, c: 51601}, 51610, 51612, - {f: 34, c: 51614}, {f: 2, c: 51650}, {f: 2, c: 51653}, 51657, - {f: 5, c: 51659}, 51666, 51668, {f: 2, c: 51671}, 51675, {f: 2, c: 51678}, - 51681, 51683, {f: 2, c: 51685}, {f: 4, c: 51688}, 51694, {f: 6, c: 51698}, - {f: 2, c: 51706}, {f: 3, c: 51709}, {f: 7, c: 51713}, 51722, - {f: 6, c: 51726}, {f: 3, c: 51733}, {f: 16, c: 51737}, {f: 34, c: 51754}, - {f: 2, c: 51790}, {f: 3, c: 51793}, {f: 7, c: 51797}, 51806, - {f: 6, c: 51810}, {f: 20, c: 51817}, {f: 6, c: 51838}, {f: 19, c: 51845}, - {f: 35, c: 51865}, {f: 2, c: 51902}, {f: 3, c: 51905}, {f: 7, c: 51909}, - 51918, 51920, 51922, {f: 4, c: 51924}, {f: 6, c: 51930}, {f: 11, c: 51937}, - {f: 7, c: 51949}, {f: 19, c: 51957}, {f: 7, c: 51977}, {f: 3, c: 51985}, - {f: 3, c: 51989}, {f: 7, c: 51993}, {f: 31, c: 52002}, {f: 6, c: 52034}, - {f: 2, c: 52042}, {f: 3, c: 52045}, {f: 7, c: 52049}, {f: 3, c: 52058}, - {f: 6, c: 52062}, {f: 19, c: 52069}, {f: 34, c: 52090}, {f: 27, c: 52125}, - {f: 27, c: 52153}, {f: 15, c: 52181}, {f: 2, c: 52197}, 52200, - {f: 34, c: 52202}, {f: 2, c: 52238}, {f: 3, c: 52241}, {f: 7, c: 52245}, - {f: 3, c: 52254}, {f: 4, c: 52259}, {f: 2, c: 52266}, 52269, 52271, - {f: 7, c: 52273}, 52282, {f: 5, c: 52287}, {f: 2, c: 52294}, - {f: 3, c: 52297}, {f: 7, c: 52301}, 52310, {f: 6, c: 52314}, - {f: 3, c: 52321}, 52325, 52327, {f: 7, c: 52329}, {f: 4, c: 52337}, - {f: 34, c: 52342}, {f: 2, c: 52378}, {f: 3, c: 52381}, {f: 7, c: 52385}, - 52394, {f: 6, c: 52398}, {f: 2, c: 52406}, {f: 3, c: 52409}, - {f: 7, c: 52413}, 52422, 52424, {f: 6, c: 52426}, {f: 3, c: 52433}, - {f: 15, c: 52437}, {f: 7, c: 52453}, {f: 3, c: 52461}, {f: 16, c: 52465}, - {f: 6, c: 52482}, {f: 2, c: 52490}, {f: 3, c: 52493}, {f: 7, c: 52497}, - 52506, 52508, {f: 6, c: 52510}, {f: 3, c: 52517}, {f: 3, c: 52521}, - {f: 12, c: 52525}, {f: 34, c: 52538}, {f: 3, c: 52573}, {f: 3, c: 52577}, - {f: 7, c: 52581}, 52590, 52592, {f: 6, c: 52594}, {f: 15, c: 52601}, - {f: 11, c: 52617}, {f: 2, c: 52630}, {f: 3, c: 52633}, {f: 7, c: 52637}, - 52646, 52648, {f: 6, c: 52650}, {f: 19, c: 52657}, {f: 7, c: 52677}, - {f: 3, c: 52685}, {f: 23, c: 52689}, {f: 3, c: 52713}, {f: 3, c: 52717}, - {f: 7, c: 52721}, 52730, 52732, {f: 6, c: 52734}, {f: 3, c: 52741}, - {f: 3, c: 52745}, {f: 7, c: 52749}, {f: 4, c: 52757}, {f: 6, c: 52762}, - {f: 2, c: 52770}, {f: 3, c: 52773}, {f: 7, c: 52777}, 52786, 52788, - {f: 34, c: 52790}, {f: 2, c: 52826}, {f: 2, c: 52829}, {f: 6, c: 52834}, - 52842, 52844, {f: 6, c: 52846}, {f: 2, c: 52854}, {f: 3, c: 52857}, - {f: 7, c: 52861}, 52870, 52872, {f: 6, c: 52874}, {f: 2, c: 52882}, - {f: 3, c: 52885}, {f: 7, c: 52889}, 52898, {f: 6, c: 52902}, - {f: 19, c: 52910}, {f: 34, c: 52930}, {f: 2, c: 52966}, {f: 2, c: 52969}, - {f: 7, c: 52973}, 52982, {f: 6, c: 52986}, {f: 2, c: 52994}, - {f: 3, c: 52997}, {f: 7, c: 53001}, 53010, 53012, {f: 6, c: 53014}, - {f: 3, c: 53021}, {f: 3, c: 53025}, {f: 7, c: 53029}, 53038, - {f: 6, c: 53042}, {f: 27, c: 53049}, {f: 2, c: 53078}, {f: 3, c: 53081}, - {f: 7, c: 53085}, 53094, 53096, {f: 6, c: 53098}, {f: 2, c: 53106}, - {f: 3, c: 53109}, {f: 7, c: 53113}, {f: 4, c: 53121}, {f: 6, c: 53126}, - {f: 20, c: 53133}, {f: 6, c: 53154}, {f: 7, c: 53161}, {f: 19, c: 53169}, - {f: 27, c: 53189}, {f: 2, c: 53218}, {f: 3, c: 53221}, {f: 7, c: 53225}, - 53234, 53236, {f: 6, c: 53238}, {f: 3, c: 53245}, {f: 3, c: 53249}, - {f: 12, c: 53253}, {f: 6, c: 53266}, {f: 20, c: 53273}, {f: 6, c: 53294}, - {f: 2, c: 53302}, {f: 3, c: 53305}, {f: 7, c: 53309}, 53318, 53320, - {f: 6, c: 53322}, {f: 3, c: 53329}, {f: 3, c: 53333}, {f: 7, c: 53337}, - {f: 11, c: 53345}, {f: 2, c: 53358}, {f: 3, c: 53361}, {f: 7, c: 53365}, - {f: 3, c: 53374}, {f: 34, c: 53378}, {f: 2, c: 53414}, {f: 3, c: 53417}, - {f: 7, c: 53421}, 53430, 53432, {f: 6, c: 53434}, {f: 2, c: 53442}, - {f: 3, c: 53445}, {f: 6, c: 53450}, 53458, {f: 6, c: 53462}, - {f: 2, c: 53470}, {f: 3, c: 53473}, {f: 7, c: 53477}, 53486, - {f: 6, c: 53490}, {f: 20, c: 53497}, {f: 34, c: 53518}, {f: 2, c: 53554}, - {f: 3, c: 53557}, 53561, {f: 5, c: 53563}, 53570, {f: 6, c: 53574}, - {f: 2, c: 53582}, {f: 3, c: 53585}, {f: 7, c: 53589}, 53598, 53600, - {f: 6, c: 53602}, {f: 3, c: 53609}, {f: 15, c: 53613}, {f: 7, c: 53629}, - {f: 3, c: 53637}, {f: 23, c: 53641}, {f: 2, c: 53666}, {f: 3, c: 53669}, - {f: 7, c: 53673}, 53682, 53684, {f: 4, c: 53686}, 53691, {f: 3, c: 53693}, - {f: 23, c: 53697}, {f: 27, c: 53721}, {f: 3, c: 53749}, {f: 14, c: 53753}, - 53768, {f: 6, c: 53770}, {f: 27, c: 53777}, {f: 2, c: 53806}, - {f: 3, c: 53809}, {f: 7, c: 53813}, 53822, 53824, {f: 6, c: 53826}, - {f: 19, c: 53833}, {f: 7, c: 53853}, {f: 27, c: 53861}, {f: 2, c: 53890}, - {f: 3, c: 53893}, {f: 7, c: 53897}, {f: 3, c: 53906}, {f: 6, c: 53910}, - {f: 3, c: 53917}, {f: 3, c: 53921}, {f: 7, c: 53925}, {f: 4, c: 53933}, - {f: 6, c: 53938}, {f: 2, c: 53946}, {f: 2, c: 53949}, 53953, - {f: 5, c: 53955}, 53962, {f: 8, c: 53964}, {f: 3, c: 53973}, - {f: 3, c: 53977}, {f: 7, c: 53981}, {f: 10, c: 53990}, {f: 2, c: 54002}, - {f: 3, c: 54005}, {f: 7, c: 54009}, 54018, 54020, {f: 6, c: 54022}, 54031, - {f: 3, c: 54033}, 54037, {f: 5, c: 54039}, 54046, {f: 3, c: 54050}, - {f: 2, c: 54054}, {f: 2, c: 54058}, {f: 3, c: 54061}, {f: 7, c: 54065}, - 54074, {f: 6, c: 54078}, {f: 54, c: 54086}, {f: 2, c: 54142}, - {f: 3, c: 54145}, {f: 7, c: 54149}, 54158, {f: 6, c: 54162}, - {f: 2, c: 54170}, {f: 3, c: 54173}, {f: 7, c: 54177}, 54186, 54188, - {f: 6, c: 54190}, {f: 3, c: 54197}, {f: 3, c: 54201}, {f: 7, c: 54205}, - {f: 2, c: 54214}, {f: 6, c: 54218}, {f: 7, c: 54225}, {f: 8, c: 54233}, - 54242, {f: 8, c: 54244}, {f: 2, c: 54254}, {f: 3, c: 54257}, - {f: 7, c: 54261}, 54270, 54272, {f: 6, c: 54274}, {f: 20, c: 54281}, - {f: 34, c: 54302}, {f: 3, c: 54337}, {f: 23, c: 54341}, {f: 3, c: 54365}, - {f: 3, c: 54369}, {f: 8, c: 54373}, 54382, {f: 8, c: 54384}, - {f: 2, c: 54394}, {f: 2, c: 54397}, 54401, {f: 5, c: 54403}, 54410, 54412, - {f: 6, c: 54414}, {f: 20, c: 54421}, {f: 34, c: 54442}, {f: 3, c: 54477}, - {f: 3, c: 54481}, {f: 7, c: 54485}, {f: 2, c: 54493}, {f: 8, c: 54496}, - {f: 3, c: 54505}, {f: 3, c: 54509}, {f: 7, c: 54513}, {f: 2, c: 54521}, - 54524, {f: 6, c: 54526}, {f: 3, c: 54533}, {f: 3, c: 54537}, - {f: 7, c: 54541}, 54550, {f: 36, c: 54552}, {f: 2, c: 54590}, - {f: 3, c: 54593}, {f: 7, c: 54597}, 54606, 54608, {f: 6, c: 54610}, - {f: 2, c: 54618}, {f: 3, c: 54621}, {f: 4, c: 54625}, {f: 2, c: 54630}, - 54634, 54636, {f: 6, c: 54638}, {f: 2, c: 54646}, {f: 3, c: 54649}, - {f: 7, c: 54653}, 54662, {f: 6, c: 54666}, {f: 20, c: 54673}, - {f: 34, c: 54694}, {f: 2, c: 54730}, {f: 3, c: 54733}, 54737, - {f: 5, c: 54739}, 54746, 54748, {f: 6, c: 54750}, {f: 2, c: 54758}, - {f: 3, c: 54761}, {f: 7, c: 54765}, 54774, 54776, {f: 6, c: 54778}, - {f: 2, c: 54786}, {f: 3, c: 54789}, {f: 7, c: 54793}, 54802, - {f: 6, c: 54806}, {f: 3, c: 54813}, {f: 3, c: 54817}, {f: 8, c: 54821}, - {f: 10, c: 54830}, {f: 2, c: 54842}, {f: 3, c: 54845}, {f: 4, c: 54849}, - {f: 2, c: 54854}, 54858, 54860, {f: 3, c: 54862}, {f: 2, c: 54866}, - {f: 2, c: 54870}, {f: 3, c: 54873}, {f: 10, c: 54877}, 54888, - {f: 6, c: 54890}, {f: 2, c: 54898}, {f: 14, c: 54901}, 54916, - {f: 6, c: 54918}, {f: 2, c: 54926}, {f: 3, c: 54929}, {f: 8, c: 54933}, - 54942, 54944, {f: 6, c: 54946}, {f: 3, c: 54953}, {f: 3, c: 54957}, - {f: 8, c: 54961}, 54970, {f: 8, c: 54972}, {f: 2, c: 54982}, - {f: 3, c: 54985}, {f: 4, c: 54989}, {f: 2, c: 54994}, {f: 2, c: 54997}, - 55000, {f: 6, c: 55002}, {f: 3, c: 55009}, {f: 3, c: 55013}, - {f: 7, c: 55017}, {f: 4, c: 55025}, {f: 6, c: 55030}, {f: 2, c: 55038}, - {f: 3, c: 55041}, {f: 12, c: 55045}, {f: 6, c: 55058}, {f: 2, c: 55066}, - {f: 3, c: 55069}, {f: 7, c: 55073}, 55082, 55084, {f: 6, c: 55086}, - {f: 2, c: 55094}, {f: 3, c: 55097}, {f: 7, c: 55101}, {f: 2, c: 55109}, - 55112, {f: 6, c: 55114}, {f: 2, c: 55122}, 55125, {f: 6, c: 55130}, 55138, - 55140, {f: 3, c: 55142}, {f: 2, c: 55146}, {f: 3, c: 55149}, - {f: 3, c: 55153}, {f: 7, c: 55157}, {f: 3, c: 55166}, {f: 6, c: 55170}, - {f: 2, c: 55178}, {f: 3, c: 55181}, {f: 7, c: 55185}, 55194, 55196, - {f: 6, c: 55198}], - 'Adobe-CNS1': [{f: 95, c: 32}, {s: 3}, 12288, 65292, {f: 2, c: 12289}, 65294, - 8226, 65307, 65306, 65311, 65281, 65072, 8230, 8229, 65104, 65380, 65106, - 183, {f: 4, c: 65108}, 65372, 8211, 65073, 8212, {s: 4}, {f: 2, c: 65288}, - {f: 2, c: 65077}, 65371, 65373, {f: 2, c: 65079}, {f: 2, c: 12308}, - {f: 2, c: 65081}, {f: 2, c: 12304}, {f: 2, c: 65083}, {f: 2, c: 12298}, - {f: 2, c: 65085}, {f: 2, c: 12296}, {f: 2, c: 65087}, {f: 2, c: 12300}, - {f: 2, c: 65089}, {f: 2, c: 12302}, {f: 2, c: 65091}, {f: 6, c: 65113}, - {f: 2, c: 8216}, {f: 2, c: 8220}, {f: 2, c: 12317}, 8245, 8242, 65283, - 65286, 65290, 8251, 167, 12291, 9675, 9679, 9651, 9650, 9678, 9734, 9733, - 9671, 9670, 9633, 9632, 9661, 9660, 12963, 8453, 8254, 0, 65343, 0, - {f: 2, c: 65097}, {f: 2, c: 65101}, {f: 2, c: 65099}, {f: 3, c: 65119}, - 65291, 65293, 215, 247, 177, 8730, 65308, 65310, 65309, {f: 2, c: 8806}, - 8800, 8734, 8786, 8801, {f: 5, c: 65122}, 8764, {f: 2, c: 8745}, 8869, - 8736, 8735, 8895, 13266, 13265, 8747, 8750, 8757, 8756, 9792, 9794, 9793, - 9737, 8593, 8595, 8594, 8592, {f: 2, c: 8598}, 8601, 8600, 8741, 8739, 0, - 0, 65295, 65340, 65284, 165, 12306, {f: 2, c: 162}, 65285, 65312, 8451, - 8457, {f: 3, c: 65129}, 13269, {f: 3, c: 13212}, 13262, 13217, - {f: 2, c: 13198}, 13252, 176, [20825, 58834], [20827, 58835], - [20830, 58837], [20829, 58836], 20833, 20835, 21991, [29929, 58044], - [31950, 58191], {f: 8, c: 9601}, 9615, 9614, 9613, 9612, 9611, 9610, 9609, - 9532, 9524, 9516, 9508, 9500, 9620, 9472, 9474, 9621, 9484, 9488, 9492, - 9496, {f: 2, c: 9581}, 9584, 9583, 9552, 9566, 9578, 9569, {f: 2, c: 9698}, - 9701, 9700, {f: 3, c: 9585}, {f: 10, c: 65296}, {f: 10, c: 8544}, - {f: 9, c: 12321}, 0, [21316, 57443], 0, {f: 26, c: 65313}, - {f: 26, c: 65345}, {f: 17, c: 913}, {f: 7, c: 931}, {f: 17, c: 945}, - {f: 7, c: 963}, {f: 37, c: 12549}, 729, 714, 711, 715, [9312, 63153], - [9313, 63154], [9314, 63155], [9315, 63156], [9316, 63157], [9317, 63158], - [9318, 63159], [9319, 63160], [9320, 63161], [9321, 63162], [9332, 63163], - [9333, 63164], [9334, 63165], [9335, 63166], [9336, 63167], [9337, 63168], - [9338, 63169], [9339, 63170], [9340, 63171], [9341, 63172], [8560, 63173], - [8561, 63174], [8562, 63175], [8563, 63176], [8564, 63177], [8565, 63178], - [8566, 63179], [8567, 63180], [8568, 63181], [8569, 63182], [12033, 20008], - [12034, 20022, 63183], [12035, 20031, 63184], [12037, 20101, 63185], - [12039, 20128, 63186], [12044, 20866, 63187], [12045, 20886, 63188], - [12046, 20907, 63189], [12051, 21241, 63190], [12054, 21304, 63191], - [12057, 21353, 63192], [12059, 21430, 63193], - [12065, 12066, 22786, 22794, 63194], [12071, 23424, 63195], - [12078, 24027, 63196], [12083, 24186, 63197], [12084, 24191, 63198], - [12085, 24308], [12089, 24400, 63200], [12090, 24417, 63201], - [12097, 25908, 63202], [12102, 26080], [12135, 30098, 63204], - [12136, 30326], [12193, 36789, 63206], [12202, 38582], {f: 32, c: 9216}, - 9249, [12032, 19968], [12036, 20057], 19969, 19971, 20035, 20061, 20102, - [12038, 20108], [12040, 20154], [12041, 20799], [12042, 20837], - [12043, 20843], [12047, 20960], [12049, 20992], 20993, [12050, 21147], - [12052, 21269], [12055, 21313], [12056, 21340], [12060, 21448], 19977, - 19979, 19976, 19978, 20011, 20024, 20961, 20037, 20040, 20063, 20062, - 20110, 20129, [20800, 64012], 20995, 21242, 21315, 21449, [12061, 21475], - [12063, 22303], [12064, 22763], [12067, 22805], [12068, 22823], - [12069, 22899], [12070, 23376], 23377, 23379, [12072, 23544], - [12073, 23567], [12074, 23586], [12075, 23608], [12077, 23665], 24029, - [12079, 24037], [12080, 24049], {f: 2, c: 24050}, [12081, 24062], - [12082, 24178], [12086, 24318], [12087, 24331], [12088, 24339], 25165, - 19985, 19984, 19981, 20013, 20016, 20025, 20043, 23609, 20104, 20113, - 20117, 20114, 20116, 20130, 20161, 20160, 20163, {f: 2, c: 20166}, 20173, - {f: 2, c: 20170}, 20164, 20803, 20801, 20839, {f: 2, c: 20845}, 20844, - 20887, 20982, {f: 3, c: 20998}, 21243, {f: 2, c: 21246}, 21270, 21305, - 21320, 21319, 21317, 21342, 21380, 21451, 21450, 21453, 22764, 22825, - 22827, 22826, 22829, 23380, 23569, 23588, 23610, 23663, 24052, 24187, - 24319, {f: 2, c: 24340}, [12092, 24515], [12093, 25096], [12094, 25142], - [12095, 25163], 25166, [12096, 25903], [12098, 25991], [12099, 26007], - [12100, 26020], [12101, 26041], [12103, 26085], [12104, 26352], - [12105, 26376], [12106, 26408], [12107, 27424], [12108, 27490], - [12109, 27513], [12111, 27595], [12112, 27604], [12113, 27611], - [12114, 27663], [12116, 27700], [12117, 28779], [12118, 29226], - [12119, 29238], [12120, 29243], [12122, 29255], [12123, 29273], - [12124, 29275], [12125, 29356], 29579, 19993, 19990, 19989, 19988, 19992, - 20027, 20045, 20047, 20046, 20197, 20184, {f: 4, c: 20180}, - {f: 2, c: 20195}, 20185, 20190, 20805, 20804, {f: 2, c: 20873}, 20908, - {f: 2, c: 20985}, 20984, 21002, 21152, 21151, [21253, 57435], 21254, 21271, - 21277, 20191, 21322, 21321, 21345, 21344, 21359, 21358, 21435, 21487, - 21476, 21491, 21484, 21486, 21481, 21480, 21500, 21496, 21493, 21483, - 21478, 21482, 21490, 21489, 21488, 21477, 21485, 21499, 22235, 22234, - 22806, 22830, 22833, 22900, 22902, 23381, 23427, 23612, 24040, 24039, - 24038, {f: 2, c: 24066}, 24179, 24188, 24321, 24344, 24343, 24517, 25098, - {f: 2, c: 25171}, 25170, 25169, 26021, 26086, 26414, 26412, - {f: 2, c: 26410}, 26413, 27491, 27597, 27665, 27664, 27704, 27713, 27712, - 27710, 29359, [12126, 29572], [12127, 29577], [12128, 29916], - [12129, 29926], [12130, 29976], [12131, 29983], [12132, 29992], 29993, - [12133, 30000], {f: 3, c: 30001}, [12134, 30091], [12137, 30333], - [12138, 30382], [12139, 30399], [12140, 30446], [12141, 30683], - [12142, 30690], [12143, 30707], [12144, 31034], [12146, 31166], - [12147, 31348], [12148, 31435], {f: 2, c: 19998}, {f: 2, c: 20050}, 20073, - 20121, 20132, 20134, 20133, 20223, 20233, 20249, 20234, 20245, 20237, - {f: 2, c: 20240}, 20239, 20210, 20214, 20219, 20208, 20211, 20221, 20225, - 20235, 20809, 20807, 20806, 20808, 20840, 20849, 20877, 20912, 21015, - {f: 2, c: 21009}, 21006, 21014, 21155, 21256, 21281, 21280, - {f: 2, c: 21360}, 21513, 21519, 21516, 21514, 21520, 21505, 21515, 21508, - 21521, 21517, 21512, 21507, 21518, 21510, 21522, 22240, 22238, 22237, - 22323, 22320, 22312, 22317, 22316, 22319, 22313, {f: 2, c: 22809}, - {f: 2, c: 22839}, 22916, 22904, 22915, 22909, 22905, 22914, 22913, - {f: 2, c: 23383}, {f: 2, c: 23431}, 23429, 23433, 23546, 23574, 23673, - 24030, 24070, 24182, 24180, 24335, 24347, 24537, 24534, 25102, - {f: 2, c: 25100}, 25104, 25187, 25179, 25176, 25910, 26089, 26088, - {f: 2, c: 26092}, {f: 2, c: 26354}, 26377, 26429, 26420, 26417, 26421, - 27425, 27492, 27515, 27670, 27741, 27735, 27737, {f: 2, c: 27743}, 27728, - 27733, 27745, 27739, {f: 2, c: 27725}, 28784, 29279, 29277, 30334, - [12149, 31481], [12150, 31859], [12151, 31992], [12152, 32566], - [12154, 32650], [12155, 32701], [12156, 32769], 32771, [12157, 32780], - [12158, 32786], [12159, 32819], [12160, 32895], [12161, 32905], - {f: 2, c: 32907}, [12162, 33251], [12163, 33258], [12164, 33267], - [12165, 33276], [12166, 33292], [12167, 33307], [12168, 33311], - [12169, 33390], [12170, 33394], 33406, [12173, 34411], [12174, 34880], - [12175, 34892], [12176, 34915], 35199, 38433, 20018, 20136, 20301, 20303, - 20295, 20311, 20318, 20276, 20315, 20309, 20272, {f: 2, c: 20304}, 20285, - 20282, 20280, 20291, 20308, 20284, 20294, 20323, 20316, 20320, 20271, - 20302, 20278, 20313, 20317, 20296, 20314, 20812, 20811, 20813, 20853, - {f: 2, c: 20918}, 21029, 21028, {f: 2, c: 21033}, 21032, 21163, - {f: 2, c: 21161}, 21164, 21283, 21363, 21365, 21533, 21549, 21534, 21566, - 21542, 21582, 21543, 21574, 21571, 21555, 21576, 21570, 21531, 21545, - 21578, 21561, 21563, 21560, 21550, {f: 2, c: 21557}, 21536, 21564, 21568, - 21553, 21547, 21535, 21548, 22250, 22256, 22244, 22251, 22346, 22353, - 22336, 22349, 22343, 22350, 22334, 22352, 22351, 22331, 22767, 22846, - 22941, 22930, 22952, 22942, 22947, 22937, 22934, 22925, 22948, 22931, - 22922, 22949, 23389, 23388, {f: 2, c: 23386}, 23436, 23435, 23439, 23596, - {f: 2, c: 23616}, 23615, 23614, {f: 2, c: 23696}, 23700, 23692, 24043, - 24076, 24207, 24199, 24202, 24311, 24324, 24351, 24420, 24418, 24439, - 24441, 24536, 24524, 24535, 24525, 24561, 24555, 24568, 24554, 25106, - 25105, 25220, 25239, 25238, 25216, 25206, 25225, 25197, 25226, 25212, - 25214, 25209, 25203, 25234, 25199, 25240, 25198, 25237, 25235, 25233, - 25222, 25913, 25915, 25912, 26097, 26356, 26463, {f: 4, c: 26446}, 26460, - 26454, [26462, 57801], 26441, 26438, 26464, 26451, 26455, 27493, 27599, - 27714, 27742, 27801, 27777, {f: 2, c: 27784}, 27781, 27803, 27754, 27770, - 27792, 27760, 27788, 27752, 27798, 27794, 27773, 27779, 27762, 27774, - 27764, 27782, 27766, 27789, 27796, 27800, 27778, 28790, {f: 2, c: 28796}, - 28792, 29282, 29281, 29280, 29380, 29378, 29590, 29996, 29995, - {f: 2, c: 30007}, 30338, 30447, 30691, 31169, 31168, 31167, 31350, 31995, - 32597, 32918, 32915, 32925, 32920, 32923, 32922, 32946, 33391, 33426, - 33419, 33421, [12178, 35211], [12179, 35282], [12180, 35328], - [12181, 35895], [12182, 35910], [12183, 35925], [12185, 35997], - [12186, 36196], [12187, 36208], [12188, 36275], [12189, 36523], - [12190, 36554], [12191, 36763], [12192, 36784], 36802, 36806, 36805, 36804, - 24033, [12194, 37009], 37026, 37034, 37030, 37027, [12195, 37193], - [12196, 37318], [12197, 37324], 38450, 38446, 38449, 38442, 38444, 20006, - 20054, 20083, 20107, 20123, 20126, {f: 2, c: 20139}, 20335, 20381, 20365, - 20339, 20351, 20332, 20379, 20363, 20358, 20355, 20336, 20341, 20360, - 20329, 20347, 20374, 20350, 20367, 20369, 20346, 20820, 20818, 20821, - 20841, 20855, 20854, 20856, 20925, 20989, 21051, 21048, 21047, 21050, - 21040, 21038, 21046, 21057, 21182, 21179, 21330, 21332, 21331, 21329, - 21350, {f: 3, c: 21367}, 21462, 21460, 21463, 21619, 21621, 21654, 21624, - 21653, 21632, 21627, 21623, 21636, 21650, 21638, 21628, 21648, 21617, - 21622, 21644, 21658, 21602, 21608, 21643, 21629, 21646, 22266, 22403, - 22391, 22378, 22377, 22369, 22374, 22372, 22396, 22812, 22857, - {f: 2, c: 22855}, 22852, 22868, 22974, 22971, 22996, 22969, 22958, 22993, - 22982, 22992, 22989, 22987, 22995, 22986, 22959, 22963, 22994, 22981, - 23391, 23396, 23395, 23447, 23450, 23448, 23452, 23449, 23451, 23578, - 23624, {f: 2, c: 23621}, 23735, 23713, 23736, 23721, 23723, 23729, 23731, - 24088, 24090, 24086, 24085, 24091, 24081, 24184, 24218, 24215, 24220, - {f: 2, c: 24213}, 24310, {f: 2, c: 24358}, 24361, {f: 2, c: 24448}, 24447, - 24444, 24541, 24544, 24573, 24565, 24575, 24591, 24596, 24623, 24629, - 24598, 24618, 24597, 24609, 24615, 24617, 24619, 24603, 25110, 25109, - 25151, 25150, 25152, 25215, 25289, 25292, 25284, 25279, 25282, 25273, - 25298, 25307, 25259, {f: 2, c: 25299}, 25291, 25288, 25256, 25277, 25276, - [25296, 60582], 25305, 25287, 25293, 25269, 25306, 25265, 25304, - {f: 2, c: 25302}, 25286, 25260, [25294, 61010], 25918, 26023, 26044, 26106, - 26132, 26131, 26124, 26118, 26114, 26126, 26112, 26127, 26133, 26122, - 26119, 26381, 26379, 26477, 26507, 26517, 26481, 26524, 26483, 26487, - 26503, 26525, 26519, {f: 2, c: 26479}, 26495, 26505, 26494, 26512, 26485, - 26522, 26515, 26492, 26474, 26482, 27427, {f: 2, c: 27494}, 27519, 27667, - 27675, 27875, 27880, 27891, 27825, 27852, 27877, 27827, {f: 2, c: 27837}, - 27836, 27874, 27819, 27861, 27859, 27832, 27844, 27833, 27841, 27822, - 27863, 27845, 27889, 27839, 27835, 27873, 27867, 27850, 27820, 27887, - 27868, 27862, 27872, 28821, 28814, 28818, 28810, 28825, {f: 2, c: 29228}, - 29240, 29256, 29287, 29289, 29376, 29390, 29401, 29399, 29392, 29609, - 29608, 29599, 29611, 29605, 30013, 30109, {f: 2, c: 30105}, 30340, 30402, - 30450, 30452, 30693, 30717, 31038, {f: 2, c: 31040}, 31177, 31176, 31354, - 31353, 31482, 31998, 32596, 32652, 32651, [32773, 58236], 32954, 32933, - 32930, 32945, 32929, 32939, 32937, 32948, 32938, 32943, 33253, 33278, - 33293, 33459, 33437, 33433, 33453, 33469, 33439, 33465, 33457, 33452, - 33445, 33455, 33464, 33443, 33456, 33470, 33463, 34382, 34417, 21021, - 34920, 36555, 36814, 36820, 36817, 37045, 37048, 37041, 37046, 37319, - [12198, 37329], [12199, 38263], [12200, 38272], [12201, 38428], 38464, - 38463, 38459, 38468, 38466, [12203, 38585], [12204, 38632], 38738, - [12206, 38750], 20127, {f: 2, c: 20141}, 20449, 20405, 20399, 20415, 20448, - 20433, 20431, 20445, 20419, 20406, 20440, 20447, 20426, 20439, 20398, - 20432, 20420, 20418, 20442, 20430, 20446, 20407, 20823, 20882, 20881, - 20896, 21070, 21059, 21066, 21069, 21068, 21067, 21063, 21191, 21193, - 21187, 21185, 21261, 21335, 21371, 21402, 21467, 21676, 21696, 21672, - 21710, 21705, 21688, 21670, 21683, 21703, 21698, 21693, 21674, 21697, - 21700, 21704, 21679, 21675, 21681, 21691, 21673, 21671, 21695, 22271, - 22402, 22411, 22432, 22435, 22434, 22478, 22446, 22419, 22869, 22865, - 22863, 22862, 22864, 23004, 23000, 23039, 23011, 23016, 23043, 23013, - 23018, 23002, 23014, 23041, 23035, 23401, 23459, 23462, 23460, 23458, - 23461, 23553, {f: 2, c: 23630}, 23629, 23627, 23769, 23762, 24055, 24093, - 24101, 24095, 24189, 24224, 24230, 24314, 24328, 24365, 24421, 24456, - 24453, {f: 2, c: 24458}, 24455, 24460, 24457, 24594, 24605, 24608, 24613, - 24590, 24616, 24653, 24688, 24680, [24674, 60712], 24646, 24643, 24684, - 24683, 24682, 24676, 25153, 25308, 25366, 25353, 25340, 25325, 25345, - 25326, 25341, 25351, 25329, 25335, 25327, 25324, 25342, 25332, 25361, - 25346, 25919, 25925, 26027, 26045, 26082, 26149, 26157, 26144, 26151, - 26159, 26143, 26152, 26161, 26148, 26359, 26623, 26579, 26609, 26580, - 26576, 26604, 26550, 26543, 26613, 26601, 26607, 26564, 26577, 26548, - 26586, 26597, 26552, 26575, 26590, 26611, 26544, 26585, 26594, 26589, - 26578, 27498, 27523, 27526, 27573, 27602, 27607, 27679, 27849, 27915, - 27954, 27946, 27969, 27941, 27916, 27953, 27934, 27927, 27963, - {f: 2, c: 27965}, 27958, 27931, 27893, 27961, 27943, 27960, 27945, 27950, - 27957, 27918, 27947, 28843, 28858, 28851, 28844, 28847, 28845, 28856, - 28846, 28836, 29232, 29298, 29295, 29300, 29417, {f: 2, c: 29408}, 29623, - 29642, 29627, 29618, 29645, 29632, 29619, 29978, 29997, 30031, 30028, - 30030, 30027, 30123, {f: 2, c: 30116}, {f: 2, c: 30114}, 30328, - {f: 3, c: 30342}, 30408, 30406, 30403, 30405, 30465, 30457, 30456, 30473, - 30475, 30462, 30460, 30471, 30684, 30722, 30740, {f: 2, c: 30732}, 31046, - 31049, 31048, 31047, {f: 2, c: 31161}, {f: 2, c: 31185}, 31179, 31359, - 31361, 31487, 31485, 31869, 32002, 32005, 32000, 32009, 32007, 32004, - 32006, 32568, 32654, 32703, 32784, 32781, 32785, 32822, 32982, 32997, - 32986, {f: 2, c: 32963}, 32972, 32993, 32987, 32974, 32990, 32996, 32989, - 33268, 33314, 33511, 33539, 33541, 33507, 33499, 33510, 33540, 33509, - 33538, 33545, 33490, 33495, 33521, 33537, 33500, 33492, 33489, 33502, - 33491, 33503, 33519, 33542, 34384, 34425, 34427, 34426, 34893, 34923, - 35201, 35284, 35336, {f: 2, c: 35330}, 35998, 36000, 36212, 36211, 36276, - 36557, 36556, 36848, 36838, 36834, 36842, 36837, 36845, 36843, 36836, - 36840, 37066, 37070, 37057, 37059, 37195, 37194, 37325, 38274, 38480, - {f: 3, c: 38475}, [12207, 38754], [12208, 38761], [12209, 38859], - [12210, 38893], [12211, 38899], [12212, 38913], [12213, 39080], - [12214, 39131], [12215, 39135], [12216, 39318], [12217, 39321], 20056, - 20147, {f: 2, c: 20492}, 20515, 20463, 20518, 20517, 20472, [20521, 57375], - 20502, 20486, 20540, 20511, 20506, 20498, 20497, 20474, 20480, 20500, - 20520, 20465, 20513, 20491, 20505, 20504, 20467, 20462, 20525, 20522, - 20478, 20523, 20489, 20860, {f: 2, c: 20900}, 20898, 20941, 20940, 20934, - 20939, 21078, 21084, 21076, 21083, 21085, 21290, [21375, 57459], 21407, - 21405, 21471, 21736, 21776, 21761, 21815, 21756, 21733, 21746, 21766, - 21754, 21780, 21737, 21741, 21729, 21769, 21742, 21738, 21734, 21799, - 21767, 21757, 21775, {f: 2, c: 22275}, 22466, 22484, 22475, 22467, 22537, - 22799, {f: 2, c: 22871}, 22874, 23057, 23064, 23068, 23071, 23067, 23059, - 23020, 23072, 23075, 23081, 23077, 23052, 23049, 23403, 23640, 23472, - 23475, 23478, 23476, 23470, 23477, 23481, 23480, 23556, 23633, 23637, - 23632, 23789, 23805, 23803, 23786, 23784, 23792, 23798, 23809, 23796, - 24046, 24109, 24107, 24235, 24237, 24231, 24369, 24466, 24465, 24464, - 24665, 24675, 24677, 24656, 24661, 24685, 24681, 24687, 24708, 24735, - 24730, 24717, 24724, 24716, 24709, 24726, 25159, 25331, 25352, 25343, - 25422, 25406, 25391, 25429, 25410, 25414, 25423, 25417, 25402, 25424, - 25405, {f: 2, c: 25386}, 25384, 25421, 25420, {f: 2, c: 25928}, 26009, - 26049, 26053, 26178, 26185, 26191, 26179, 26194, 26188, 26181, 26177, - 26360, {f: 2, c: 26388}, 26391, 26657, 26680, 26696, 26694, 26707, 26681, - 26690, 26708, 26665, 26803, 26647, 26700, 26705, 26685, 26612, 26704, - 26688, 26684, 26691, 26666, 26693, 26643, 26648, 26689, 27530, 27529, - 27575, 27683, {f: 2, c: 27687}, 27686, 27684, 27888, 28010, 28053, 28040, - 28039, 28006, 28024, 28023, 27993, 28051, 28012, 28041, 28014, 27994, - 28020, 28009, 28044, 28042, 28025, 28037, 28005, 28052, 28874, 28888, - 28900, 28889, 28872, 28879, 29241, 29305, 29436, 29433, 29437, 29432, - 29431, 29574, 29677, 29705, 29678, 29664, 29674, 29662, 30036, 30045, - 30044, 30042, 30041, 30142, 30149, 30151, {f: 2, c: 30130}, 30141, 30140, - 30137, 30146, 30136, 30347, 30384, 30410, {f: 2, c: 30413}, 30505, - {f: 2, c: 30495}, 30504, 30697, 30768, 30759, 30776, 30749, 30772, 30775, - 30757, 30765, 30752, 30751, 30770, 31061, 31056, 31072, 31071, 31062, - 31070, 31069, 31063, 31066, 31204, [31203, 60418], 31207, 31199, 31206, - 31209, 31192, 31364, 31368, 31449, 31494, 31505, 31881, 32033, 32023, - 32011, 32010, 32032, 32034, 32020, 32016, 32021, 32026, 32028, 32013, - 32025, 32027, 32570, 32607, 32660, 32709, 32705, 32774, 32772, 32792, - 32789, 32793, 32791, 32829, 32831, 33009, 33026, 33008, 33029, 33005, - 33012, 33030, 33016, 33011, 33032, 33021, 33034, 33020, 33007, 33261, - 33260, 33280, 33296, {f: 2, c: 33322}, 33320, 33324, 33467, 33579, 33618, - 33620, 33610, 33592, 33616, 33609, 33589, 33588, 33615, 33586, 33593, - 33590, 33559, 33600, 33585, 33576, 33603, 34388, 34442, 34474, 34451, - 34468, 34473, 34444, 34467, 34460, 34928, 34935, {f: 2, c: 34945}, 34941, - 34937, 35352, 35344, 35342, 35340, 35349, 35338, 35351, 35347, 35350, - 35343, 35345, 35912, 35962, 35961, {f: 2, c: 36001}, [36215, 58442], 36524, - 36562, 36564, 36559, 36785, 36865, 36870, 36855, 36864, 36858, 36852, - 36867, 36861, 36869, 36856, 37013, 37089, 37085, 37090, 37202, 37197, - 37196, 37336, 37341, 37335, 37340, 37337, 38275, {f: 2, c: 38498}, 38497, - 38491, 38493, 38500, 38488, 38494, 38587, 39138, [12218, 39340], - [12219, 39592], [12220, 39640], [12222, 39717], [12224, 39730], - [12225, 39740], 20094, 20602, [20605, 57382], 20572, 20551, 20547, 20556, - 20570, 20553, 20581, 20598, 20558, 20565, 20597, 20596, 20599, 20559, - 20495, 20591, 20589, 20828, 20885, 20976, 21098, 21103, 21202, 21209, - 21208, 21205, 21264, 21263, 21273, {f: 2, c: 21311}, 21310, 21443, 26364, - 21830, 21866, 21862, 21828, 21854, 21857, 21827, 21834, 21809, 21846, - 21839, 21845, 21807, 21860, 21816, 21806, 21852, 21804, 21859, 21811, - 21825, 21847, 22280, 22283, 22281, 22495, 22533, 22538, 22534, 22496, - 22500, 22522, 22530, 22581, 22519, 22521, 22816, 22882, 23094, 23105, - 23113, 23142, 23146, 23104, 23100, 23138, 23130, 23110, 23114, 23408, - 23495, 23493, 23492, 23490, 23487, 23494, 23561, 23560, 23559, 23648, - {f: 2, c: 23644}, 23815, 23814, 23822, 23835, 23830, 23842, 23825, 23849, - 23828, 23833, 23844, 23847, 23831, 24034, 24120, 24118, 24115, 24119, - {f: 2, c: 24247}, 24246, 24245, 24254, 24373, 24375, 24407, 24428, 24425, - 24427, 24471, 24473, 24478, 24472, 24481, 24480, 24476, 24703, 24739, - 24713, 24736, 24744, 24779, 24756, 24806, 24765, 24773, 24763, 24757, - 24796, 24764, 24792, 24789, 24774, 24799, 24760, 24794, 24775, - {f: 2, c: 25114}, 25160, 25504, 25511, 25458, 25494, 25506, 25509, 25463, - 25447, 25496, 25514, 25457, 25513, 25481, 25475, 25499, 25451, 25512, - 25476, 25480, 25497, 25505, 25516, 25490, 25487, 25472, 25467, 25449, - 25448, 25466, 25949, 25942, 25937, 25945, 25943, 21855, 25935, 25944, - 25941, 25940, 26012, 26011, 26028, 26063, {f: 2, c: 26059}, 26062, 26205, - 26202, 26212, 26216, 26214, 26206, 26361, 21207, 26395, 26753, 26799, - 26786, 26771, 26805, 26751, 26742, 26801, 26791, 26775, 26800, 26755, - 26820, 26797, 26758, 26757, 26772, 26781, 26792, 26783, 26785, 26754, - 27442, 27578, {f: 2, c: 27627}, 27691, 28046, 28092, 28147, 28121, 28082, - 28129, 28108, 28132, 28155, 28154, 28165, 28103, 28107, 28079, 28113, - 28078, 28126, 28153, 28088, 28151, 28149, 28101, 28114, 28186, 28085, - 28122, 28139, 28120, 28138, 28145, 28142, 28136, 28102, 28100, 28074, - 28140, 28095, 28134, 28921, {f: 2, c: 28937}, 28925, 28911, 29245, 29309, - 29313, 29468, 29467, 29462, 29459, 29465, 29575, 29701, 29706, 29699, - 29702, 29694, 29709, 29920, {f: 2, c: 29942}, 29980, 29986, - {f: 2, c: 30053}, 30050, 30064, 30095, {f: 2, c: 30164}, 30133, 30154, - 30157, 30350, 30420, 30418, 30427, 30519, 30526, 30524, 30518, 30520, - 30522, 30827, 30787, 30798, 31077, 31080, 31085, 31227, 31378, 31381, - 31520, 31528, 31515, 31532, 31526, 31513, 31518, 31534, 31890, 31895, - 31893, 32070, 32067, 32113, 32046, 32057, 32060, 32064, 32048, 32051, - 32068, 32047, 32066, 32050, 32049, 32573, 32670, 32666, 32716, 32718, - 32722, 32796, 32842, 32838, 33071, 33046, 33059, 33067, 33065, 33072, - 33060, 33282, 33333, 33335, 33334, 33337, 33678, 33694, 33688, 33656, - 33698, 33686, 33725, 33707, 33682, 33674, 33683, 33673, 33696, 33655, - {f: 2, c: 33659}, 33670, 33703, 34389, 24426, 34503, 34496, 34486, 34500, - 34485, 34502, 34507, 34481, 34479, 34505, 34899, 34974, 34952, 34987, - 34962, 34966, 34957, 34955, 35219, 35215, 35370, 35357, 35363, 35365, - 35377, 35373, 35359, 35355, 35362, 35913, 35930, 36009, 36012, 36011, - 36008, 36010, 36007, 36199, 36198, 36286, 36282, 36571, 36575, 36889, - 36877, 36890, 36887, 36899, 36895, 36893, 36880, 36885, 36894, 36896, - 36879, 36898, 36886, 36891, 36884, 37096, 37101, [37117, 58488], 37207, - 37326, 37365, 37350, 37347, 37351, 37357, 37353, 38281, 38506, 38517, - 38515, 38520, 38512, 38516, {f: 2, c: 38518}, 38508, 38592, 38634, 38633, - 31456, 31455, {f: 2, c: 38914}, [12226, 39770], [12227, 40165], - [12228, 40565], [12229, 40575], [12230, 40613], [12231, 40635], 20642, - 20621, 20613, 20633, 20625, 20608, 20630, 20632, 20634, 26368, 20977, - 21106, {f: 2, c: 21108}, 21097, 21214, 21213, 21211, 21338, 21413, 21883, - 21888, 21927, 21884, 21898, 21917, 21912, 21890, 21916, 21930, 21908, - 21895, 21899, 21891, 21939, 21934, 21919, 21822, 21938, 21914, 21947, - 21932, 21937, 21886, 21897, 21931, 21913, 22285, 22575, 22570, 22580, - 22564, {f: 2, c: 22576}, 22561, 22557, 22560, {f: 2, c: 22777}, 22880, - [23159, 57587], 23194, 23167, 23186, 23195, 23207, 23411, 23409, 23506, - 23500, 23507, 23504, {f: 2, c: 23562}, 23601, 23884, 23888, 23860, 23879, - 24061, 24133, 24125, 24128, 24131, 24190, 24266, {f: 2, c: 24257}, 24260, - 24380, 24429, {f: 2, c: 24489}, 24488, 24785, 24801, 24754, 24758, 24800, - 24860, 24867, 24826, 24853, 24816, 24827, 24820, 24936, 24817, 24846, - 24822, 24841, 24832, 24850, 25119, 25161, 25507, 25484, 25551, 25536, - 25577, 25545, 25542, 25549, 25554, 25571, 25552, 25569, 25558, - {f: 2, c: 25581}, 25462, 25588, 25578, 25563, 25682, 25562, 25593, 25950, - 25958, {f: 2, c: 25954}, 26001, 26000, 26031, 26222, 26224, [26228, 57786], - 26230, 26223, 26257, 26234, 26238, 26231, {f: 2, c: 26366}, 26399, 26397, - 26874, 26837, 26848, 26840, 26839, 26885, 26847, 26869, 26862, 26855, - 26873, 26834, 26866, 26851, 26827, 26829, 26893, 26898, 26894, 26825, - 26842, 26990, 26875, 27454, 27450, 27453, 27544, 27542, 27580, 27631, - {f: 2, c: 27694}, 27692, [28207, 57904], 28216, 28244, 28193, 28210, 28263, - 28234, 28192, 28197, 28195, 28187, 28251, 28248, 28196, 28246, 28270, - 28205, 28198, 28271, 28212, 28237, 28218, 28204, 28227, [28189, 57901], - 28222, 28363, 28297, 28185, 28238, 28259, 28228, 28274, 28265, 28255, - {f: 2, c: 28953}, 28966, 28976, 28961, 28982, [29038, 57958], 28956, 29260, - 29316, 29312, 29494, 29477, 29492, 29481, 29754, 29738, 29747, 29730, - 29733, {f: 2, c: 29749}, 29748, 29743, 29723, 29734, 29736, - {f: 2, c: 29989}, 30059, 30058, 30178, 30171, 30179, 30169, 30168, 30174, - 30176, {f: 2, c: 30331}, 30358, 30355, 30388, 30428, 30543, 30701, 30813, - 30828, 30831, 31245, 31240, 31243, 31237, 31232, 31384, 31383, 31382, - 31461, 31459, 31561, 31574, 31558, 31568, 31570, 31572, 31565, 31563, - 31567, [31569, 60510], 31903, 31909, 32094, 32080, 32104, 32085, 32043, - 32110, 32114, 32097, 32102, 32098, 32112, 32115, 21892, {f: 2, c: 32724}, - 32779, 32850, 32901, 33109, 33108, 33099, 33105, 33102, 33081, 33094, - 33086, 33100, 33107, 33140, 33298, 33308, 33769, 33795, 33784, 33805, - 33760, 33733, 33803, [33729, 58309], 33775, 33777, 33780, 33879, 33802, - 33776, 33804, 33740, 33789, 33778, 33738, 33848, 33806, 33796, 33756, - 33799, 33748, 33759, 34395, 34527, 34521, 34541, 34516, 34523, 34532, - 34512, 34526, 34903, {f: 2, c: 35009}, 34993, 35203, 35222, 35387, 35424, - 35413, 35422, 35388, 35393, 35412, 35419, 35408, 35398, 35380, 35386, - 35382, 35414, 35937, 35970, 36015, 36028, 36019, 36029, 36033, 36027, - 36032, 36020, 36023, 36022, 36031, 36024, 36234, 36229, 36225, 36302, - 36317, 36299, 36314, 36305, 36300, 36315, 36294, 36603, 36600, 36604, - 36764, 36910, 36917, 36913, 36920, 36914, 36918, 37122, 37109, 37129, - 37118, 37219, 37221, 37327, {f: 2, c: 37396}, 37411, 37385, 37406, 37389, - 37392, 37383, 37393, 38292, 38287, 38283, 38289, 38291, 38290, 38286, - 38538, 38542, 38539, 38525, {f: 2, c: 38533}, 38541, 38514, 38532, 38593, - 38597, 38596, {f: 2, c: 38598}, 38639, 38642, 38860, {f: 2, c: 38917}, - 38920, 39143, 39146, 39151, 39145, 39154, 39149, 39342, 39341, - [12232, 40643], [12233, 40653], [12234, 40657], 20098, 20653, 20661, - {f: 2, c: 20658}, 20677, 20670, 20652, 20663, 20667, 20655, 20679, 21119, - 21111, 21117, 21215, 21222, 21220, {f: 2, c: 21218}, 21295, 21983, 21992, - 21971, 21990, 21966, 21980, 21959, 21969, {f: 2, c: 21987}, 21999, 21978, - 21985, {f: 2, c: 21957}, 21989, 21961, {f: 2, c: 22290}, 22622, 22609, - 22616, 22615, 22618, 22612, 22635, 22604, 22637, 22602, 22626, 22610, - 22603, 22887, 23233, 23241, 23244, 23230, 23229, 23228, 23219, 23234, - 23218, 23913, 23919, 24140, 24185, 24265, 24264, 24338, 24409, 24492, - 24494, 24858, 24847, 24904, 24863, 24819, 24859, 24825, 24833, 24840, - 24910, 24908, 24900, 24909, 24894, 24884, 24871, 24845, 24838, 24887, - {f: 2, c: 25121}, 25619, 25662, 25630, 25642, 25645, 25661, 25644, 25615, - 25628, 25620, 25613, 25654, {f: 2, c: 25622}, 25606, 25964, 26015, 26032, - 26263, 26249, {f: 2, c: 26247}, 26262, 26244, 26264, 26253, 26371, 27028, - 26989, 26970, 26999, 26976, 26964, 26997, 26928, 27010, 26954, 26984, - 26987, 26974, 26963, 27001, 27014, 26973, 26979, 26971, 27463, 27506, - 27584, 27583, 27603, 27645, 28322, 28335, 28371, 28342, 28354, 28304, - 28317, 28359, 28357, 28325, 28312, 28348, 28346, 28331, 28369, 28310, - 28316, 28356, 28372, 28330, 28327, 28340, 29006, 29017, 29033, 29028, - 29001, 29031, 29020, 29036, 29030, 29004, 29029, 29022, 28998, 29032, - 29014, 29242, 29266, 29495, 29509, 29503, 29502, 29807, 29786, 29781, - 29791, 29790, 29761, 29759, 29785, 29787, [29788, 58019], 30070, 30072, - 30208, 30192, 30209, 30194, 30193, 30202, 30207, 30196, 30195, - {f: 2, c: 30430}, 30555, 30571, 30566, 30558, 30563, 30585, 30570, 30572, - 30556, 30565, 30568, 30562, 30702, 30862, 30896, {f: 2, c: 30871}, 30860, - 30857, 30844, 30865, 30867, 30847, 31098, 31103, 31105, 33836, 31165, - 31260, 31258, 31264, 31252, 31263, 31262, {f: 2, c: 31391}, 31607, 31680, - 31584, 31598, 31591, 31921, 31923, 31925, 32147, 32121, 32145, 32129, - 32143, 32091, 32622, {f: 2, c: 32617}, 32626, 32681, 32680, 32676, 32854, - 32856, 32902, 32900, 33137, 33136, 33144, 33125, 33134, 33139, 33131, - {f: 2, c: 33145}, 33126, 33285, 33351, 33922, 33911, 33853, 33841, 33909, - 33894, 33899, 33865, 33900, 33883, 33852, 33845, 33889, 33891, 33897, - 33901, 33862, 34398, 34396, 34399, 34553, 34579, 34568, 34567, 34560, - 34558, 34555, {f: 2, c: 34562}, 34566, 34570, 34905, 35039, 35028, 35033, - 35036, 35032, 35037, 35041, 35018, 35029, 35026, 35228, 35299, 35435, - {f: 2, c: 35442}, 35430, 35433, 35440, 35463, 35452, 35427, 35488, 35441, - 35461, 35437, 35426, 35438, 35436, 35449, 35451, 35390, 35432, 35938, - 35978, 35977, 36042, {f: 2, c: 36039}, 36036, 36018, 36035, 36034, 36037, - 36321, 36319, 36328, 36335, 36339, 36346, 36330, 36324, 36326, 36530, - 36611, 36617, 36606, 36618, 36767, 36786, 36939, 36938, 36947, 36930, - 36948, 36924, 36949, 36944, 36935, 36943, 36942, 36941, 36945, 36926, - 36929, 37138, 37143, 37228, 37226, 37225, 37321, 37431, 37463, 37432, - 37437, 37440, 37438, 37467, 37451, 37476, 37457, 37428, 37449, 37453, - 37445, 37433, 37439, 37466, 38296, 38552, {f: 2, c: 38548}, 38605, 38603, - {f: 2, c: 38601}, 38647, 38651, 38649, 38646, 38742, 38772, 38774, - {f: 2, c: 38928}, 38931, 38922, 38930, 38924, 39164, 39156, - {f: 2, c: 39165}, 39347, 39345, 39348, 39649, 40169, 40578, [12237, 40718], - [12238, 40723], [12239, 40736], 20711, 20718, 20709, 20694, [20717, 60903], - 20698, 20693, 20687, 20689, 20721, 20686, 20713, 20834, 20979, 21123, - 21122, 21297, 21421, 22014, 22016, 22043, 22039, 22013, 22036, 22022, - 22025, {f: 2, c: 22029}, 22007, 22038, 22047, 22024, 22032, 22006, 22296, - 22294, 22645, 22654, 22659, 22675, 22666, 22649, 22661, 22653, 22781, - 22821, 22818, 22820, 22890, 22889, 23265, 23270, 23273, 23255, 23254, - 23256, 23267, 23413, 23518, 23527, 23521, {f: 2, c: 23525}, 23528, 23522, - 23524, 23519, 23565, 23650, 23940, 23943, 24155, 24163, 24149, 24151, - 24148, 24275, 24278, 24330, 24390, 24432, 24505, 24903, 24895, 24907, - 24951, {f: 2, c: 24930}, 24927, 24922, 24920, 24949, 25130, 25735, 25688, - 25684, 25764, 25720, 25695, 25722, 25681, 25703, 25652, 25709, 25723, - 25970, 26017, 26071, 26070, 26274, 26280, 26269, 27036, 27048, 27029, - 27073, 27054, 27091, 27083, 27035, 27063, 27067, 27051, 27060, 27088, - 27085, 27053, 27084, 27046, 27075, 27043, 27465, 27468, 27699, 28467, - 28436, 28414, 28435, 28404, 28457, 28478, 28448, 28460, 28431, 28418, - 28450, 28415, 28399, 28422, 28465, 28472, 28466, 28451, 28437, 28459, - 28463, 28552, 28458, 28396, 28417, 28402, 28364, 28407, 29076, 29081, - 29053, 29066, 29060, 29074, 29246, 29330, 29334, 29508, 29520, 29796, - 29795, 29802, 29808, 29805, 29956, 30097, 30247, 30221, 30219, 30217, - 30227, 30433, 30435, 30596, 30589, 30591, 30561, 30913, 30879, 30887, - 30899, 30889, 30883, {f: 2, c: 31118}, 31117, 31278, 31281, 31402, 31401, - 31469, 31471, 31649, 31637, 31627, 31605, 31639, 31645, 31636, 31631, - [31672, 58170], 31623, 31620, 31929, {f: 2, c: 31933}, 32187, 32176, 32156, - {f: 2, c: 32189}, 32160, 32202, 32180, 32178, 32177, 32186, 32162, 32191, - 32181, 32184, 32173, [32210, 58202], 32199, 32172, 32624, {f: 2, c: 32736}, - 32735, 32862, 32858, 32903, 33104, 33152, 33167, 33160, 33162, 33151, - 33154, 33255, 33274, 33287, 33300, 33310, 33355, 33993, 33983, 33990, - 33988, 33945, 33950, 33970, 33948, 33995, 33976, 33984, 34003, 33936, - 33980, 34001, 33994, 34623, 34588, 34619, 34594, 34597, 34612, 34584, - 34645, 34615, 34601, 35059, 35074, 35060, 35065, 35064, 35069, 35048, - 35098, 35055, 35494, 35468, 35486, 35491, 35469, 35489, 35475, 35492, - 35498, 35493, 35496, 35480, 35473, 35482, 35495, 35946, 35981, 35980, - 36051, {f: 2, c: 36049}, 36203, 36249, 36245, 36348, 36628, 36626, 36629, - 36627, 36771, 36960, 36952, 36956, 36963, 36953, 36958, 36962, 36957, - 36955, 37145, 37144, 37150, 37237, 37240, 37239, 37236, 37496, 37548, - 37504, 37509, 37528, 37526, 37499, 37523, 37532, 37544, 37500, 37521, - 38305, {f: 2, c: 38312}, 38307, 38309, 38308, 38553, 38556, 38555, 38604, - 38610, 38656, 38780, 38789, 38902, {f: 2, c: 38935}, 39087, 39089, 39171, - 39173, 39180, 39177, 39361, {f: 2, c: 39599}, 39654, {f: 2, c: 39745}, - 40180, 40182, 40179, 40636, [12240, 40763], [12241, 40778], 20740, 20736, - 20731, 20725, 20729, 20738, {f: 2, c: 20744}, 20741, 20956, - {f: 3, c: 21127}, 21133, 21130, 21232, 21426, 22062, 22075, 22073, 22066, - 22079, 22068, 22057, 22099, 22094, 22103, 22132, 22070, {f: 2, c: 22063}, - 22656, 22687, 22686, 22707, 22684, 22702, 22697, 22694, 22893, 23305, - 23291, 23307, 23285, 23308, 23304, 23534, 23532, 23529, 23531, - {f: 2, c: 23652}, 23965, 23956, 24162, 24159, 24161, 24290, 24282, 24287, - 24285, 24291, 24288, 24392, 24433, 24503, 24501, 24950, 24935, 24942, - 24925, 24917, 24962, 24956, 24944, 24939, 24958, 24999, 24976, 25003, - 24974, 25004, 24986, 24996, 24980, 25006, 25134, 25705, 25711, 25721, - 25758, 25778, 25736, [25744, 57745], 25776, 25765, 25747, 25749, 25769, - 25746, 25774, 25773, 25771, 25754, 25772, 25753, 25762, 25779, 25973, - {f: 2, c: 25975}, 26286, 26283, 26292, 26289, 27171, 27167, 27112, 27137, - 27166, 27161, 27133, 27169, 27155, 27146, 27123, 27138, 27141, 27117, - 27153, 27472, 27470, 27556, {f: 2, c: 27589}, 28479, 28540, 28548, 28497, - 28518, 28500, 28550, 28525, 28507, 28536, 28526, 28558, 28538, 28528, - 28516, 28567, 28504, 28373, 28527, 28512, 28511, 29087, 29100, 29105, - 29096, 29270, 29339, 29518, 29527, 29801, 29835, 29827, 29822, 29824, - 30079, 30240, 30249, 30239, 30244, 30246, {f: 2, c: 30241}, 30362, 30394, - 30436, 30606, 30599, 30604, 30609, 30603, 30923, 30917, 30906, 30922, - 30910, 30933, 30908, 30928, 31295, 31292, 31296, 31293, 31287, 31291, - 31407, 31406, 31661, 31665, 31684, 31668, {f: 2, c: 31686}, 31681, 31648, - 31692, 31946, 32224, 32244, 32239, 32251, 32216, 32236, 32221, 32232, - 32227, 32218, 32222, 32233, 32158, 32217, 32242, 32249, 32629, 32631, - 32687, 32745, 32806, {f: 3, c: 33179}, 33184, 33178, 33176, 34071, 34109, - 34074, 34030, {f: 2, c: 34092}, 34067, 34065, 34083, 34081, 34068, 34028, - 34085, 34047, 34054, 34690, 34676, 34678, 34656, 34662, 34680, 34664, - 34649, 34647, 34636, 34643, 34907, 34909, 35088, 35079, {f: 2, c: 35090}, - 35093, 35082, 35516, 35538, 35527, 35524, 35477, 35531, 35576, 35506, - 35529, 35522, 35519, 35504, 35542, 35533, 35510, 35513, 35547, 35916, - 35918, 35948, 36064, 36062, 36070, 36068, {f: 2, c: 36076}, - {f: 2, c: 36066}, 36060, 36074, 36065, 36205, 36255, 36259, 36395, 36368, - 36381, 36386, 36367, 36393, 36383, 36385, 36382, 36538, 36637, 36635, - 36639, 36649, 36646, 36650, 36636, 36638, 36645, 36969, 36974, 36968, - 36973, 36983, 37168, 37165, 37159, 37169, 37255, 37257, 37259, 37251, - 37573, 37563, 37559, 37610, 37604, 37569, 37555, 37564, 37586, 37575, - 37616, 37554, 38317, 38321, 38660, {f: 2, c: 38662}, 38665, 38752, 38797, - 38795, 38799, 38945, 38955, 38940, 39091, 39178, 39187, 39186, 39192, - 39389, 39376, 39391, 39387, 39377, 39381, 39378, 39385, 39607, - {f: 2, c: 39662}, 39719, 39749, 39748, 39799, 39791, 40198, 40201, 40195, - 40617, 40638, 40654, 22696, [12242, 40786], 20754, 20760, 20756, 20752, - 20757, 20864, 20906, 20957, 21137, 21139, 21235, 22105, 22123, 22137, - 22121, 22116, 22136, 22122, 22120, 22117, 22129, 22127, 22124, 22114, - 22134, 22721, 22718, 22727, 22725, 22894, 23325, 23348, 23416, 23536, - 23566, 24394, 25010, 24977, 25001, 24970, 25037, 25014, 25022, 25034, - 25032, 25136, 25797, 25793, 25803, {f: 2, c: 25787}, 25818, 25796, 25799, - 25794, 25805, 25791, 25810, 25812, 25790, 25972, 26310, 26313, 26297, - 26308, 26311, 26296, 27197, 27192, 27194, 27225, 27243, 27224, 27193, - 27204, 27234, 27233, 27211, 27207, 27189, 27231, 27208, 27481, 27511, - 27653, 28610, 28593, 28577, 28611, 28580, 28609, 28583, 28595, 28608, - 28601, [28598, 60318], 28582, 28576, 28596, 29118, 29129, 29136, 29138, - 29128, 29141, 29113, 29134, 29145, 29148, {f: 2, c: 29123}, 29544, 29852, - 29859, 29848, 29855, 29854, 29922, {f: 2, c: 29964}, 30260, 30264, 30266, - 30439, 30437, 30624, {f: 2, c: 30622}, 30629, 30952, 30938, 30956, 30951, - 31142, {f: 2, c: 31309}, 31302, 31308, 31307, 31418, 31705, 31761, 31689, - 31716, 31707, 31713, 31721, 31718, {f: 2, c: 31957}, 32266, 32273, 32264, - 32283, 32291, 32286, [32285, 58211], 32265, 32272, 32633, 32690, - {f: 2, c: 32752}, 32750, [32808, 58239], 33203, 33193, 33192, 33275, 33288, - {f: 2, c: 33368}, 34122, 34137, 34120, {f: 2, c: 34152}, 34115, 34121, - 34157, 34154, 34142, 34691, 34719, 34718, 34722, 34701, 34913, 35114, - 35122, 35109, 35115, 35105, 35242, [35238, 58391], 35558, 35578, 35563, - 35569, 35584, 35548, 35559, 35566, 35582, {f: 2, c: 35585}, 35575, 35565, - 35571, 35574, 35580, 35947, 35949, 35987, 36084, 36420, 36401, 36404, - 36418, 36409, 36405, 36667, 36655, 36664, 36659, 36776, 36774, 36981, - 36980, 36984, 36978, 36988, 36986, 37172, 37266, 37664, 37686, 37624, - 37683, 37679, 37666, 37628, 37675, 37636, 37658, 37648, 37670, 37665, - 37653, 37678, 37657, 38331, {f: 2, c: 38567}, 38570, 38613, 38670, 38673, - 38678, 38669, 38675, 38671, 38747, [38748, 58565], 38758, 38808, 38960, - 38968, 38971, 38967, 38957, 38969, 38948, 39184, 39208, 39198, 39195, - 39201, 39194, 39405, 39394, 39409, 39608, 39612, 39675, 39661, 39720, - 39825, 40213, 40227, 40230, 40232, 40210, 40219, 40664, 40660, - [12243, 40845], [12244, 40860], 20778, 20767, 20769, 20786, 21237, 22158, - 22144, 22160, 22149, 22151, 22159, 22741, 22739, 22737, 22734, 23344, - 23338, 23332, 23418, 23607, 23656, 23996, 23994, 23997, 23992, 24171, - 24396, 24509, 25033, 25026, 25031, 25062, 25035, 25138, 25140, 25806, - 25802, 25816, 25824, 25840, 25830, 25836, 25841, 25826, 25837, - {f: 2, c: 25986}, 26329, 26326, 27264, 27284, 27268, 27298, 27292, 27355, - 27299, 27262, 27287, 27280, 27296, 27484, 27566, 27610, 27656, 28632, - 28657, {f: 2, c: 28639}, 28635, 28644, 28651, 28655, 28544, 28652, 28641, - 28649, 28629, 28654, 28656, 29159, [29151, 60361], 29166, 29158, 29157, - 29165, 29164, 29172, 29152, 29237, 29254, 29552, 29554, 29865, 29872, - 29862, 29864, 30278, 30274, 30284, 30442, 30643, 30634, 30640, 30636, - 30631, 30637, 30703, 30967, 30970, 30964, 30959, 30977, 31143, 31146, - 31319, 31423, 31751, 31757, 31742, 31735, 31756, 31712, 31968, 31964, - 31966, 31970, 31967, 31961, 31965, 32302, 32318, 32326, 32311, 32306, - 32323, 32299, 32317, 32305, 32325, 32321, 32308, 32313, 32328, 32309, - 32319, 32303, 32580, 32755, 32764, {f: 2, c: 32881}, 32880, 32879, 32883, - 33222, 33219, 33210, 33218, 33216, 33215, 33213, 33225, 33214, 33256, - 33289, 33393, 34218, 34180, 34174, 34204, 34193, 34196, 34223, 34203, - 34183, 34216, 34186, 34214, 34407, 34752, 34769, 34739, 34770, 34758, - 34731, 34747, 34746, 34760, 34763, 35131, 35126, 35140, 35128, 35133, - 35244, 35598, 35607, 35609, 35611, 35594, 35616, 35613, 35588, 35600, - 35905, 35903, 35955, 36090, 36093, 36092, 36088, 36091, 36264, 36425, - 36427, 36424, 36426, 36676, 36670, 36674, 36677, 36671, 36991, 36989, - 36996, {f: 2, c: 36993}, 36992, 37177, 37283, 37278, 37276, 37709, 37762, - 37672, 37749, 37706, 37733, 37707, 37656, 37758, 37740, 37723, 37744, - 37722, 37716, {f: 3, c: 38346}, 38344, 38342, 38577, 38584, 38614, 38684, - 38686, 38816, 38867, 38982, 39094, 39221, 39425, 39423, 39854, 39851, - 39850, 39853, 40251, 40255, 40587, 40655, 40670, {f: 2, c: 40668}, 40667, - 40766, 40779, 21474, 22165, 22190, 22745, 22744, 23352, 24413, 25059, - 25139, 25844, 25842, 25854, 25862, {f: 2, c: 25850}, 25847, 26039, 26332, - 26406, 27315, 27308, 27331, 27323, 27320, 27330, {f: 2, c: 27310}, 27487, - 27512, 27567, 28681, 28683, 28670, 28678, 28666, 28689, 28687, - {f: 2, c: 29179}, 29182, 29176, 29559, 29557, 29863, 29887, 29973, 30294, - 30296, 30290, 30653, 30655, {f: 2, c: 30651}, 30990, 31150, - {f: 2, c: 31329}, 31328, {f: 2, c: 31428}, 31787, 31783, 31786, 31774, - 31779, 31777, 31975, {f: 2, c: 32340}, 32350, 32346, 32353, 32338, 32345, - 32584, 32761, 32763, 32887, 32886, 33229, 33231, 33290, 34255, 34217, - 34253, 34256, 34249, 34224, 34234, 34233, 34799, 34796, 34802, 34784, - 35206, 35250, 35316, 35624, 35641, 35628, 35627, 35920, 36101, 36441, - 36451, 36454, 36452, 36447, 36437, 36544, 36681, 36685, 36999, 36995, - 37000, {f: 2, c: 37291}, 37328, 37780, 37770, 37782, 37794, 37811, 37806, - 37804, 37808, 37784, 37786, 37783, 38356, 38358, 38352, 38357, 38626, - 38620, 38617, 38619, 38622, 38692, 38819, 38822, 38829, 38905, 38989, - 38991, 38988, 38990, 38995, 39098, {f: 2, c: 39230}, 39229, 39214, 39333, - 39438, 39617, 39683, 39686, 39759, 39758, 39757, 39882, 39881, 39933, - 39880, 39872, 40273, 40285, 40288, 40672, 40725, 40748, 20787, 22181, - 22184, {f: 2, c: 22750}, 22754, 23541, 40848, 24300, 25074, 25079, 25078, - 25077, 25856, 25871, 26336, 26333, 27365, 27357, 27354, 27347, 28699, - 28703, 28712, 28698, 28701, 28693, 28696, 29190, 29197, 29272, 29346, - 29560, 29562, 29885, 29898, 29923, 30087, 30086, 30303, 30305, 30663, - 31001, 31153, 31339, 31337, {f: 2, c: 31806}, 31800, 31805, 31799, 31808, - 32363, 32365, 32377, {f: 2, c: 32361}, 32371, 32645, 32694, 32697, 32696, - 33240, 34281, 34269, 34282, 34261, {f: 2, c: 34276}, 34295, 34811, 34821, - 34829, 34809, 34814, 35168, 35167, 35158, 35166, 35649, 35676, 35672, - 35657, 35674, {f: 2, c: 35662}, 35654, 35673, 36104, 36106, 36476, 36466, - 36487, 36470, 36460, 36474, 36468, 36692, 36686, 36781, {f: 2, c: 37002}, - 37297, 37294, 37857, 37841, 37855, 37827, 37832, {f: 2, c: 37852}, 37846, - 37858, 37837, 37848, 37860, 37847, 37864, 38364, 38580, 38627, 38698, - 38695, 38753, 38876, 38907, 39006, 39000, 39003, 39100, 39237, 39241, - 39446, 39449, 39693, 39912, 39911, 39894, 39899, 40329, 40289, 40306, - 40298, 40300, 40594, 40599, 40595, 40628, 21240, 22199, 22198, 22196, - 22204, 22756, 23360, 23363, 23421, 23542, 24009, 25080, 25082, 25880, - 25876, 25881, 26342, 26407, 27372, 28734, 28720, 28722, 29200, 29563, - 29903, 30306, 30309, 31014, 31018, 31020, 31019, 31431, 31478, 31820, - 31811, 31821, {f: 2, c: 31983}, 36782, 32381, 32380, 32386, 32588, 32768, - 33242, 33382, 34299, 34297, 34321, 34298, 34310, 34315, 34311, 34314, - {f: 2, c: 34836}, 35172, 35258, 35320, 35696, 35692, 35686, 35695, 35679, - 35691, 36111, 36109, 36489, 36481, 36485, 36482, 37300, 37323, 37912, - 37891, 37885, 38369, 38704, 39108, 39250, 39249, 39336, 39467, 39472, - 39479, 39477, 39955, 39949, 40569, 40629, 40680, 40751, 40799, 40803, - 40801, {f: 2, c: 20791}, 22209, 22208, 22210, 22804, 23660, 24013, 25084, - 25086, 25885, 25884, 26005, 26345, 27387, 27396, 27386, 27570, 28748, - 29211, 29351, 29910, 29908, 30313, 30675, 31824, 32399, 32396, 32700, - 34327, 34349, 34330, 34851, 34850, 34849, 34847, 35178, 35180, 35261, - 35700, 35703, 35709, 36115, 36490, 36493, 36491, 36703, 36783, 37306, - 37934, 37939, 37941, 37946, 37944, 37938, 37931, 38370, {f: 2, c: 38712}, - 38706, [38911, 58586], 39015, 39013, 39255, 39493, 39491, 39488, 39486, - 39631, 39764, 39761, 39981, 39973, 40367, 40372, 40386, 40376, 40605, - 40687, 40729, 40796, {f: 2, c: 40806}, 20796, 20795, 22216, 22218, 22217, - 23423, 24020, 24018, 24398, 25087, 25892, 27402, 27489, 28753, 28760, - 29568, 29924, 30090, 30318, 30316, 31155, 31840, 31839, 32894, 32893, - 33247, 35186, 35183, 35324, 35712, {f: 2, c: 36118}, 36497, 36499, 36705, - 37192, 37956, {f: 2, c: 37969}, {f: 2, c: 38717}, 38851, 38849, 39019, - 39253, 39509, 39501, 39634, 39706, 40009, 39985, 39998, 39995, 40403, - 40407, 40756, 40812, 40810, 40852, 22220, 24022, 25088, 25891, 25899, - 25898, 26348, 27408, 29914, 31434, 31844, 31843, 31845, 32403, 32406, - 32404, 33250, 34360, 34367, 34865, 35722, 37008, 37007, 37987, 37984, - 37988, 38760, 39023, 39260, {f: 2, c: 39514}, 39511, {f: 2, c: 39635}, - 39633, 40020, 40023, 40022, 40421, 40607, 40692, 22225, 22761, 25900, - 28766, {f: 2, c: 30321}, [30679, 60226], 32592, 32648, 34870, 34873, 34914, - 35731, 35730, 35734, 33399, 36123, 37312, 37994, 38722, 38728, 38724, - 38854, 39024, 39519, 39714, 39768, 40031, {f: 2, c: 40441}, - {f: 2, c: 40572}, 40711, 40823, 40818, 24307, 27414, 28771, 31852, 31854, - 34875, 35264, 36513, 37313, 38002, 38000, 39025, 39262, 39638, 39715, - 40652, 28772, 30682, 35738, 38007, 38857, 39522, 39525, 32412, 35740, - 36522, 37317, {f: 2, c: 38013}, 38012, {f: 2, c: 40055}, 40695, 35924, - 38015, 40474, 29224, 39530, 39729, 40475, 40478, 31858, 20034, 20060, - [12048, 20981], [12053, 21274], [12058, 21378], 19975, 19980, 20039, 20109, - [12062, 22231], [12076, 23662], [12091, 24435], 19983, 20871, 19982, 20014, - 20115, 20162, 20169, 20168, 20888, 21244, 21356, 21433, 22304, 22787, - 22828, [23568, 60417], 24063, 26081, [12110, 27571], 27596, [12115, 27668], - [12121, 29247], 20017, 20028, 20200, 20188, 20201, 20193, 20189, 20186, - 21004, 21001, 21276, 21324, {f: 2, c: 22306}, 22807, 22831, 23425, 23428, - 23570, 23611, 23668, 23667, 24068, 24192, 24194, 24521, 25097, 25168, - 27669, 27702, 27715, 27711, 27707, 29358, 29360, 29578, [12145, 31160], - 32906, 38430, 20238, 20248, 20268, 20213, 20244, 20209, 20224, 20215, - 20232, 20253, 20226, 20229, 20258, 20243, 20228, 20212, 20242, 20913, - 21011, 21008, 21158, 21282, 21279, 21325, 21386, 21511, 22241, 22239, - 22318, 22314, 22324, 22844, 22912, 22908, 22917, 22907, 22910, 22903, - 22911, 23382, 23573, 23589, 23676, {f: 2, c: 23674}, 23678, 24031, - [24181, 57646], 24196, 24322, 24346, 24436, 24533, 24532, 24527, 25180, - 25182, 25188, 25185, 25190, 25186, 25177, 25184, 25178, 25189, 25911, - 26095, 26094, 26430, 26425, 26424, 26427, 26426, 26431, 26428, 26419, - 27672, 27718, 27730, 27740, 27727, [27722, 60796], 27732, {f: 2, c: 27723}, - 28785, 29278, {f: 2, c: 29364}, 29582, 29994, 30335, 31349, [12153, 32593], - [12171, 33400], 33404, 33408, 33405, 33407, [12172, 34381], [12177, 35198], - 37017, [37015, 59347], 37016, 37019, 37012, 38434, 38436, 38432, 38435, - 20310, 20283, 20322, 20297, 20307, 20324, 20286, 20327, 20306, 20319, - 20289, 20312, 20269, 20275, 20287, 20321, 20879, 20921, 21020, 21022, - 21025, {f: 2, c: 21165}, 21257, 21347, 21362, {f: 2, c: 21390}, 21552, - 21559, 21546, 21588, 21573, 21529, 21532, 21541, 21528, 21565, 21583, - 21569, 21544, 21540, 21575, 22254, 22247, 22245, 22337, 22341, 22348, - 22345, 22347, 22354, 22790, 22848, 22950, 22936, 22944, 22935, 22926, - 22946, 22928, 22927, 22951, 22945, 23438, 23442, 23592, 23594, 23693, - 23695, 23688, 23691, 23689, 23698, 23690, 23686, 23699, 23701, 24032, - 24074, 24078, 24203, 24201, 24204, 24200, 24205, 24325, 24349, 24440, - 24438, 24530, 24529, 24528, 24557, 24552, 24558, 24563, 24545, 24548, - 24547, 24570, 24559, 24567, 24571, 24576, 24564, 25146, 25219, 25228, - {f: 2, c: 25230}, 25236, 25223, 25201, 25211, 25210, 25200, 25217, 25224, - 25207, 25213, 25202, 25204, 26096, 26100, 26099, 26098, 26101, 26437, - 26439, 26457, 26453, 26444, 26440, 26461, 26445, 26458, 26443, 27600, - {f: 2, c: 27673}, 27768, 27751, 27755, 27780, 27787, 27791, 27761, 27759, - 27753, 27802, 27757, 27783, 27797, [27804, 57900], 27750, 27763, 27749, - 27771, 27790, 28788, 28794, 29283, 29375, 29373, 29379, 29382, 29377, - 29370, 29381, 29589, 29591, {f: 2, c: 29587}, 29586, 30010, 30009, - {f: 2, c: 30100}, 30337, 31037, 32820, 32917, 32921, 32912, 32914, 32924, - 33424, 33423, 33413, 33422, 33425, 33427, 33418, {f: 2, c: 33411}, - [12184, 35960], 36809, 36799, 37023, 37025, 37029, 37022, 37031, 37024, - 38448, 38440, 38447, 38445, 20019, 20376, 20348, 20357, 20349, 20352, - 20359, 20342, 20340, 20361, 20356, 20343, 20300, 20375, 20330, 20378, - 20345, 20353, 20344, 20368, 20380, 20372, 20382, 20370, 20354, 20373, - 20331, 20334, 20894, 20924, 20926, 21045, {f: 2, c: 21042}, 21062, 21041, - 21180, {f: 2, c: 21258}, 21308, 21394, 21396, 21639, 21631, 21633, 21649, - 21634, 21640, 21611, 21626, 21630, 21605, 21612, 21620, 21606, 21645, - 21615, 21601, 21600, 21656, 21603, 21607, 21604, 22263, 22265, 22383, - 22386, 22381, 22379, 22385, 22384, 22390, 22400, 22389, 22395, - {f: 2, c: 22387}, 22370, 22376, 22397, 22796, 22853, 22965, 22970, 22991, - 22990, 22962, 22988, 22977, 22966, 22972, 22979, 22998, 22961, 22973, - 22976, 22984, 22964, 22983, 23394, 23397, 23443, 23445, 23620, 23623, - 23726, 23716, 23712, 23733, 23727, 23720, 23724, 23711, 23715, 23725, - 23714, 23722, 23719, 23709, 23717, 23734, 23728, 23718, 24087, 24084, - 24089, 24360, {f: 3, c: 24354}, 24404, 24450, 24446, 24445, 24542, 24549, - 24621, 24614, 24601, 24626, 24587, 24628, 24586, 24599, 24627, 24602, - 24606, 24620, 24610, 24589, 24592, 24622, 24595, 24593, 24588, 24585, - 24604, 25108, 25149, 25261, 25268, 25297, 25278, 25258, 25270, 25290, - 25262, 25267, 25263, 25275, 25257, 25264, 25272, 25917, 26024, 26043, - 26121, 26108, 26116, 26130, 26120, 26107, 26115, 26123, 26125, 26117, - 26109, 26129, 26128, 26358, 26378, 26501, 26476, 26510, 26514, 26486, - 26491, 26520, 26502, 26500, 26484, 26509, 26508, 26490, 26527, 26513, - 26521, 26499, 26493, 26497, {f: 2, c: 26488}, 26516, 27429, 27520, 27518, - 27614, 27677, 27795, 27884, 27883, 27886, 27865, 27830, 27860, 27821, - 27879, 27831, 27856, 27842, 27834, 27843, 27846, 27885, 27890, 27858, - 27869, 27828, 27786, 27805, 27776, 27870, 27840, 27952, 27853, 27847, - 27824, 27897, 27855, 27881, 27857, 28820, 28824, 28805, 28819, 28806, - 28804, 28817, 28822, 28802, 28826, 28803, 29290, 29398, 29387, 29400, - 29385, 29404, 29394, 29396, 29402, 29388, 29393, 29604, 29601, 29613, - 29606, 29602, 29600, 29612, 29597, 29917, 29928, {f: 2, c: 30015}, 30014, - 30092, 30104, 30383, 30451, 30449, 30448, 30453, 30712, 30716, 30713, - 30715, 30714, 30711, 31042, 31039, 31173, 31352, 31355, 31483, 31861, - 31997, 32821, 32911, 32942, 32931, 32952, 32949, 32941, 33312, 33440, - 33472, 33451, 33434, 33432, 33435, 33461, 33447, 33454, 33468, 33438, - 33466, 33460, 33448, 33441, 33449, 33474, 33444, 33475, 33462, 33442, - 34416, 34415, {f: 2, c: 34413}, 35926, 36818, 36811, 36819, 36813, 36822, - 36821, 36823, 37042, 37044, 37039, 37043, 37040, 38457, 38461, 38460, - 38458, 38467, 20429, 20421, 20435, 20402, 20425, 20427, 20417, 20436, - 20444, 20441, [20411, 60346], 20403, 20443, 20423, 20438, 20410, 20416, - 20409, 20460, 21060, 21065, 21184, 21186, 21309, 21372, 21399, 21398, - 21401, 21400, 21690, 21665, 21677, 21669, 21711, 21699, 33549, 21687, - 21678, 21718, 21686, {f: 2, c: 21701}, 21664, 21616, 21692, 21666, 21694, - 21618, 21726, 21680, 22453, {f: 2, c: 22430}, 22436, 22412, 22423, 22429, - 22427, 22420, 22424, 22415, 22425, 22437, 22426, 22421, 22772, 22797, - 22867, 23009, 23006, 23022, 23040, 23025, 23005, 23034, 23037, 23036, - 23030, 23012, 23026, 23031, 23003, 23017, 23027, 23029, 23008, 23038, - 23028, 23021, 23464, 23628, 23760, 23768, 23756, 23767, 23755, 23771, - 23774, 23770, 23753, 23751, 23754, 23766, {f: 2, c: 23763}, 23759, 23752, - 23750, 23758, 23775, 23800, 24057, {f: 3, c: 24097}, 24096, 24100, 24240, - 24228, 24226, 24219, 24227, 24229, 24327, 24366, 24406, 24454, 24631, - 24633, 24660, 24690, 24670, 24645, 24659, 24647, 24649, 24667, 24652, - 24640, 24642, 24671, 24612, 24644, 24664, 24678, 24686, {f: 2, c: 25154}, - 25295, 25357, 25355, 25333, 25358, 25347, 25323, 25337, 25359, 25356, - 25336, 25334, 25344, {f: 2, c: 25363}, 25338, 25365, 25339, 25328, 25921, - 25923, 26026, 26047, 26166, 26145, 26162, 26165, 26140, 26150, 26146, - 26163, 26155, 26170, 26141, 26164, 26169, 26158, {f: 2, c: 26383}, 26561, - 26610, 26568, 26554, 26588, 26555, 26616, 26584, 26560, 26551, 26565, - 26603, 26596, 26591, 26549, 26573, 26547, 26615, 26614, 26606, 26595, - 26562, 26553, 26574, 26599, 26608, 26546, 26620, 26566, 26605, 26572, - 26542, 26598, 26587, 26618, {f: 2, c: 26569}, 26563, 26602, 26571, 27432, - 27522, 27524, 27574, 27606, 27608, 27616, {f: 2, c: 27680}, 27944, 27956, - 27949, 27935, 27964, 27967, 27922, 27914, 27866, 27955, 27908, 27929, - 27962, 27930, 27921, 27904, 27933, 27970, 27905, 27928, 27959, 27907, - 27919, 27968, 27911, 27936, 27948, 27912, 27938, 27913, 27920, 28855, - 28831, 28862, 28849, 28848, 28833, {f: 2, c: 28852}, 28841, 29249, - {f: 2, c: 29257}, 29292, 29296, 29299, 29294, 29386, 29412, 29416, 29419, - 29407, 29418, 29414, 29411, 29573, 29644, 29634, 29640, 29637, 29625, - 29622, 29621, 29620, 29675, 29631, 29639, 29630, 29635, 29638, 29624, - 29643, 29932, 29934, 29998, {f: 2, c: 30023}, 30119, 30122, 30329, 30404, - 30472, {f: 3, c: 30467}, 30474, 30455, 30459, 30458, {f: 2, c: 30695}, - 30726, {f: 2, c: 30737}, 30725, 30736, 30735, 30734, [30729, 58095], 30723, - 30739, 31050, 31052, 31051, 31045, 31044, 31189, 31181, 31183, 31190, - 31182, 31360, 31358, 31441, {f: 2, c: 31488}, 31866, {f: 2, c: 31864}, - {f: 3, c: 31871}, 32003, 32008, 32001, 32600, 32657, 32653, 32702, 32775, - {f: 2, c: 32782}, 32788, 32823, 32984, 32967, 32992, 32977, 32968, 32962, - 32976, 32965, 32995, 32985, 32988, 32970, 32981, 32969, 32975, 32983, - 32998, 32973, 33279, 33313, 33428, 33497, 33534, 33529, 33543, 33512, - 33536, 33493, 33594, 33515, 33494, 33524, 33516, 33505, 33522, 33525, - 33548, 33531, 33526, 33520, 33514, 33508, 33504, 33530, 33523, 33517, - 34423, 34420, 34428, 34419, 34881, 34894, 34919, 34922, 34921, 35283, - 35332, 35335, 36210, 36835, 36833, 36846, 36832, 37105, 37053, 37055, - 37077, 37061, 37054, 37063, 37067, 37064, [37332, 60294], 37331, 38484, - 38479, 38481, 38483, 38474, 38478, 20510, 20485, 20487, 20499, 20514, - 20528, 20507, 20469, 20468, 20531, 20535, 20524, {f: 2, c: 20470}, 20503, - 20508, 20512, 20519, 20533, 20527, 20529, 20494, 20826, 20884, 20883, - 20938, {f: 2, c: 20932}, 20936, 20942, 21089, 21082, 21074, - {f: 2, c: 21086}, 21077, 21090, 21197, 21262, 21406, 21798, 21730, 21783, - 21778, 21735, 21747, 21732, 21786, 21759, 21764, 21768, 21739, 21777, - 21765, 21745, 21770, 21755, {f: 2, c: 21751}, 21728, 21774, 21763, 21771, - {f: 2, c: 22273}, 22476, 22578, 22485, 22482, 22458, 22470, 22461, 22460, - 22456, 22454, 22463, 22471, 22480, 22457, 22465, 22798, 22858, 23065, - 23062, {f: 2, c: 23085}, 23061, 23055, 23063, 23050, 23070, 23091, 23404, - 23463, 23469, 23468, 23555, 23638, 23636, 23788, 23807, 23790, 23793, - 23799, 23808, 23801, 24105, 24104, 24232, 24238, 24234, 24236, 24371, - 24368, 24423, 24669, 24666, 24679, 24641, 24738, 24712, 24704, 24722, - 24705, 24733, 24707, 24725, 24731, 24727, 24711, 24732, 24718, 25113, - 25158, 25330, 25360, 25430, 25388, {f: 2, c: 25412}, 25398, 25411, 25572, - 25401, 25419, 25418, 25404, 25385, 25409, 25396, 25432, 25428, 25433, - 25389, 25415, 25395, 25434, 25425, 25400, 25431, 25408, 25416, 25930, - 25926, 26054, {f: 2, c: 26051}, 26050, 26186, 26207, 26183, 26193, - {f: 2, c: 26386}, 26655, 26650, 26697, {f: 2, c: 26674}, 26683, 26699, - 26703, 26646, 26673, 26652, 26677, 26667, 26669, 26671, 26702, 26692, - 26676, 26653, 26642, 26644, 26662, 26664, 26670, 26701, 26682, 26661, - 26656, 27436, 27439, 27437, 27441, 27444, 27501, 32898, 27528, 27622, - 27620, 27624, 27619, 27618, 27623, 27685, 28026, {f: 2, c: 28003}, 28022, - 27917, 28001, 28050, 27992, 28002, 28013, 28015, 28049, 28045, 28143, - 28031, 28038, 27998, [28007, 59078], 28000, 28055, 28016, 28028, 27999, - 28034, 28056, 27951, 28008, 28043, 28030, 28032, 28036, 27926, 28035, - 28027, 28029, 28021, 28048, 28892, 28883, 28881, 28893, 28875, 32569, - 28898, 28887, 28882, 28894, 28896, 28884, 28877, {f: 3, c: 28869}, 28890, - 28878, 28897, 29250, 29304, 29303, 29302, 29440, 29434, 29428, 29438, - 29430, 29427, 29435, 29441, 29651, 29657, 29669, 29654, 29628, 29671, - 29667, 29673, 29660, 29650, 29659, 29652, 29661, 29658, {f: 2, c: 29655}, - 29672, {f: 2, c: 29918}, {f: 2, c: 29940}, 29985, 30043, 30047, 30128, - 30145, 30139, 30148, 30144, 30143, 30134, 30138, 30346, 30409, 30493, - 30491, 30480, 30483, 30482, 30499, 30481, 30485, {f: 2, c: 30489}, 30498, - 30503, 30755, 30764, 30754, 30773, 30767, 30760, 30766, 30763, 30753, - 30761, 30771, 30762, 30769, 31060, 31067, 31055, 31068, 31059, 31058, - 31057, {f: 2, c: 31211}, 31200, 31214, 31213, 31210, 31196, 31198, 31197, - 31366, 31369, 31365, {f: 2, c: 31371}, 31370, 31367, 31448, 31504, 31492, - 31507, 31493, 31503, 31496, 31498, 31502, 31497, 31506, 31876, 31889, - 31882, 31884, 31880, 31885, 31877, 32030, 32029, 32017, 32014, 32024, - 32022, 32019, 32031, 32018, 32015, 32012, 32604, 32609, 32606, 32608, - 32605, 32603, 32662, 32658, 32707, 32706, 32704, 32790, 32830, 32825, - 33018, 33010, 33017, 33013, 33025, 33019, 33024, 33281, 33327, 33317, - 33587, 33581, 33604, 33561, 33617, 33573, 33622, 33599, 33601, 33574, - 33564, 33570, 33602, 33614, 33563, 33578, 33544, 33596, 33613, 33558, - 33572, 33568, 33591, 33583, 33577, 33607, 33605, 33612, 33619, 33566, - 33580, 33611, 33575, 33608, 34387, 34386, 34466, 34472, 34454, 34445, - 34449, 34462, 34439, 34455, 34438, 34443, 34458, 34437, 34469, 34457, - 34465, 34471, 34453, 34456, 34446, 34461, 34448, 34452, {f: 2, c: 34883}, - 34925, {f: 2, c: 34933}, 34930, 34944, 34929, 34943, 34927, 34947, 34942, - 34932, 34940, 35346, 35911, 35927, 35963, 36004, 36003, 36214, 36216, - 36277, 36279, 36278, 36561, 36563, 36862, 36853, 36866, 36863, 36859, - 36868, 36860, 36854, 37078, 37088, {f: 2, c: 37081}, 37091, 37087, 37093, - 37080, 37083, 37079, 37084, 37092, 37200, {f: 2, c: 37198}, 37333, 37346, - 37338, 38492, 38495, 38588, 39139, [12221, 39647], [12223, 39727], 20095, - 20592, 20586, 20577, 20574, 20576, 20563, 20555, 20573, 20594, 20552, - 20557, 20545, 20571, 20554, 20578, 20501, 20549, 20575, 20585, 20587, - {f: 2, c: 20579}, 20550, 20544, 20590, 20595, 20567, 20561, 20944, 21099, - 21101, 21100, 21102, 21206, 21203, 21293, 21404, {f: 2, c: 21877}, 21820, - 21837, 21840, 21812, 21802, 21841, 21858, 21814, 21813, 21808, 21842, - 21829, 21772, 21810, 21861, 21838, 21817, 21832, 21805, 21819, 21824, - 21835, 22282, 22279, 22523, 22548, 22498, 22518, 22492, 22516, 22528, - 22509, 22525, 22536, 22520, 22539, 22515, 22479, 22535, 22510, 22499, - 22514, 22501, 22508, 22497, 22542, 22524, 22544, 22503, 22529, 22540, - 22513, 22505, 22512, 22541, 22532, 22876, 23136, 23128, 23125, - [23143, 60437], 23134, 23096, 23093, 23149, 23120, 23135, 23141, 23148, - 23123, 23140, 23127, 23107, 23133, 23122, 23108, 23131, 23112, 23182, - 23102, 23117, 23097, 23116, 23152, 23145, 23111, 23121, 23126, 23106, - 23132, 23410, 23406, 23489, 23488, 23641, 23838, 23819, 23837, 23834, - 23840, 23820, 23848, 23821, 23846, 23845, 23823, 23856, 23826, 23843, - 23839, 23854, 24126, 24116, 24241, 24244, 24249, {f: 2, c: 24242}, 24374, - 24376, 24475, 24470, 24479, 24714, 24720, 24710, 24766, 24752, 24762, - {f: 2, c: 24787}, 24783, 24804, 24793, 24797, 24776, 24753, 24795, 24759, - 24778, 24767, 24771, 24781, 24768, 25394, 25445, 25482, 25474, 25469, - 25533, 25502, 25517, 25501, 25495, 25515, 25486, 25455, 25479, 25488, - 25454, 25519, 25461, 25500, 25453, 25518, 25468, 25508, 25403, 25503, - 25464, 25477, 25473, 25489, 25485, 25456, 25939, 26061, 26213, 26209, - 26203, 26201, 26204, 26210, 26392, 26745, 26759, 26768, 26780, - {f: 2, c: 26733}, 26798, 26795, 26966, 26735, 26787, 26796, 26793, 26741, - 26740, 26802, 26767, 26743, 26770, 26748, 26731, 26738, 26794, 26752, - 26737, 26750, 26779, 26774, 26763, 26784, 26761, 26788, 26744, 26747, - 26769, 26764, 26762, 26749, 27446, 27443, {f: 2, c: 27447}, 27537, 27535, - {f: 2, c: 27533}, 27532, 27690, 28096, 28075, 28084, 28083, 28276, 28076, - 28137, 28130, 28087, 28150, 28116, 28160, 28104, 28128, 28127, 28118, - 28094, 28133, {f: 2, c: 28124}, 28123, 28148, 28106, 28093, 28141, 28144, - 28090, 28117, 28098, 28111, 28105, 28112, 28146, 28115, 28157, 28119, - 28109, 28131, 28091, 28922, 28941, 28919, 28951, 28916, 28940, 28912, - 28932, 28915, 28944, 28924, 28927, 28934, 28947, 28928, 28920, 28918, - 28939, 28930, 28942, 29310, {f: 2, c: 29307}, 29311, 29469, 29463, 29447, - 29457, 29464, 29450, 29448, 29439, 29455, 29470, 29576, 29686, 29688, - 29685, 29700, 29697, 29693, 29703, 29696, 29690, 29692, 29695, 29708, - 29707, 29684, 29704, 30052, 30051, 30158, 30162, 30159, {f: 2, c: 30155}, - 30161, 30160, 30351, 30345, 30419, 30521, 30511, 30509, {f: 2, c: 30513}, - 30516, 30515, 30525, 30501, 30523, 30517, 30792, 30802, 30793, 30797, - 30794, 30796, 30758, 30789, 30800, 31076, 31079, {f: 2, c: 31081}, 31075, - 31083, 31073, 31163, 31226, 31224, {f: 2, c: 31222}, 31375, 31380, 31376, - 31541, 31547, 31540, 31525, 31536, 31522, 31524, 31539, 31512, 31530, - 31517, 31537, 31531, 31533, 31535, 31538, 31544, 31514, 31523, 31892, - 31896, 31894, 31907, 32053, 32061, 32056, 32054, 32058, 32069, 32044, - 32041, 32065, 32071, {f: 2, c: 32062}, 32074, 32059, 32040, 32611, 32661, - {f: 2, c: 32668}, 32667, {f: 2, c: 32714}, 32717, {f: 2, c: 32720}, 32711, - 32719, 32713, 32799, 32798, 32795, 32839, 32835, 32840, 33048, 33061, - 33049, 33051, 33069, 33055, 33068, 33054, 33057, 33045, 33063, 33053, - 33058, 33297, 33336, 33331, 33338, 33332, 33330, 33396, 33680, 33699, - 33704, 33677, 33658, 33651, 33700, 33652, 33679, 33665, 33685, 33689, - 33653, 33684, 33705, 33661, 33667, 33676, 33693, 33691, 33706, 33675, - 33662, 33701, 33711, 33672, 33687, 33712, 33663, 33702, 33671, 33710, - 33654, 34393, 34390, 34495, 34487, 34498, 34497, 34501, 34490, 34480, - 34504, 34489, 34483, 34488, 34508, 34484, {f: 2, c: 34491}, 34499, - {f: 2, c: 34493}, 34898, 34953, 34965, 34984, 34978, 34986, 34970, 34961, - 34977, 34975, 34968, 34983, 34969, 34971, 34967, 34980, 34988, 34956, - 34963, 34958, 35202, 35286, 35289, 35285, 35376, 35367, 35372, 35358, - 35897, 35899, {f: 2, c: 35932}, 35965, 36005, 36221, 36219, 36217, 36284, - 36290, 36281, 36287, 36289, 36568, 36574, 36573, 36572, 36567, - {f: 2, c: 36576}, 36900, 36875, 36881, 36892, 36876, 36897, 37103, 37098, - 37104, 37108, {f: 2, c: 37106}, 37076, {f: 2, c: 37099}, 37097, 37206, - 37208, 37210, 37203, 37205, 37356, 37364, 37361, 37363, 37368, 37348, - 37369, {f: 2, c: 37354}, 37367, 37352, 37358, 38266, 38278, 38280, 38524, - 38509, 38507, 38513, 38511, 38591, 38762, 38916, 39141, 39319, 20635, - 20629, 20628, 20638, 20619, 20643, 20611, 20620, 20622, 20637, 20584, - 20636, 20626, 20610, 20615, 20831, 20948, 21266, 21265, 21412, 21415, - 21905, 21928, 21925, 21933, 21879, 22085, 21922, 21907, 21896, 21903, - 21941, 21889, 21923, 21906, 21924, 21885, 21900, 21926, 21887, 21909, - 21921, 21902, 22284, 22569, 22583, 22553, 22558, 22567, 22563, 22568, - 22517, 22600, 22565, 22556, 22555, 22579, 22591, 22582, 22574, 22585, - 22584, 22573, 22572, 22587, 22881, 23215, 23188, 23199, 23162, 23202, - 23198, 23160, 23206, 23164, 23205, 23212, 23189, 23214, 23095, 23172, - 23178, 23191, 23171, 23179, 23209, 23163, 23165, 23180, 23196, 23183, - 23187, 23197, 23530, 23501, 23499, 23508, 23505, 23498, 23502, 23564, - 23600, 23863, 23875, 23915, 23873, 23883, 23871, 23861, 23889, 23886, - 23893, 23859, 23866, 23890, 23869, 23857, 23897, 23874, 23865, 23881, - 23864, 23868, 23858, 23862, 23872, 23877, 24132, 24129, [24408, 57673], - 24486, 24485, 24491, 24777, 24761, 24780, 24802, 24782, 24772, 24852, - 24818, 24842, 24854, 24837, 24821, 24851, 24824, 24828, 24830, 24769, - 24835, 24856, 24861, 24848, 24831, 24836, 24843, 25162, 25492, 25521, - 25520, 25550, 25573, 25576, 25583, 25539, 25757, 25587, 25546, 25568, - 25590, 25557, 25586, 25589, 25697, 25567, 25534, 25565, 25564, 25540, - 25560, 25555, 25538, 25543, 25548, 25547, 25544, 25584, 25559, 25561, - 25906, 25959, 25962, 25956, 25948, 25960, 25957, 25996, {f: 2, c: 26013}, - 26030, 26064, 26066, 26236, 26220, 26235, 26240, 26225, 26233, 26218, - 26226, 26369, 26892, 26835, 26884, 26844, 26922, 26860, 26858, 26865, - 26895, 26838, 26871, 26859, 26852, 26870, 26899, 26896, 26867, 26849, - 26887, 26828, 26888, 26992, 26804, 26897, 26863, 26822, 26900, 26872, - 26832, 26877, 26876, 26856, 26891, 26890, 26903, 26830, 26824, - {f: 2, c: 26845}, 26854, 26868, 26833, 26886, 26836, 26857, 26901, 26917, - 26823, 27449, 27451, 27455, 27452, 27540, 27543, 27545, 27541, 27581, - 27632, {f: 2, c: 27634}, 27696, 28156, {f: 2, c: 28230}, 28191, 28233, - 28296, {f: 2, c: 28220}, 28229, 28258, 28203, 28223, 28225, 28253, 28275, - 28188, 28211, 28235, 28224, 28241, 28219, 28163, 28206, 28254, 28264, - 28252, 28257, 28209, 28200, 28256, 28273, 28267, 28217, 28194, 28208, - 28243, 28261, 28199, 28280, 28260, 28279, 28245, 28281, 28242, 28262, - {f: 2, c: 28213}, 28250, 28960, 28958, 28975, 28923, 28974, 28977, 28963, - 28965, 28962, 28978, 28959, 28968, 28986, 28955, 29259, 29274, - {f: 2, c: 29320}, 29318, 29317, 29323, 29458, 29451, 29488, 29474, 29489, - 29491, 29479, 29490, 29485, 29478, 29475, 29493, 29452, 29742, 29740, - 29744, 29739, 29718, 29722, 29729, 29741, 29745, 29732, 29731, 29725, - 29737, 29728, 29746, 29947, 29999, 30063, 30060, 30183, 30170, 30177, - 30182, 30173, 30175, 30180, 30167, 30357, 30354, 30426, {f: 2, c: 30534}, - 30532, 30541, 30533, 30538, 30542, {f: 2, c: 30539}, 30686, 30700, 30816, - {f: 2, c: 30820}, 30812, 30829, 30833, 30826, 30830, 30832, 30825, 30824, - 30814, 30818, 31092, 31091, 31090, 31088, 31234, 31242, 31235, 31244, - 31236, 31385, 31462, 31460, 31562, 31559, 31556, 31560, 31564, 31566, - 31552, 31576, 31557, 31906, 31902, 31912, 31905, 32088, 32111, 32099, - 32083, 32086, 32103, 32106, 32079, 32109, 32092, 32107, 32082, 32084, - 32105, 32081, 32095, 32078, {f: 2, c: 32574}, {f: 2, c: 32613}, 32674, - {f: 2, c: 32672}, 32727, 32849, {f: 2, c: 32847}, 33022, 32980, 33091, - 33098, 33106, 33103, 33095, 33085, 33101, 33082, 33254, 33262, - {f: 3, c: 33271}, 33284, {f: 2, c: 33340}, 33343, 33397, 33595, - [33743, 60382], 33785, 33827, 33728, 33768, 33810, 33767, 33764, 33788, - 33782, 33808, 33734, 33736, 33771, 33763, 33727, 33793, 33757, 33765, - 33752, 33791, 33761, 33739, 33742, 33750, 33781, 33737, 33801, - [33807, 58332], 33758, 33809, 33798, 33730, 33779, 33749, 33786, 33735, - 33745, 33770, 33811, 33690, 33731, 33772, 33774, 33732, 33787, 33751, - 33762, 33819, 33755, 33790, 34520, 34530, 34534, 34515, 34531, 34522, - 34538, 34525, 34539, 34524, 34540, 34537, 34519, 34536, 34513, 34888, - 34902, 34901, 35002, 35031, 35001, 35000, 35008, 35006, 34998, 35004, - 34999, 35005, 34994, 35073, 35017, 35221, 35224, 35223, 35293, - {f: 2, c: 35290}, 35406, 35405, 35385, 35417, 35392, {f: 2, c: 35415}, - {f: 2, c: 35396}, 35410, 35400, 35409, 35402, 35404, 35407, 35935, 35969, - 35968, 36026, 36030, 36016, 36025, 36021, 36228, 36224, 36233, 36312, - 36307, 36301, 36295, 36310, 36316, 36303, 36309, 36313, 36296, 36311, - 36293, 36591, 36599, 36602, 36601, 36582, 36590, 36581, 36597, - {f: 2, c: 36583}, 36598, 36587, 36593, 36588, 36596, 36585, 36909, 36916, - 36911, 37126, 37164, [37124, 60367], 37119, 37116, 37128, 37113, 37115, - 37121, 37120, 37127, 37125, 37123, 37217, 37220, 37215, 37218, 37216, - 37377, 37386, 37413, 37379, 37402, 37414, 37391, 37388, 37376, 37394, - 37375, 37373, 37382, 37380, 37415, 37378, 37404, 37412, 37401, 37399, - 37381, 37398, 38267, 38285, 38284, 38288, 38535, 38526, {f: 2, c: 38536}, - 38531, 38528, 38594, 38600, 38595, 38641, 38640, 38764, 38768, 38766, - 38919, 39081, 39147, 40166, [12235, 40697], {f: 2, c: 20099}, 20150, 20669, - 20671, 20678, 20654, 20676, 20682, 20660, 20680, 20674, 20656, 20673, - 20666, 20657, 20683, 20681, 20662, 20664, 20951, 21114, 21112, - {f: 2, c: 21115}, 21955, 21979, 21964, 21968, 21963, 21962, 21981, - [21952, 64013], 21972, 21956, 21993, 21951, 21970, 21901, 21967, 21973, - 21986, 21974, 21960, 22002, 21965, 21977, 21954, 22292, 22611, 22632, - 22628, 22607, 22605, 22601, 22639, 22613, 22606, 22621, 22617, 22629, - 22619, 22589, 22627, 22641, 22780, 23239, 23236, 23243, 23226, 23224, - 23217, 23221, 23216, 23231, 23240, 23227, 23238, 23223, 23232, 23242, - 23220, 23222, 23245, 23225, 23184, 23510, {f: 2, c: 23512}, 23583, 23603, - 23921, 23907, 23882, 23909, 23922, 23916, 23902, 23912, 23911, 23906, - 24048, 24143, 24142, 24138, 24141, 24139, 24261, 24268, 24262, 24267, - 24263, 24384, 24495, 24493, 24823, {f: 2, c: 24905}, 24875, 24901, 24886, - 24882, 24878, 24902, 24879, 24911, 24873, 24896, 25120, 37224, 25123, - 25125, 25124, 25541, 25585, 25579, 25616, 25618, 25609, 25632, 25636, - 25651, 25667, 25631, 25621, 25624, 25657, 25655, {f: 2, c: 25634}, 25612, - 25638, 25648, 25640, 25665, 25653, 25647, 25610, 25626, 25664, 25637, - 25639, 25611, 25575, 25627, 25646, 25633, 25614, 25967, 26002, 26067, - 26246, 26252, 26261, 26256, 26251, 26250, 26265, 26260, 26232, 26400, - 26982, 26975, 26936, 26958, 26978, 26993, 26943, 26949, 26986, 26937, - 26946, 26967, 26969, 27002, {f: 2, c: 26952}, 26933, 26988, 26931, 26941, - 26981, 26864, 27000, 26932, 26985, 26944, 26991, 26948, 26998, 26968, - 26945, 26996, 26956, 26939, 26955, 26935, 26972, 26959, 26961, 26930, - 26962, 26927, 27003, 26940, 27462, 27461, 27459, 27458, 27464, 27457, - 27547, {f: 2, c: 27643}, 27641, {f: 2, c: 27639}, 28315, 28374, 28360, - 28303, 28352, 28319, {f: 2, c: 28307}, 28320, 28337, 28345, 28358, 28370, - 28349, 28353, 28318, 28361, 28343, 28336, 28365, 28326, 28367, 28338, - 28350, 28355, 28380, 28376, 28313, 28306, 28302, 28301, 28324, 28321, - 28351, 28339, 28368, 28362, 28311, 28334, 28323, 28999, 29012, 29010, - 29027, 29024, 28993, 29021, [29026, 61080], 29042, 29048, 29034, 29025, - 28994, 29016, 28995, 29003, 29040, 29023, 29008, 29011, 28996, 29005, - 29018, 29263, 29325, 29324, 29329, 29328, 29326, 29500, 29506, 29499, - 29498, 29504, 29514, 29513, 29764, {f: 2, c: 29770}, 29778, 29777, 29783, - 29760, {f: 2, c: 29775}, 29774, 29762, 29766, 29773, 29780, 29921, 29951, - 29950, 29949, 29981, 30073, 30071, 27011, 30191, 30223, 30211, 30199, - 30206, 30204, [30201, 60782], 30200, 30224, 30203, 30198, 30189, 30197, - 30205, 30361, 30389, 30429, 30549, {f: 2, c: 30559}, 30546, 30550, 30554, - 30569, 30567, 30548, 30553, 30573, 30688, 30855, 30874, 30868, 30863, - 30852, 30869, {f: 2, c: 30853}, 30881, 30851, 30841, 30873, 30848, 30870, - 30843, 31100, 31106, 31101, 31097, 31249, {f: 2, c: 31256}, 31250, 31255, - 31253, 31266, 31251, 31259, 31248, 31395, 31394, 31390, 31467, 31590, - 31588, 31597, 31604, 31593, 31602, 31589, 31603, 31601, 31600, 31585, - 31608, 31606, 31587, 31922, 31924, 31919, 32136, 32134, 32128, 32141, - 32127, 32133, 32122, 32142, 32123, 32131, 32124, 32140, 32148, 32132, - 32125, 32146, 32621, 32619, {f: 2, c: 32615}, 32620, 32678, 32677, 32679, - {f: 2, c: 32731}, 32801, 33124, 33120, 33143, 33116, 33129, 33115, 33122, - 33138, 26401, 33118, 33142, 33127, 33135, 33092, 33121, 33309, 33353, - 33348, 33344, 33346, 33349, 34033, 33855, 33878, 33910, 33913, 33935, - 33933, 33893, 33873, 33856, 33926, 33895, 33840, 33869, 33917, 33882, - 33881, 33908, 33907, 33885, 34055, 33886, 33847, 33850, 33844, 33914, - 33859, 33912, 33842, 33861, 33833, 33753, 33867, 33839, 33858, 33837, - 33887, 33904, 33849, 33870, 33868, 33874, 33903, 33989, 33934, 33851, - 33863, 33846, 33843, 33896, 33918, 33860, 33835, 33888, 33876, 33902, - 33872, 34571, 34564, 34551, 34572, 34554, 34518, 34549, 34637, 34552, - 34574, 34569, 34561, 34550, 34573, 34565, 35030, 35019, {f: 2, c: 35021}, - 35038, 35035, 35034, 35020, 35024, 35205, 35227, 35295, 35301, 35300, - 35297, 35296, 35298, 35292, 35302, 35446, 35462, 35455, 35425, 35391, - 35447, 35458, 35460, 35445, 35459, 35457, 35444, 35450, 35900, 35915, - 35914, 35941, 35940, 35942, 35974, {f: 2, c: 35972}, 36044, - {f: 2, c: 36200}, 36241, 36236, {f: 2, c: 36238}, 36237, {f: 2, c: 36243}, - 36240, 36242, 36336, 36320, 36332, 36337, 36334, 36304, 36329, 36323, - 36322, 36327, 36338, 36331, 36340, 36614, 36607, 36609, 36608, 36613, - {f: 2, c: 36615}, 36610, [36619, 60507], 36946, 36927, 36932, 36937, 36925, - 37136, 37133, 37135, 37137, 37142, 37140, 37131, 37134, {f: 2, c: 37230}, - 37448, 37458, 37424, 37434, 37478, 37427, 37477, 37470, 37507, 37422, - 37450, 37446, 37485, 37484, 37455, 37472, 37479, 37487, 37430, 37473, - 37488, 37425, 37460, 37475, 37456, 37490, 37454, 37459, 37452, 37462, - 37426, 38303, 38300, 38302, 38299, {f: 2, c: 38546}, 38545, 38551, 38606, - 38650, 38653, 38648, 38645, 38771, {f: 2, c: 38775}, 38770, 38927, - {f: 2, c: 38925}, 39084, 39158, 39161, 39343, 39346, 39344, 39349, 39597, - 39595, 39771, 40170, 40173, 40167, 40576, [12236, 40701], 20710, 20692, - 20695, 20712, 20723, 20699, 20714, 20701, 20708, 20691, 20716, 20720, - 20719, 20707, 20704, 20952, {f: 2, c: 21120}, 21225, 21227, 21296, 21420, - 22055, 22037, 22028, 22034, 22012, 22031, 22044, 22017, 22035, 22018, - 22010, 22045, 22020, 22015, 22009, 22665, 22652, 22672, 22680, 22662, - 22657, 22655, 22644, 22667, 22650, 22663, 22673, 22670, 22646, 22658, - 22664, 22651, 22676, 22671, 22782, 22891, 23260, 23278, 23269, 23253, - 23274, 23258, 23277, 23275, 23283, 23266, 23264, 23259, 23276, 23262, - 23261, 23257, 23272, 23263, 23415, 23520, 23523, 23651, 23938, 23936, - 23933, 23942, 23930, 23937, 23927, 23946, 23945, 23944, 23934, 23932, - 23949, 23929, 23935, {f: 2, c: 24152}, 24147, 24280, 24273, 24279, 24270, - 24284, 24277, 24281, 24274, 24276, 24388, 24387, 24431, 24502, 24876, - 24872, 24897, 24926, 24945, 24947, {f: 2, c: 24914}, 24946, 24940, 24960, - 24948, 24916, 24954, 24923, 24933, 24891, 24938, 24929, 24918, 25129, - 25127, 25131, 25643, 25677, 25691, 25693, 25716, 25718, {f: 2, c: 25714}, - 25725, 25717, 25702, 25766, 25678, 25730, 25694, 25692, 25675, 25683, - 25696, 25680, 25727, 25663, 25708, 25707, 25689, 25701, 25719, 25971, - 26016, 26273, 26272, 26271, 26373, 26372, 26402, 27057, 27062, 27081, - 27040, 27086, 27030, 27056, 27052, 27068, 27025, 27033, 27022, 27047, - 27021, 27049, 27070, 27055, 27071, 27076, 27069, 27044, 27092, 27065, - 27082, 27034, 27087, 27059, 27027, 27050, 27041, 27038, 27097, 27031, - 27024, 27074, 27061, 27045, 27078, 27466, 27469, 27467, {f: 3, c: 27550}, - {f: 2, c: 27587}, 27646, 28366, 28405, 28401, 28419, 28453, 28408, 28471, - 28411, 28462, 28425, 28494, {f: 2, c: 28441}, 28455, 28440, 28475, 28434, - 28397, 28426, 28470, 28531, 28409, 28398, 28461, 28480, 28464, 28476, - 28469, 28395, 28423, 28430, 28483, 28421, 28413, 28406, 28473, 28444, - 28412, 28474, 28447, 28429, 28446, 28424, 28449, 29063, 29072, 29065, - 29056, 29061, 29058, 29071, 29051, 29062, 29057, 29079, 29252, 29267, - 29335, 29333, 29331, 29507, 29517, 29521, 29516, 29794, 29811, 29809, - 29813, 29810, 29799, 29806, 29952, {f: 2, c: 29954}, 30077, 30096, 30230, - 30216, 30220, 30229, 30225, 30218, 30228, 30392, 30593, 30588, 30597, - 30594, 30574, 30592, 30575, 30590, 30595, 30898, 30890, 30900, 30893, - 30888, 30846, 30891, 30878, 30885, 30880, 30892, 30882, 30884, 31128, - {f: 2, c: 31114}, 31126, 31125, 31124, 31123, 31127, 31112, 31122, 31120, - 31275, 31306, 31280, 31279, 31272, 31270, 31400, {f: 2, c: 31403}, 31470, - 31624, 31644, 31626, 31633, 31632, 31638, 31629, 31628, 31643, 31630, - 31621, 31640, 21124, 31641, 31652, 31618, 31931, 31935, 31932, 31930, - 32167, 32183, 32194, 32163, 32170, 32193, 32192, 32197, 32157, 32206, - 32196, 32198, {f: 2, c: 32203}, 32175, 32185, 32150, 32188, 32159, 32166, - 32174, 32169, 32161, 32201, 32627, {f: 2, c: 32738}, 32741, 32734, 32804, - 32861, 32860, 33161, 33158, 33155, 33159, 33165, 33164, 33163, 33301, - 33943, 33956, 33953, 33951, 33978, 33998, 33986, 33964, 33966, 33963, - 33977, 33972, 33985, 33997, 33962, 33946, 33969, 34000, 33949, 33959, - 33979, 33954, 33940, 33991, 33996, 33947, 33961, 33967, [33960, 58327], - 34006, 33944, 33974, 33999, 33952, 34007, 34004, 34002, 34011, 33968, - 33937, 34401, 34611, 34595, 34600, 34667, 34624, 34606, 34590, 34593, - 34585, 34587, 34627, 34604, 34625, 34622, 34630, 34592, 34610, 34602, - 34605, 34620, 34578, 34618, 34609, 34613, 34626, {f: 2, c: 34598}, 34616, - 34596, 34586, 34608, 34577, 35063, 35047, {f: 2, c: 35057}, 35066, 35070, - 35054, 35068, 35062, 35067, 35056, 35052, 35051, 35229, 35233, 35231, - 35230, 35305, 35307, 35304, 35499, 35481, 35467, 35474, 35471, 35478, - 35901, {f: 2, c: 35944}, 36053, 36047, 36055, 36246, 36361, 36354, 36351, - 36365, 36349, 36362, 36355, 36359, 36358, 36357, 36350, 36352, 36356, - {f: 2, c: 36624}, 36622, 36621, 37155, 37148, 37152, 37154, 37151, 37149, - 37146, 37156, 37153, 37147, 37242, 37234, 37241, 37235, 37541, 37540, - 37494, 37531, 37498, 37536, 37524, 37546, 37517, 37542, 37530, 37547, - 37497, 37527, 37503, 37539, 37614, 37518, 37506, 37525, 37538, 37501, - 37512, 37537, 37514, 37510, 37516, 37529, 37543, 37502, 37511, 37545, - 37533, 37515, 37421, 38558, 38561, 38655, 38744, 38781, 38778, 38782, - 38787, 38784, 38786, 38779, 38788, 38785, 38783, 38862, 38861, 38934, - {f: 2, c: 39085}, 39170, 39168, 39175, 39325, 39324, 39363, 39353, 39355, - 39354, 39362, 39357, 39367, 39601, 39651, 39655, {f: 2, c: 39742}, - {f: 2, c: 39776}, 39775, {f: 2, c: 40177}, 40181, 40615, 20735, 20739, - 20784, 20728, {f: 2, c: 20742}, 20726, 20734, {f: 2, c: 20747}, 20733, - 20746, {f: 2, c: 21131}, 21233, 21231, 22088, 22082, 22092, 22069, 22081, - 22090, 22089, 22086, 22104, 22106, 22080, 22067, 22077, 22060, 22078, - 22072, 22058, 22074, 22298, 22699, 22685, 22705, 22688, 22691, 22703, - 22700, 22693, 22689, 22783, 23295, 23284, 23293, 23287, 23286, 23299, - 23288, 23298, 23289, 23297, 23303, 23301, 23311, 23655, 23961, 23959, - 23967, 23954, 23970, 23955, 23957, 23968, 23964, 23969, 23962, 23966, - 24169, 24157, 24160, 24156, 32243, 24283, 24286, 24289, 24393, 24498, - 24971, 24963, 24953, 25009, 25008, 24994, 24969, 24987, 24979, 25007, - 25005, 24991, 24978, 25002, 24993, 24973, 24934, 25011, 25133, 25710, - 25712, 25750, 25760, 25733, 25751, 25756, 25743, 25739, 25738, 25740, - 25763, 25759, 25704, 25777, 25752, 25974, 25978, 25977, 25979, - {f: 2, c: 26034}, 26293, 26288, 26281, 26290, 26295, 26282, 26287, 27136, - 27142, 27159, 27109, 27128, 27157, 27121, 27108, 27168, 27135, 27116, - 27106, 27163, 27165, 27134, 27175, 27122, 27118, 27156, 27127, 27111, - 27200, 27144, 27110, 27131, 27149, 27132, 27115, 27145, 27140, 27160, - 27173, 27151, 27126, 27174, 27143, 27124, 27158, 27473, 27557, 27555, - 27554, 27558, 27649, 27648, 27647, 27650, 28481, 28454, 28542, 28551, - 28614, 28562, 28557, 28553, 28556, 28514, 28495, 28549, 28506, 28566, - 28534, 28524, 28546, 28501, 28530, 28498, 28496, 28503, 28564, 28563, - 28509, 28416, 28513, 28523, 28541, 28519, 28560, 28499, 28555, 28521, - 28543, 28565, 28515, 28535, 28522, 28539, 29106, 29103, 29083, 29104, - 29088, 29082, 29097, 29109, 29085, 29093, 29086, 29092, 29089, 29098, - 29084, 29095, 29107, 29336, 29338, 29528, 29522, {f: 3, c: 29534}, 29533, - 29531, 29537, 29530, 29529, 29538, 29831, {f: 2, c: 29833}, 29830, 29825, - 29821, 29829, 29832, 29820, [29817, 58868], 29960, 29959, 30078, 30245, - 30238, 30233, 30237, 30236, 30243, 30234, 30248, 30235, {f: 3, c: 30364}, - 30363, 30605, 30607, 30601, 30600, 30925, 30907, 30927, 30924, 30929, - 30926, 30932, 30920, {f: 2, c: 30915}, 30921, 31130, 31137, 31136, 31132, - 31138, [31131, 59175], 27510, 31289, 31410, 31412, 31411, 31671, 31691, - 31678, 31660, 31694, 31663, 31673, 31690, 31669, 31941, 31944, 31948, - 31947, 32247, 32219, 32234, 32231, 32215, 32225, 32259, 32250, 32230, - 32246, 32241, 32240, 32238, 32223, 32630, 32684, 32688, 32685, 32749, - 32747, 32746, 32748, 32742, 32744, 32868, 32871, 33187, 33183, 33182, - 33173, 33186, 33177, 33175, 33302, 33359, 33363, 33362, 33360, 33358, - 33361, 34084, 34107, 34063, 34048, 34089, 34062, 34057, 34061, 34079, - 34058, 34087, 34076, 34043, 34091, 34042, 34056, 34060, 34036, 34090, - 34034, 34069, 34039, 34027, 34035, 34044, 34066, 34026, 34025, 34070, - 34046, 34088, 34077, 34094, 34050, 34045, 34078, 34038, 34097, 34086, - {f: 2, c: 34023}, 34032, 34031, 34041, 34072, 34080, 34096, 34059, 34073, - 34095, 34402, 34646, {f: 2, c: 34659}, 34679, 34785, 34675, 34648, 34644, - 34651, 34642, 34657, 34650, 34641, 34654, 34669, 34666, 34640, 34638, - 34655, 34653, 34671, 34668, 34682, 34670, 34652, 34661, 34639, 34683, - 34677, 34658, 34663, 34665, 34906, 35077, 35084, 35092, 35083, - {f: 3, c: 35095}, 35078, 35094, 35089, 35086, 35081, 35234, 35236, 35235, - 35309, 35312, 35308, 35535, 35526, 35512, 35539, 35537, {f: 2, c: 35540}, - 35515, 35543, 35518, 35520, 35525, 35544, 35523, 35514, 35517, 35545, - 35902, 35917, 35983, 36069, 36063, 36057, 36072, 36058, 36061, 36071, - 36256, 36252, 36257, 36251, 36384, 36387, 36389, 36388, 36398, 36373, - 36379, 36374, 36369, 36377, {f: 2, c: 36390}, 36372, 36370, 36376, 36371, - 36380, 36375, 36378, 36652, 36644, 36632, 36634, 36640, 36643, - {f: 2, c: 36630}, 36979, 36976, 36975, 36967, 36971, 37167, 37163, - {f: 2, c: 37161}, 37170, 37158, 37166, {f: 2, c: 37253}, 37258, - {f: 2, c: 37249}, 37252, 37248, 37584, {f: 2, c: 37571}, 37568, 37593, - 37558, 37583, 37617, 37599, 37592, 37609, 37591, 37597, 37580, 37615, - 37570, 37608, 37578, 37576, 37582, 37606, 37581, 37589, 37577, 37600, - 37598, 37607, 37585, 37587, 37557, 37601, 37669, 37574, 37556, 38268, - 38316, 38315, 38318, 38320, 38564, 38562, 38611, 38661, 38664, 38658, - 38746, 38794, 38798, 38792, 38864, 38863, 38942, 38941, 38950, 38953, - 38952, 38944, 38939, 38951, 39090, 39176, 39162, 39185, 39188, - {f: 2, c: 39190}, 39189, 39388, 39373, 39375, {f: 2, c: 39379}, 39374, - 39369, [39382, 60270], 39384, 39371, 39383, 39372, 39603, 39660, 39659, - 39667, 39666, 39665, 39750, 39747, 39783, 39796, 39793, 39782, 39798, - 39797, 39792, 39784, 39780, 39788, 40188, 40186, 40189, 40191, 40183, - 40199, 40192, 40185, 40187, 40200, 40197, 40196, 40579, 40659, - {f: 2, c: 40719}, 20764, 20755, 20759, 20762, 20753, 20958, 21300, 21473, - 22128, 22112, 22126, 22131, 22118, 22115, 22125, 22130, 22110, 22135, - 22300, 22299, 22728, 22717, 22729, 22719, 22714, 22722, 22716, 22726, - 23319, 23321, 23323, 23329, 23316, 23315, 23312, 23318, [23336, 59539], - 23322, 23328, 23326, 23535, 23980, 23985, 23977, 23975, 23989, 23984, - 23982, 23978, 23976, 23986, 23981, 23983, 23988, {f: 2, c: 24167}, 24166, - 24175, 24297, 24295, 24294, 24296, 24293, 24395, 24508, 24507, 24989, - 25000, 24982, 25029, 25012, 25030, 25025, 25036, 25018, 25023, 25016, - 24972, 25815, 25814, 25808, 25807, 25801, 25789, 25737, 25795, 25819, - 25843, 25817, 25907, 25983, 25980, 26018, 26312, 26302, 26304, - {f: 2, c: 26314}, 26319, 26301, 26299, 26298, 26316, 26403, 27188, 27238, - 27209, 27239, 27186, 27240, 27198, 27229, 27245, 27254, 27227, 27217, - 27176, 27226, 27195, 27199, 27201, 27242, 27236, 27216, 27215, 27220, - 27247, 27241, 27232, 27196, 27230, 27222, 27221, {f: 2, c: 27213}, 27206, - 27477, 27476, 27478, 27559, {f: 2, c: 27562}, 27592, 27591, 27652, 27651, - 27654, 28589, 28619, 28579, 28615, 28604, 28622, 28616, 28510, 28612, - 28605, 28574, 28618, 28584, 28676, 28581, 28590, 28602, 28588, 28586, - 28623, 28607, 28600, 28578, 28617, 28587, 28621, 28591, 28594, 28592, - 29125, 29122, 29119, 29112, 29142, {f: 2, c: 29120}, 29131, 29140, 29130, - 29127, 29135, 29117, 29144, 29116, 29126, {f: 2, c: 29146}, - {f: 2, c: 29341}, 29545, {f: 2, c: 29542}, 29548, 29541, 29547, 29546, - 29823, 29850, 29856, 29844, 29842, 29845, 29857, 29963, 30080, 30255, - 30253, 30257, 30269, 30259, 30268, 30261, 30258, 30256, 30395, 30438, - 30618, 30621, 30625, 30620, 30619, {f: 2, c: 30626}, 30613, 30617, 30615, - 30941, 30953, 30949, 30954, 30942, 30947, 30939, {f: 2, c: 30945}, 30957, - {f: 2, c: 30943}, 31140, 31300, 31304, 31303, 31414, 31416, 31413, 31409, - 31415, 31710, 31715, 31719, 31709, 31701, 31717, 31706, 31720, 31737, - 31700, 31722, 31714, 31708, 31723, 31704, 31711, 31954, 31956, 31959, - {f: 2, c: 31952}, 32274, 32289, 32279, 32268, {f: 2, c: 32287}, 32275, - 32270, 32284, 32277, 32282, 32290, 32267, 32271, 32278, 32269, 32276, - 32293, 32292, 32579, {f: 2, c: 32635}, 32634, 32689, 32751, 32810, 32809, - 32876, 33201, 33190, 33198, 33209, 33205, 33195, 33200, 33196, 33204, - 33202, 33207, 33191, 33266, {f: 3, c: 33365}, 34134, 34117, 34155, 34125, - 34131, 34145, 34136, 34112, 34118, 34148, 34113, 34146, 34116, 34129, - 34119, 34147, 34110, 34139, 34161, 34126, 34158, 34165, 34133, 34151, - 34144, 34188, 34150, 34141, 34132, 34149, 34156, 34403, 34405, 34404, - 34724, 34715, 34703, 34711, 34707, 34706, 34696, 34689, 34710, 34712, - 34681, 34695, 34723, 34693, {f: 2, c: 34704}, 34717, 34692, 34708, 34716, - 34714, 34697, 35102, 35110, 35120, {f: 2, c: 35117}, 35111, 35121, 35106, - 35113, 35107, 35119, 35116, 35103, 35313, 35552, 35554, 35570, - {f: 2, c: 35572}, 35549, 35604, 35556, 35551, 35568, 35528, 35550, 35553, - 35560, 35583, 35567, 35579, {f: 2, c: 35985}, 35984, 36085, 36078, 36081, - 36080, 36083, 36204, 36206, 36261, 36263, 36403, 36414, 36408, 36416, - 36421, 36406, {f: 2, c: 36412}, 36417, 36400, 36415, 36541, [36662, 60329], - 36654, 36661, 36658, 36665, 36663, 36660, 36982, 36985, 36987, 36998, - 37114, 37171, {f: 2, c: 37173}, 37267, {f: 2, c: 37264}, 37261, 37263, - 37671, 37662, 37640, 37663, 37638, 37647, 37754, 37688, 37692, 37659, - 37667, 37650, 37633, 37702, 37677, 37646, 37645, 37579, 37661, 37626, - 37651, 37625, 37623, 37684, 37634, 37668, 37631, 37673, 37689, 37685, - 37674, 37652, 37644, 37643, 37630, 37641, 37632, 37627, 37654, 38332, - 38349, 38334, {f: 2, c: 38329}, 38326, 38335, 38325, 38333, 38569, 38612, - 38667, 38674, 38672, 38809, 38807, 38804, 38896, 38904, 38965, 38959, - 38962, 39204, 39199, 39207, 39209, 39326, 39406, 39404, 39397, 39396, - 39408, 39395, 39402, 39401, 39399, 39609, 39615, 39604, 39611, 39670, - 39674, 39673, 39671, 39731, 39808, 39813, 39815, 39804, 39806, 39803, - 39810, 39827, 39826, 39824, 39802, 39829, 39805, 39816, 40229, 40215, - 40224, 40222, 40212, 40233, 40221, 40216, 40226, 40208, 40217, 40223, - 40584, {f: 2, c: 40582}, 40622, 40621, {f: 2, c: 40661}, 40698, 40722, - 40765, 20774, 20773, 20770, 20772, 20768, 20777, 21236, 22163, - {f: 2, c: 22156}, 22150, 22148, 22147, 22142, 22146, 22143, 22145, 22742, - 22740, 22735, 22738, 23341, 23333, 23346, 23331, 23340, 23335, 23334, - 23343, 23342, 23419, {f: 2, c: 23537}, 23991, 24172, 24170, 24510, 25027, - 25013, 25020, 25063, 25056, 25061, 25060, 25064, 25054, 25839, 25833, - 25827, 25835, 25828, 25832, 25985, 25984, 26038, 26074, 26322, 27277, - 27286, 27265, 27301, 27273, 27295, 27291, 27297, 27294, 27271, 27283, - 27278, 27285, 27267, 27304, 27300, 27281, 27263, 27302, 27290, 27269, - 27276, 27282, 27483, 27565, 27657, 28620, 28585, 28660, 28628, 28643, - 28636, 28653, 28647, 28646, 28638, 28658, 28637, 28642, 28648, 29153, - 29169, 29160, 29170, 29156, 29168, 29154, 29555, {f: 2, c: 29550}, 29847, - 29874, 29867, 29840, 29866, 29869, 29873, 29861, 29871, {f: 3, c: 29968}, - 29967, 30084, 30275, {f: 2, c: 30280}, 30279, 30372, 30441, 30645, 30635, - 30642, 30647, 30646, 30644, 30641, 30632, 30704, 30963, 30973, 30978, - {f: 2, c: 30971}, 30975, 30962, 30981, 30969, 30974, 30980, 31147, 31144, - 31324, 31323, 31318, 31320, 31316, 31322, 31422, {f: 2, c: 31424}, 31749, - 31759, 31730, 31744, 31743, 31739, 31758, 31732, 31755, 31731, 31746, - 31753, 31747, 31745, 31736, 31741, [31750, 58176], {f: 2, c: 31728}, 31760, - 31754, 31976, 32301, 32316, 32322, 32307, 38984, 32312, 32298, 32329, - 32320, 32327, 32297, 32332, 32304, 32315, 32310, 32324, 32314, 32581, - 32639, 32638, 32637, 32756, 32754, 32812, 33211, 33220, 33228, 33226, - 33221, 33223, 33212, 33257, 33371, 33370, 33372, 34179, 34176, 34191, - 34215, 34197, 34208, 34187, 34211, 34171, 34212, 34202, 34206, 34167, - 34172, 34185, 34209, 34170, 34168, 34135, 34190, 34198, 34182, 34189, - 34201, 34205, 34177, 34210, 34178, 34184, 34181, 34169, 34166, 34200, - 34192, 34207, 34408, 34750, 34730, 34733, 34757, 34736, 34732, 34745, - 34741, 34748, 34734, 34761, 34755, 34754, 34764, 34743, 34735, 34756, - 34762, 34740, 34742, 34751, 34744, 34749, 34782, 34738, 35125, 35123, - 35132, 35134, 35137, 35154, 35127, 35138, 35245, 35247, 35246, - {f: 2, c: 35314}, 35614, 35608, 35606, 35601, 35589, 35595, 35618, 35599, - 35602, 35605, 35591, 35597, 35592, 35590, 35612, 35603, 35610, 35919, - 35952, 35954, 35953, 35951, 35989, 35988, 36089, 36207, 36430, 36429, - 36435, 36432, 36428, 36423, 36675, 36672, 36997, 36990, 37176, 37274, - 37282, 37275, 37273, 37279, 37281, 37277, 37280, 37793, 37763, 37807, - 37732, 37718, 37703, 37756, 37720, 37724, 37750, 37705, {f: 2, c: 37712}, - 37728, 37741, 37775, 37708, 37738, 37753, 37719, 37717, 37714, 37711, - 37745, 37751, 37755, 37729, 37726, 37731, 37735, 37710, 37721, 38343, - 38336, 38345, 38339, 38341, 38327, 38574, 38576, 38572, 38688, 38687, - 38680, 38685, 38681, 38810, 38817, 38812, 38814, 38813, 38869, 38868, - 38897, 38977, 38980, 38986, 38985, 38981, 38979, 39205, {f: 2, c: 39211}, - 39210, 39219, 39218, 39215, 39213, 39217, 39216, 39320, 39331, 39329, - 39426, 39418, 39412, 39415, 39417, 39416, 39414, 39419, {f: 2, c: 39421}, - 39420, 39427, 39614, 39678, 39677, 39681, 39676, 39752, 39834, 39848, - 39838, 39835, 39846, 39841, 39845, 39844, 39814, 39842, 39840, 39855, - 40243, 40257, 40295, 40246, {f: 2, c: 40238}, 40241, 40248, 40240, 40261, - {f: 2, c: 40258}, 40254, 40247, 40256, 40253, 32757, 40237, 40586, 40585, - 40589, 40624, 40648, 40666, 40699, 40703, 40740, 40739, 40738, 40788, - [12245, 40864], 20785, {f: 2, c: 20781}, 22168, 22172, 22167, 22170, 22173, - 22169, 22896, 23356, {f: 2, c: 23657}, 24000, {f: 2, c: 24173}, 25048, - 25055, {f: 2, c: 25069}, 25073, 25066, 25072, 25067, 25046, 25065, 25855, - 25860, 25853, 25848, 25857, 25859, 25852, 26004, 26075, {f: 2, c: 26330}, - 26328, 27333, 27321, 27325, 27361, 27334, 27322, {f: 2, c: 27318}, 27335, - 27316, 27309, 27486, 27593, 27659, 28679, {f: 2, c: 28684}, 28673, 28677, - 28692, 28686, {f: 2, c: 28671}, 28667, 28710, 28668, 28663, 28682, - [29185, 60224], 29183, 29177, 29187, 29181, 29558, 29880, 29888, 29877, - 29889, 29886, 29878, 29883, 29890, 29972, 29971, 30300, 30308, 30297, - 30288, 30291, 30295, 30298, 30374, 30397, 30444, 30658, 30650, 30988, - {f: 2, c: 30995}, 30985, 30992, 30994, 30993, 31149, 31148, 31327, 31772, - 31785, 31769, 31776, 31775, 31789, 31773, 31782, 31784, 31778, 31781, - 31792, 32348, 32336, 32342, 32355, 32344, 32354, 32351, 32337, 32352, - 32343, 32339, 32693, 32691, {f: 2, c: 32759}, 32885, {f: 2, c: 33233}, - 33232, 33375, 33374, 34228, 34246, 34240, 34243, 34242, 34227, 34229, - 34237, 34247, 34244, 34239, 34251, 34254, 34248, 34245, 34225, 34230, - 34258, 34340, 34232, 34231, 34238, 34409, 34791, 34790, 34786, 34779, - 34795, 34794, 34789, 34783, 34803, 34788, 34772, 34780, 34771, 34797, - 34776, 34787, 34775, 34777, 34817, 34804, 34792, 34781, 35155, 35147, - 35151, 35148, 35142, {f: 2, c: 35152}, 35145, 35626, 35623, 35619, 35635, - 35632, 35637, 35655, 35631, 35644, 35646, 35633, 35621, 35639, 35622, - 35638, 35630, 35620, 35643, 35645, 35642, 35906, 35957, 35993, 35992, - 35991, 36094, 36100, 36098, 36096, 36444, 36450, 36448, 36439, 36438, - 36446, 36453, 36455, 36443, 36442, 36449, 36445, 36457, 36436, - {f: 3, c: 36678}, 36683, 37160, {f: 2, c: 37178}, 37182, 37288, 37285, - 37287, 37295, 37290, 37813, 37772, 37778, 37815, 37787, 37789, 37769, - 37799, 37774, 37802, 37790, 37798, 37781, 37768, 37785, 37791, 37760, - 37773, 37809, 37777, 37810, 37796, 37800, 37812, 37795, {f: 2, c: 38354}, - 38353, 38579, 38615, 38618, 24002, 38623, 38616, 38621, 38691, 38690, - 38693, 38828, 38830, 38824, 38827, 38820, 38826, 38818, 38821, 38871, - 38873, 38870, 38872, 38906, {f: 3, c: 38992}, 39096, 39233, 39228, 39226, - 39439, 39435, 39433, 39437, 39428, 39441, 39434, 39429, 39431, 39430, - 39616, 39644, 39688, {f: 2, c: 39684}, 39721, 39733, 39754, 39756, 39755, - 39879, 39878, 39875, 39871, 39873, 39861, 39864, 39891, 39862, 39876, - 39865, 39869, 40284, 40275, 40271, 40266, 40283, 40267, 40281, 40278, - 40268, 40279, 40274, 40276, 40287, 40280, 40282, 40590, 40588, 40671, - 40705, 40704, [40726, 58693], 40741, 40747, 40746, 40745, 40744, 40780, - 40789, {f: 2, c: 20788}, 21142, 21239, 21428, 22187, 22189, - {f: 2, c: 22182}, 22186, 22188, 22746, 22749, 22747, 22802, - {f: 3, c: 23357}, 24003, 24176, 24511, 25083, 25863, 25872, 25869, 25865, - 25868, 25870, 25988, 26078, 26077, 26334, 27367, 27360, 27340, 27345, - 27353, 27339, 27359, 27356, 27344, 27371, 27343, 27341, 27358, 27488, - 27568, 27660, 28697, 28711, 28704, 28694, 28715, {f: 3, c: 28705}, 28713, - 28695, 28708, 28700, 29196, 29194, 29191, 29186, 29189, {f: 2, c: 29349}, - 29348, 29347, 29345, 29899, 29893, 29879, 29891, 29974, 30304, - {f: 2, c: 30665}, 30660, 30705, 31005, 31003, 31009, 31004, 30999, 31006, - 31152, {f: 2, c: 31335}, 31795, 31804, 31801, 31788, 31803, 31980, 31978, - 32374, 32373, 32376, 32368, 32375, 32367, 32378, 32370, 32372, 32360, - 32587, 32586, 32643, 32646, 32695, {f: 2, c: 32765}, 32888, 33239, 33237, - 33291, 33380, 33377, 33379, 34283, 34289, 34285, 34265, 34273, 34280, - 34266, 34263, 34284, 34290, 34296, 34264, 34271, 34275, 34268, 34257, - 34288, 34278, 34287, 34270, 34274, 34816, 34810, 34819, {f: 2, c: 34806}, - 34825, 34828, 34827, 34822, 34812, 34824, 34815, 34826, 34818, 35170, - {f: 2, c: 35162}, 35159, 35169, 35164, 35160, 35165, 35161, 35208, 35255, - 35254, 35318, 35664, 35656, 35658, 35648, 35667, 35670, 35668, 35659, - 35669, 35665, 35650, 35666, 35671, 35907, 35959, 35958, 35994, - {f: 2, c: 36102}, 36105, 36268, 36266, 36269, 36267, 36461, 36472, 36467, - 36458, 36463, 36475, 36546, 36690, 36689, {f: 2, c: 36687}, 36691, 36788, - 37184, 37183, 37296, 37293, 37854, 37831, 37839, 37826, 37850, 37840, - 37881, 37868, 37836, 37849, 37801, 37862, 37834, 37844, 37870, 37859, - 37845, 37828, 37838, 37824, 37842, 37797, 37863, 38269, {f: 2, c: 38362}, - 38625, 38697, {f: 2, c: 38699}, 38696, 38694, 38835, 38839, 38838, - {f: 3, c: 38877}, 39004, 39001, 39005, 38999, 39103, 39101, 39099, 39102, - 39240, 39239, 39235, {f: 2, c: 39334}, 39450, 39445, 39461, 39453, 39460, - 39451, 39458, 39456, 39463, 39459, 39454, 39452, 39444, 39618, 39691, - 39690, 39694, 39692, 39735, {f: 2, c: 39914}, 39904, 39902, 39908, 39910, - 39906, 39920, 39892, 39895, 39916, 39900, 39897, 39909, 39893, 39905, - 39898, 40311, 40321, 40330, 40324, 40328, 40305, 40320, 40312, 40326, - {f: 2, c: 40331}, 40317, 40299, {f: 2, c: 40308}, 40304, 40297, 40325, - 40307, 40315, 40322, 40303, 40313, 40319, 40327, 40296, 40596, 40593, - 40640, 40700, 40749, {f: 2, c: 40768}, 40781, {f: 3, c: 40790}, 21303, - 22194, 22197, 22195, 22755, 23365, {f: 2, c: 24006}, {f: 2, c: 24302}, - {f: 2, c: 24512}, 25081, 25879, 25878, 25877, 25875, 26079, 26344, - {f: 2, c: 26339}, 27379, 27376, 27370, 27368, 27385, 27377, - {f: 2, c: 27374}, 28732, 28725, 28719, 28727, 28724, 28721, 28738, 28728, - 28735, 28730, 28729, 28714, 28736, 28731, 28723, 28737, {f: 2, c: 29203}, - 29352, 29565, 29564, 29882, 30379, 30378, 30398, 30445, 30668, - {f: 2, c: 30670}, 30669, 30706, 31013, 31011, {f: 2, c: 31015}, 31012, - 31017, 31154, 31342, {f: 2, c: 31340}, 31479, 31817, 31816, 31818, 31815, - 31813, 31982, 32379, 32382, 32385, 32384, 32698, 32767, 32889, 33243, - 33241, {f: 2, c: 33384}, 34338, 34303, 34305, 34302, 34331, 34304, 34294, - 34308, 34313, 34309, 34316, 34301, 34841, {f: 2, c: 34832}, 34839, 34835, - 34838, 35171, 35174, 35257, 35319, 35680, 35690, 35677, 35688, 35683, - 35685, 35687, 35693, 36270, 36486, 36488, 36484, 36697, {f: 2, c: 36694}, - 36693, 36696, 36698, 37005, 37187, 37185, 37303, 37301, {f: 2, c: 37298}, - 37899, 37907, 37883, 37920, 37903, 37908, 37886, 37909, 37904, 37928, - 37913, 37901, 37877, 37888, 37879, 37895, 37902, 37910, 37906, 37882, - 37897, 37880, 37948, 37898, 37887, 37884, 37900, 37878, 37905, 37894, - 38366, 38368, 38367, {f: 2, c: 38702}, 38841, 38843, {f: 2, c: 38909}, - 39008, {f: 2, c: 39010}, 39007, {f: 2, c: 39105}, 39248, 39246, 39257, - 39244, 39243, 39251, 39474, 39476, 39473, 39468, 39466, 39478, 39465, - 39470, 39480, 39469, 39623, 39626, 39622, 39696, 39698, 39697, 39947, - 39944, 39927, 39941, 39954, 39928, 40000, 39943, 39950, 39942, 39959, - 39956, 39945, 40351, 40345, 40356, 40349, 40338, 40344, 40336, 40347, - 40352, 40340, 40348, 40362, 40343, 40353, 40346, 40354, 40360, 40350, - 40355, 40383, 40361, 40342, {f: 2, c: 40358}, 40601, 40603, 40602, 40677, - 40676, 40679, 40678, 40752, 40750, 40795, 40800, 40798, 40797, 40793, - 40849, 20794, 20793, 21144, 21143, 22211, {f: 2, c: 22205}, 23368, 23367, - 24011, 24015, 24305, 25085, 25883, 27394, 27388, 27395, 27384, 27392, - {f: 2, c: 28739}, 28746, {f: 2, c: 28744}, {f: 2, c: 28741}, 29213, 29210, - 29209, 29566, 29975, 30314, 30672, 31021, 31025, 31023, 31828, 31827, - 31986, 32394, [32391, 60229], 32392, 32395, 32390, 32397, 32589, 32699, - 32816, 33245, 34328, 34346, 34342, 34335, 34339, 34332, 34329, 34343, - 34350, 34337, 34336, 34345, 34334, 34341, 34857, 34845, 34843, 34848, - 34852, 34844, 34859, 34890, 35181, 35177, 35182, 35179, 35322, 35705, - 35704, 35653, {f: 2, c: 35706}, 36112, 36116, 36271, 36494, 36492, 36702, - 36699, 36701, 37190, {f: 2, c: 37188}, 37305, 37951, 37947, 37942, 37929, - 37949, 37936, 37945, 37930, 37943, 37932, 37952, 37937, 38373, 38372, - 38371, 38709, 38714, 38847, 38881, 39012, 39113, 39110, 39104, 39256, - 39254, 39481, 39485, 39494, 39492, 39490, 39489, 39482, 39487, 39629, - 39701, {f: 2, c: 39703}, 39702, 39738, 39762, 39979, 39965, 39964, 39980, - 39971, {f: 2, c: 39976}, 39972, 39969, 40375, 40374, 40380, 40385, 40391, - 40394, 40399, 40382, 40389, 40387, 40379, 40373, 40398, {f: 2, c: 40377}, - 40364, 40392, 40369, 40365, 40396, 40371, 40397, 40370, 40570, 40604, - 40683, 40686, 40685, 40731, 40728, 40730, 40753, 40782, 40805, 40804, - 40850, 20153, 22214, 22213, 22219, 22897, {f: 2, c: 23371}, 24021, 24017, - 24306, 25889, 25888, 25894, 25890, 27403, {f: 2, c: 27400}, 27661, - {f: 3, c: 28757}, 28754, {f: 2, c: 29214}, 29353, 29567, 29912, 29909, - 29913, 29911, 30317, 30381, 31029, 31156, {f: 2, c: 31344}, 31831, 31836, - 31833, 31835, 31834, 31988, 31985, 32401, 32591, 32647, 33246, 33387, - {f: 2, c: 34356}, 34355, 34348, 34354, 34358, 34860, 34856, 34854, 34858, - 34853, 35185, 35263, 35262, 35323, 35710, 35716, 35714, 35718, 35717, - 35711, 36117, 36501, 36500, 36506, 36498, 36496, {f: 2, c: 36502}, 36704, - 36706, 37191, 37964, 37968, {f: 2, c: 37962}, 37967, 37959, 37957, - {f: 2, c: 37960}, 37958, 38719, 38883, 39018, 39017, 39115, 39252, 39259, - 39502, {f: 2, c: 39507}, 39500, 39503, 39496, 39498, 39497, 39506, 39504, - 39632, 39705, 39723, 39739, 39766, 39765, 40006, 40008, 39999, 40004, - 39993, 39987, 40001, 39996, 39991, 39988, 39986, 39997, 39990, 40411, - 40402, 40414, 40410, 40395, 40400, 40412, 40401, 40415, 40425, 40409, - 40408, 40406, 40437, 40405, 40413, 40630, 40688, 40757, 40755, 40754, - 40770, 40811, 40853, 40866, 20797, 21145, 22760, 22759, 22898, 23373, - 24024, 34863, 24399, 25089, {f: 2, c: 25091}, 25897, 25893, 26006, 26347, - {f: 2, c: 27409}, 27407, 27594, 28763, 28762, 29218, 29570, 29569, 29571, - 30320, 30676, 31847, 31846, 32405, 33388, 34362, 34368, 34361, 34364, - 34353, 34363, 34366, 34864, 34866, 34862, 34867, 35190, 35188, 35187, - 35326, 35724, 35726, 35723, 35720, 35909, 36121, 36504, 36708, 36707, - 37308, 37986, 37973, 37981, 37975, 37982, {f: 2, c: 38852}, 38912, 39510, - 39513, {f: 3, c: 39710}, 40018, 40024, 40016, 40010, 40013, 40011, 40021, - 40025, 40012, 40014, 40443, 40439, 40431, 40419, 40427, 40440, 40420, - 40438, 40417, 40430, 40422, 40434, [40432, 60370], 40418, 40428, 40436, - 40435, 40424, 40429, 40642, 40656, {f: 2, c: 40690}, 40710, 40732, 40760, - 40759, 40758, 40771, 40783, 40817, 40816, {f: 2, c: 40814}, 22227, 22221, - 23374, 23661, 25901, {f: 2, c: 26349}, 27411, 28767, 28769, 28765, 28768, - 29219, 29915, 29925, 30677, 31032, 31159, 31158, 31850, 32407, 32649, - 33389, 34371, 34872, 34871, 34869, 34891, {f: 2, c: 35732}, - {f: 3, c: 36510}, 36509, 37310, 37309, 37314, 37995, {f: 2, c: 37992}, - 38629, 38726, 38723, 38727, 38855, 38885, 39518, 39637, 39769, 40035, - 40039, 40038, 40034, 40030, 40032, 40450, 40446, 40455, 40451, 40454, - 40453, {f: 2, c: 40448}, 40457, 40447, 40445, 40452, 40608, 40734, 40774, - {f: 3, c: 40820}, 22228, 25902, 26040, {f: 2, c: 27416}, 27415, 27418, - 28770, 29222, 29354, {f: 2, c: 30680}, 31033, 31849, 31851, 31990, 32410, - 32408, 32411, 32409, {f: 2, c: 33248}, {f: 3, c: 34374}, {f: 2, c: 35193}, - 35196, 35195, 35327, {f: 2, c: 35736}, 36517, 36516, 36515, 37998, 37997, - 37999, 38001, 38003, 38729, 39026, 39263, 40040, 40046, 40045, 40459, - 40461, 40464, 40463, 40466, 40465, 40609, 40693, 40713, 40775, 40824, - 40827, 40826, 40825, 22302, 28774, 31855, 34876, 36274, 36518, 37315, - 38004, 38008, 38006, 38005, 39520, [39726, 60830], 40052, 40051, 40049, - 40053, 40468, 40467, 40694, 40714, 40868, 28776, 28773, 31991, 34410, - 34878, 34877, 34879, 35742, 35996, 36521, 36553, 38731, {f: 2, c: 39027}, - 39116, 39265, 39339, 39524, {f: 2, c: 39526}, 39716, 40469, 40471, 40776, - 25095, 27422, 29223, 34380, 36520, 38018, {f: 2, c: 38016}, 39529, 39528, - 40473, 34379, 35743, 38019, 40057, 40631, 30325, 39531, 40058, 40477, - {f: 2, c: 28777}, 29225, 40612, 40830, 40777, 40856, {s: 97}, 65075, 0, - 65076, 65103, [168, 776, 63208], [710, 63209, 65342], [12541, 63210], - [12542, 63211], [12445, 63212], [12446, 63213], 0, [12293, 63216], - [12294, 63217], [12295, 63218], [12540, 63219], [63220, 65339], - [63221, 65341], [10045, 63222], [12353, 63223], [12354, 63224], - [12355, 63225], [12356, 63226], [12357, 63227], [12358, 63228], - [12359, 63229], [12360, 63230], [12361, 63231], [12362, 63232], - [12363, 63233], [12364, 63234], [12365, 63235], [12366, 63236], - [12367, 63237], [12368, 63238], [12369, 63239], [12370, 63240], - [12371, 63241], [12372, 63242], [12373, 63243], [12374, 63244], - [12375, 63245], [12376, 63246], [12377, 63247], [12378, 63248], - [12379, 63249], [12380, 63250], [12381, 63251], [12382, 63252], - [12383, 63253], [12384, 63254], [12385, 63255], [12386, 63256], - [12387, 63257], [12388, 63258], [12389, 63259], [12390, 63260], - [12391, 63261], [12392, 63262], [12393, 63263], [12394, 63264], - [12395, 63265], [12396, 63266], [12397, 63267], [12398, 63268], - [12399, 63269], [12400, 63270], [12401, 63271], [12402, 63272], - [12403, 63273], [12404, 63274], [12405, 63275], [12406, 63276], - [12407, 63277], [12408, 63278], [12409, 63279], [12410, 63280], - [12411, 63281], [12412, 63282], [12413, 63283], [12414, 63284], - [12415, 63285], [12416, 63286], [12417, 63287], [12418, 63288], - [12419, 63289], [12420, 63290], [12421, 63291], [12422, 63292], - [12423, 63293], [12424, 63294], [12425, 63295], [12426, 63296], - [12427, 63297], [12428, 63298], [12429, 63299], [12430, 63300], - [12431, 63301], [12432, 63302], [12433, 63303], [12434, 63304], - [12435, 63305], [12449, 63306], [12450, 63307], [12451, 63308], - [12452, 63309], [12453, 63310], [12454, 63311], [12455, 63312], - [12456, 63313], [12457, 63314], [12458, 63315], [12459, 63316], - [12460, 63317], [12461, 63318], [12462, 63319], [12463, 63320], - [12464, 63321], [12465, 63322], [12466, 63323], [12467, 63324], - [12468, 63325], [12469, 63326], [12470, 63327], [12471, 63328], - [12472, 63329], [12473, 63330], [12474, 63331], [12475, 63332], - [12476, 63333], [12477, 63334], [12478, 63335], [12479, 63336], - [12480, 63337], [12481, 63338], [12482, 63339], [12483, 63340], - [12484, 63341], [12485, 63342], [12486, 63343], [12487, 63344], - [12488, 63345], [12489, 63346], [12490, 63347], [12491, 63348], - [12492, 63349], [12493, 63350], [12494, 63351], [12495, 63352], - [12496, 63353], [12497, 63354], [12498, 63355], [12499, 63356], - [12500, 63357], [12501, 63358], [12502, 63359], [12503, 63360], - [12504, 63361], [12505, 63362], [12506, 63363], [12507, 63364], - [12508, 63365], [12509, 63366], [12510, 63367], [12511, 63368], - [12512, 63369], [12513, 63370], [12514, 63371], [12515, 63372], - [12516, 63373], [12517, 63374], [12518, 63375], [12519, 63376], - [12520, 63377], [12521, 63378], [12522, 63379], [12523, 63380], - [12524, 63381], [12525, 63382], [12526, 63383], [12527, 63384], - [12528, 63385], [12529, 63386], [12530, 63387], [12531, 63388], - [12532, 63389], [12533, 63390], [12534, 63391], [1040, 63392], - [1041, 63393], [1042, 63394], [1043, 63395], [1044, 63396], [1045, 63397], - [1025, 63398], [1046, 63399], [1047, 63400], [1048, 63401], [1049, 63402], - [1050, 63403], [1051, 63404], [1052, 63405], [1053, 63406], [1054, 63407], - [1055, 63408], [1056, 63409], [1057, 63410], [1058, 63411], [1059, 63412], - [1060, 63413], [1061, 63414], [1062, 63415], [1063, 63416], [1064, 63417], - [1065, 63418], [1066, 63419], [1067, 63420], [1068, 63421], [1069, 63422], - [1070, 63423], [1071, 63424], [1072, 63425], [1073, 63426], [1074, 63427], - [1075, 63428], [1076, 63429], [1077, 63430], [1105, 63431], [1078, 63432], - [1079, 63433], [1080, 63434], [1081, 63435], [1082, 63436], [1083, 63437], - [1084, 63438], [1085, 63439], [1086, 63440], [1087, 63441], [1088, 63442], - [1089, 63443], [1090, 63444], [1091, 63445], [1092, 63446], [1093, 63447], - [1094, 63448], [1095, 63449], [1096, 63450], [1097, 63451], [1098, 63452], - [1099, 63453], [1100, 63454], [1101, 63455], [1102, 63456], [1103, 63457], - [8679, 63458], [8632, 63459], [8633, 63460], [20033, 63461], - [63462, 131276], [20058, 63463], [63464, 131210], [20994, 63465], - [17553, 63466], 63467, [20872, 63468], [13853, 63469], [63470, 161287], - {s: 40}, [172, 63511, 65506], [63512, 65508], [63513, 65287], - [63514, 65282], [12849, 63515], [8470, 63516], [8481, 63517], 30849, - [37561, 58501], 35023, 22715, 24658, 31911, 23290, 9556, 9574, 9559, 9568, - 9580, 9571, 9562, 9577, 9565, 9554, 9572, 9557, {s: 3}, 9560, 9575, 9563, - 9555, 9573, 9558, 9567, 9579, 9570, 9561, 9576, 9564, 9553, {s: 5}, 9619, - {s: 26}, [58129, 147159], [22462, 58130], [58131, 159443], [28990, 58132], - [58133, 153568], [27042, 58135], [58136, 166889], [23412, 58137], - [31305, 58138], [58139, 153825], [58140, 169177], [31333, 58141], - [31357, 58142], [58143, 154028], [31419, 58144], [31408, 58145], - [31426, 58146], [31427, 58147], [29137, 58148], [58149, 156813], - [16842, 58150], [31450, 58151], [31453, 58152], [31466, 58153], - [16879, 58154], [21682, 58155], [58156, 154625], [31499, 58157], - [31573, 58158], [31529, 58159], [58160, 152334], [58161, 154878], - [31650, 58162], [31599, 58163], [33692, 58164], [58165, 154548], - [58166, 158847], [31696, 58167], [33825, 58168], [31634, 58169], 0, - [58171, 154912], 0, [33938, 58174], [31738, 58175], 0, [31797, 58177], - [58178, 154817], [31812, 58179], [31875, 58180], [58181, 149634], - [31910, 58182], [58184, 148856], [31945, 58185], [31943, 58186], - [31974, 58187], 0, [31987, 58189], [31989, 58190], [32359, 58192], - [17693, 58193], [58194, 159300], [32093, 58195], [58196, 159446], - [32137, 58198], [32171, 58199], [28981, 58200], [32179, 58201], 32214, - [58203, 147543], [58204, 155689], [32228, 58205], [15635, 58206], - [32245, 58207], [58208, 137209], [32229, 58209], [58210, 164717], 0, - [58212, 155937], [58213, 155994], [32366, 58214], 0, [17195, 58216], - [37996, 58217], [32295, 58218], [32576, 58219], [32577, 58220], - [32583, 58221], [31030, 58222], [58223, 156368], [39393, 58224], - [32663, 58225], [58226, 156497], [32675, 58227], [58228, 136801], - [58229, 131176], [17756, 58230], [58231, 145254], [58233, 164666], - [32762, 58234], [58235, 156809], 0, [32776, 58237], [32797, 58238], 0, - [32815, 58240], [58241, 172167], [58242, 158915], [32827, 58243], - [32828, 58244], [32865, 58245], [58246, 141076], [18825, 58247], - [58248, 157222], [58249, 146915], [58250, 157416], [26405, 58251], - [32935, 58252], [58253, 166472], [33031, 58254], [33050, 58255], - [22704, 58256], [58257, 141046], [27775, 58258], [58259, 156824], - [25831, 58261], [58262, 136330], [33304, 58263], [58264, 137310], - [27219, 58265], [58266, 150117], [58267, 150165], [17530, 58268], - [33321, 58269], [58271, 158290], [58272, 146814], [20473, 58273], - [58274, 136445], [34018, 58275], [33634, 58276], 0, [58278, 149927], - [58279, 144688], [58280, 137075], [58281, 146936], [33450, 58282], - [26907, 58283], [58284, 194964], [16859, 58285], [34123, 58286], - [33488, 58287], [33562, 58288], [58289, 134678], [58290, 137140], - [14017, 58291], [58292, 143741], [58293, 144730], [33403, 58294], - [33506, 58295], [33560, 58296], [58297, 147083], [58298, 159139], - [58299, 158469], [58300, 158615], [58301, 144846], [15807, 58302], - [33565, 58303], [21996, 58304], [33669, 58305], [17675, 58306], - [58307, 159141], [33708, 58308], 0, [33747, 58310], [58312, 159444], - [27223, 58313], [34138, 58314], [13462, 58315], [58316, 159298], - [33880, 58318], [58319, 154596], [33905, 58320], [15827, 58321], - [17636, 58322], [27303, 58323], [33866, 58324], [31064, 58326], 0, - [58328, 158614], [58329, 159351], [58330, 159299], [34014, 58331], 0, - [33681, 58333], [17568, 58334], [33939, 58335], [34020, 58336], - [58337, 154769], [16960, 58338], [58339, 154816], [17731, 58340], - [34100, 58341], [23282, 58342], 0, [17703, 58344], [34163, 58345], - [17686, 58346], [26559, 58347], [34326, 58348], [58349, 165413], - [58350, 165435], [34241, 58351], [58352, 159880], [34306, 58353], - [58354, 136578], [58355, 159949], [58356, 194994], [17770, 58357], - [34344, 58358], [13896, 58359], [58360, 137378], [21495, 58361], - [58362, 160666], [34430, 58363], 0, [58365, 172280], [34798, 58366], - [58367, 142375], [34737, 58368], [34778, 58369], [34831, 58370, 60990], - [22113, 58371], [34412, 58372], [26710, 58373], [17935, 58374], - [34885, 58375], [34886, 58376], [58377, 161248], [58378, 146873], - [58379, 161252], [34910, 58380], [34972, 58381], [18011, 58382], - [34996, 58383], [34997, 58384], [35013, 58386], [58388, 161551], - [35207, 58389], {s: 3}, [35239, 58393], [35260, 58394], [58395, 166437], - [35303, 58396], [58397, 162084], [58398, 162493], [35484, 58399], - [30611, 58400], [37374, 58401], [35472, 58402], [58403, 162393], - [31465, 58404], [58405, 162618], [18195, 58407], [58408, 162616], - [29052, 58409], [35596, 58410], [35615, 58411], [58412, 152624], - [58413, 152933], [35647, 58414], 0, [35661, 58416], [35497, 58417], - [58418, 150138], [35728, 58419], [35739, 58420], [35503, 58421], - [58422, 136927], [17941, 58423], [34895, 58424], [35995, 58425], - [58426, 163156], [58427, 163215], [58428, 195028], [14117, 58429], - [58430, 163155], [36054, 58431], [58432, 163224], [58433, 163261], - [36114, 58434], [36099, 58435], [58436, 137488], [36059, 58437], - [28764, 58438], [36113, 58439], [16080, 58441], 0, [36265, 58443], - [58444, 163842], [58445, 135188], [58446, 149898], [15228, 58447], - [58448, 164284], [58449, 160012], [31463, 58450], [36525, 58451], - [36534, 58452], [36547, 58453], [37588, 58454], [36633, 58455], - [36653, 58456], [58457, 164709], [58458, 164882], [36773, 58459], - [37635, 58460], [58461, 172703], [58462, 133712], [36787, 58463], 0, - [58465, 166366], [58466, 165181], [58467, 146875], [24312, 58468], - [58469, 143970], [36857, 58470], 0, [58474, 140069], [14720, 58475], - [58476, 159447], [36919, 58477], [58478, 165180], [58479, 162494], - [36961, 58480], [58481, 165228], [58482, 165387], [37032, 58483], - [58484, 165651], [37060, 58485], [58486, 165606], [37038, 58487], 0, - [37223, 58489], [37289, 58491], [37316, 58492], [31916, 58493], - [58494, 166195], [58495, 138889], [37390, 58496], [27807, 58497], - [37441, 58498], [37474, 58499], [58500, 153017], [58502, 166598], - [58503, 146587], [58504, 166668], [58505, 153051], [58506, 134449], - [37676, 58507], [37739, 58508], [58509, 166625], [58510, 166891], - [23235, 58512], [58513, 166626], [58514, 166629], [18789, 58515], - [37444, 58516], [58517, 166892], [58518, 166969], [58519, 166911], - [37747, 58520], [37979, 58521], [36540, 58522], [38277, 58523], - [38310, 58524], [37926, 58525], [38304, 58526], [28662, 58527], - [17081, 58528], [58530, 165592], [58531, 135804], [58532, 146990], - [18911, 58533], [27676, 58534], [38523, 58535], [38550, 58536], - [16748, 58537], [38563, 58538], [58539, 159445], [25050, 58540], 58541, - [30965, 58542], [58543, 166624], [38589, 58544], [21452, 58545], - [18849, 58546], [58547, 158904], [58548, 131700], [58549, 156688], - [58550, 168111], [58551, 168165], [58552, 150225], [58553, 137493], - [58554, 144138], [38705, 58555], [34370, 58556], [38710, 58557], - [18959, 58558], [17725, 58559], [17797, 58560], [58561, 150249], - [28789, 58562], [23361, 58563], [38683, 58564], 0, [58566, 168405], - [38743, 58567], [23370, 58568], [58569, 168427], [38751, 58570], - [37925, 58571], [20688, 58572], [58573, 143543], [58574, 143548], - [38793, 58575], [38815, 58576], [38833, 58577], [38846, 58578], - [38848, 58579], [38866, 58580], [38880, 58581], [58582, 152684], - [38894, 58583], [29724, 58584], [58585, 169011], 0, [38901, 58587], - [58588, 168989], [58589, 162170], [19153, 58590], [38964, 58591], - [38963, 58592], [38987, 58593], [39014, 58594], [15118, 58595], - [58596, 160117], [15697, 58597], [58598, 132656], [58599, 147804], - [58600, 153350], [39114, 58601], [39095, 58602], [39112, 58603], - [39111, 58604], [19199, 58605], [58606, 159015], [58607, 136915], - [21936, 58608], [39137, 58609], [39142, 58610], [39148, 58611], - [37752, 58612], [39225, 58613], [58614, 150057], [19314, 58615], - [58616, 170071], [58617, 170245], [39413, 58618], [39436, 58619], - [39483, 58620], [39440, 58621], [39512, 58622], [58623, 153381], - [14020, 58624], [58625, 168113], [58626, 170965], [39648, 58627], - [39650, 58628], [58629, 170757], [39668, 58630], [19470, 58631], - [39700, 58632], [39725, 58633], [58634, 165376], [20532, 58635], - [39732, 58636], [14531, 58638], [58639, 143485], [39760, 58640], - [39744, 58641], [58642, 171326], [23109, 58643], [58644, 137315], - [39822, 58645], [39938, 58647], [39935, 58648], [39948, 58649], - [58650, 171624], [40404, 58651], [58652, 171959], [58653, 172434], - [58654, 172459], [58655, 172257], [58656, 172323], [58657, 172511], - [40318, 58658], [40323, 58659], [58660, 172340], [40462, 58661], - [40388, 58663], [58665, 172435], [58666, 172576], [58667, 137531], - [58668, 172595], [40249, 58669], [58670, 172217], [58671, 172724], - [40592, 58672], [40597, 58673], [40606, 58674], [40610, 58675], - [19764, 58676], [40618, 58677], [40623, 58678], [58679, 148324], - [40641, 58680], [15200, 58681], [14821, 58682], [15645, 58683], - [20274, 58684], [14270, 58685], [58686, 166955], [40706, 58687], - [40712, 58688], [19350, 58689], [37924, 58690], [58691, 159138], - [40727, 58692, 60836], 0, [40761, 58694], [22175, 58695], [22154, 58696], - [40773, 58697], [39352, 58698], [58699, 168075], [38898, 58700], - [33919, 58701], 0, [40809, 58703], [31452, 58704], [40846, 58705], - [29206, 58706], [19390, 58707], [58708, 149877], [58709, 149947], - [29047, 58710], [58711, 150008], [58712, 148296], [58713, 150097], - [29598, 58714], [58715, 166874], [58716, 137466], [31135, 58717], - [58718, 166270], [58719, 167478], [37737, 58720], [37875, 58721], - [58722, 166468], [37612, 58723], [37761, 58724], [37835, 58725], - [58726, 166252], [58727, 148665], [29207, 58728], [16107, 58729], - [30578, 58730], [31299, 58731], [28880, 58732], [58733, 148595], - [58734, 148472], [29054, 58735], [58736, 137199], [28835, 58737], - [58738, 137406], [58739, 144793], [16071, 58740], [58741, 137349], - [58742, 152623], [58743, 137208], [14114, 58744], [58745, 136955], - [58746, 137273], [14049, 58747], [58748, 137076], [58749, 137425], - [58750, 155467], [14115, 58751], [58752, 136896], [22363, 58753], - [58754, 150053], [58755, 136190], [58756, 135848], [58757, 136134], - [58758, 136374], [34051, 58759, 58761], [58760, 145062], 0, [33877, 58762], - [58763, 149908], [58764, 160101], [58765, 146993], [58766, 152924], - [58767, 147195], [58768, 159826], [17652, 58769], [58770, 145134], - [58771, 170397], [58772, 159526], [26617, 58773], [14131, 58774], - [15381, 58775], [15847, 58776], [22636, 58777], [58778, 137506], - [26640, 58779], [16471, 58780], [58781, 145215], [58782, 147681], - [58783, 147595], [58784, 147727], [58785, 158753], [21707, 58786], - [22174, 58787], [58788, 157361], [22162, 58789], [58790, 135135], - [58791, 134056], [58792, 134669], 0, [58794, 166675], [37788, 58795], - [20216, 58796], [20779, 58797], [14361, 58798], [58799, 148534], - [20156, 58800], [58801, 132197], 0, [20299, 58803], [20362, 58804], - [58805, 153169], [23144, 58806], [58807, 131499], [58808, 132043], - [14745, 58809], [58810, 131850], [58811, 132116], [13365, 58812], - [20265, 58813], [58814, 131776], [58815, 167603], [58816, 131701], - [35546, 58817], [58818, 131596], [20120, 58819], [20685, 58820], - [20749, 58821], [20386, 58822], [20227, 58823], [58824, 150030], - [58825, 147082], [20290, 58826], [20526, 58827], [20588, 58828], - [20609, 58829], [20428, 58830], [20453, 58831], [20568, 58832], - [20732, 58833], [28278, 58838], [58839, 144789], [58840, 147001], - [58841, 147135], [28018, 58842], [58843, 137348], [58844, 147081], - [20904, 58845], [20931, 58846], [58847, 132576], [17629, 58848], - [58849, 132259], [58850, 132242], [58851, 132241], [36218, 58852], - [58853, 166556], [58854, 132878], [21081, 58855], [21156, 58856], - [58857, 133235], [21217, 58858], 0, [18042, 58860], [29068, 58861], - [58862, 148364], [58863, 134176], [58864, 149932], [58865, 135396], - [27089, 58866], [58867, 134685], 0, [16094, 58869], [29849, 58870], - [29716, 58871], [29782, 58872], [29592, 58873], [19342, 58874], - [58875, 150204], [58876, 147597], [21456, 58877], [13700, 58878], - [29199, 58879], [58880, 147657], [21940, 58881], [58882, 131909], - [21709, 58883], [58884, 134086], [22301, 58885], [37469, 58886], - [38644, 58887], [22493, 58889], [22413, 58890], [22399, 58891], - [13886, 58892], [22731, 58893], [23193, 58894], [58895, 166470], - [58896, 136954], [58897, 137071], [58898, 136976], [23084, 58899], - [22968, 58900], [23166, 58902], [23247, 58903], [23058, 58904], - [58905, 153926], [58906, 137715], [58907, 137313], [58908, 148117], - [14069, 58909], [27909, 58910], [29763, 58911], [23073, 58912], - [58913, 155267], [23169, 58914], [58915, 166871], [58916, 132115], - [37856, 58917], [29836, 58918], [58919, 135939], [28933, 58920], - [18802, 58921], [37896, 58922], [58923, 166395], [37821, 58924], - [14240, 58925], [23582, 58926], [23710, 58927], [24158, 58928], - [24136, 58929], [58930, 137622], [58931, 137596], [58932, 146158], - [24269, 58933], [23375, 58934], [58935, 137475], [58936, 137476], - [14081, 58937], [58938, 137376], [14045, 58939], [58940, 136958], - [14035, 58941], [33066, 58942], [58943, 166471], [58944, 138682], - [58945, 144498], [58946, 166312], [24332, 58947, 60916], [24334, 58948], - [58949, 137511], [58950, 137131], [23147, 58951], [58952, 137019], - [23364, 58953], [58955, 161277], [34912, 58956], [24702, 58957], - [58958, 141408], [58959, 140843], [24539, 58960], [16056, 58961], - [58962, 140719], [58963, 140734], [58964, 168072], [58965, 159603], - [25024, 58966], [58967, 131134], [58968, 131142], [58969, 140827], - [24985, 58970], [24984, 58971], [24693, 58972], [58973, 142491], - [58974, 142599], [58975, 149204], [58976, 168269], [25713, 58977], - [58978, 149093], [58979, 142186], [14889, 58980], [58981, 142114], - [58982, 144464], [58983, 170218], [58984, 142968], [25399, 58985], - [25782, 58987], [25393, 58988], [25553, 58989], [58990, 149987], - [58991, 142695], [25252, 58992], [58993, 142497], [25659, 58994], - [25963, 58995], [26994, 58996], [15348, 58997], [58998, 143502], - [58999, 144045], [59000, 149897], [59001, 144043], [21773, 59002], - [59003, 144096], [59004, 137433], [59005, 169023], [26318, 59006], - [59007, 144009], [59008, 143795], [15072, 59009], [59011, 152964], - [59012, 166690], [59013, 152975], [59014, 136956], [59015, 152923], - [59016, 152613], [30958, 59017], [59018, 143619], [59019, 137258], - [59020, 143924], [13412, 59021], [59022, 143887], [59023, 143746], - [59024, 148169], [26254, 59025], [59026, 159012], [26219, 59027], - [19347, 59028], [26160, 59029], [59030, 161904], [59031, 138731], - [26211, 59032], [59033, 144082], [59034, 144097], [26142, 59035], - [59036, 153714], [14545, 59037], [59038, 145466], [59039, 145340], - [15257, 59040], [59041, 145314], [59042, 144382], [29904, 59043], - [15254, 59044], [59046, 149034], [26806, 59047], 0, [15300, 59049], - [27326, 59050], [59052, 145365], [59053, 148615], [27187, 59054], - [27218, 59055], [27337, 59056], [27397, 59057], [59058, 137490], - [25873, 59059], [26776, 59060], [27212, 59061], [15319, 59062], - [27258, 59063], [27479, 59064], [59065, 147392], [59066, 146586], - [37792, 59067], [37618, 59068], [59069, 166890], [59070, 166603], - [37513, 59071], [59072, 163870], [59073, 166364], [37991, 59074], - [28069, 59075], [28427, 59076], 0, [59079, 147327], [15759, 59080], - [28164, 59081], [59082, 147516], [23101, 59083], [28170, 59084], - [22599, 59085], [27940, 59086], [30786, 59087], [28987, 59088], - [59089, 148250], [59090, 148086], [28913, 59091], [29264, 59092, 61085], - [29319, 59093], [29332, 59094], [59095, 149391], [59096, 149285], - [20857, 59097], [59098, 150180], [59099, 132587], [29818, 59100], - [59101, 147192], [59102, 144991], [59103, 150090], [59104, 149783], - [59105, 155617], [16134, 59106], [16049, 59107], [59108, 150239], - [59109, 166947], [59110, 147253], [24743, 59111], [16115, 59112], - [29900, 59113], [29756, 59114], [37767, 59115], [29751, 59116], - [17567, 59117], [59118, 159210], [17745, 59119], [30083, 59120], - [16227, 59121], [59122, 150745], [59123, 150790], [16216, 59124], - [30037, 59125], [30323, 59126], [59127, 173510], 0, [29800, 59129, 61070], - [59130, 166604], [59131, 149931], [59132, 149902], [15099, 59133], - [15821, 59134], [59135, 150094], [16127, 59136], [59137, 149957], - [59138, 149747], [37370, 59139], [22322, 59140], [37698, 59141], - [59142, 166627], [59143, 137316], [20703, 59144], [59145, 152097], - [59146, 152039], [30584, 59147], [59148, 143922], [30478, 59149], - [30479, 59150], [30587, 59151], [59152, 149143], [59153, 145281], - [14942, 59154], [59155, 149744], [29752, 59156], [29851, 59157], - [16063, 59158], [59159, 150202], [59160, 150215], [16584, 59161], - [59162, 150166], [59163, 156078], [37639, 59164], [59165, 152961], - [30750, 59166], [30861, 59167], [30856, 59168], [30930, 59169], - [29648, 59170], [31065, 59171], [59172, 161601], [59173, 153315], - [16654, 59174], 0, 0, [31141, 59177], [27181, 59178], [59179, 147194], - [31290, 59180], [31220, 59181], [16750, 59182], [59183, 136934], - [16690, 59184], [37429, 59185], [31217, 59186], [59187, 134476], - [59188, 149900], [59189, 131737], [59190, 146874], [59191, 137070], - [13719, 59192], [21867, 59193], [13680, 59194], [13994, 59195], - [59196, 131540], [59197, 134157], [31458, 59198], [23129, 59199], - [59200, 141045], [59201, 154287], [59202, 154268], [23053, 59203], - [59204, 131675], [30960, 59205], [23082, 59206], [59207, 154566], - [31486, 59208], [16889, 59209], [31837, 59210], [31853, 59211], - [16913, 59212], [59213, 154547], [59214, 155324], [59215, 155302], - [31949, 59216], [59217, 150009], [59218, 137136], [31886, 59219], - [31868, 59220], [31918, 59221], [27314, 59222], [32220, 59223], - [32263, 59224], [32211, 59225], [32590, 59226], [59227, 156257], - [59228, 155996], [59229, 162632], [32151, 59230], [59231, 155266], - [17002, 59232], [59233, 158581], [59234, 133398], [26582, 59235], - [59236, 131150], [59237, 144847], [22468, 59238], [59239, 156690], - [59240, 156664], [32733, 59242], [31527, 59243], [59244, 133164], - [59245, 154345], [59246, 154947], [31500, 59247], [59248, 155150], - [39398, 59249], [34373, 59250], [39523, 59251], [27164, 59252], - [59253, 144447], [59255, 150007], [59256, 157101], [39455, 59257], - [59258, 157088], 0, [59260, 160039], [59261, 158929], [17642, 59262], - [33079, 59263], [17410, 59264], [32966, 59265], [33033, 59266], - [33090, 59267], [59268, 157620], [39107, 59269], [59270, 158274], - [33378, 59271], [33381, 59272], [59273, 158289], [33875, 59274], - [59275, 159143], [34320, 59276], [59277, 160283], [23174, 59278], - [16767, 59279], [59280, 137280], [23339, 59281], [59282, 137377], - [23268, 59283], [59284, 137432], [34464, 59285], [59286, 195004], - [59287, 146831], [34861, 59288], [59289, 160802], [23042, 59290], - [34926, 59291], [20293, 59292], [34951, 59293], [35007, 59294], - [35046, 59295], [35173, 59296], [35149, 59297], [59298, 153219], - [35156, 59299], [59300, 161669], [59301, 161668], [59302, 166901], - [59303, 166873], [59304, 166812], [59305, 166393], [16045, 59306], - [33955, 59307], [18165, 59308], [18127, 59309], [14322, 59310], - [35389, 59311], [35356, 59312], [59313, 169032], [24397, 59314], - [37419, 59315], [59316, 148100], [26068, 59317], [28969, 59318], - [28868, 59319], [59320, 137285], [40301, 59321], [35999, 59322], - [36073, 59323], [59324, 163292], [22938, 59325], [30659, 59326], - [23024, 59327], [14036, 59329], [36394, 59330], [36519, 59331], - [59332, 150537], [36656, 59333], [36682, 59334], [17140, 59335], - [27736, 59336], [28603, 59337], [59338, 140065], [18587, 59339], - [28537, 59340], [28299, 59341], [59342, 137178], [39913, 59343], - [14005, 59344], [59345, 149807], [37051, 59346], 0, [21873, 59348], - [18694, 59349], [37307, 59350], [37892, 59351], [59352, 166475], - [16482, 59353], [59354, 166652], [37927, 59355], [59356, 166941], - [59357, 166971], [34021, 59358], [35371, 59359], [38297, 59360], - [38311, 59361], [38295, 59362], [38294, 59363], [59364, 167220], - [29765, 59365], [16066, 59366], [59367, 149759], [59368, 150082], - [59369, 148458], [16103, 59370], [59371, 143909], [38543, 59372], - [59373, 167655], [59374, 167526], [59375, 167525], [16076, 59376], - [59377, 149997], [59378, 150136], [59379, 147438], [29714, 59380], - [29803, 59381], [16124, 59382], [38721, 59383], [59384, 168112], - [26695, 59385], [18973, 59386], [59387, 168083], [59388, 153567], 0, - [37736, 59390], [59391, 166281], [59392, 166950], [59393, 166703], - [59394, 156606], [37562, 59395], [23313, 59396], [35689, 59397], - [18748, 59398], [29689, 59399], [59400, 147995], [38811, 59401], 0, - [39224, 59403], [59404, 134950], [24001, 59405], [59406, 166853], - [59407, 150194], [38943, 59408], [59409, 169178], [37622, 59410], - [59411, 169431], [37349, 59412], [17600, 59413], [59414, 166736], - [59415, 150119], [59416, 166756], [39132, 59417], [59418, 166469], - [16128, 59419], [37418, 59420], [18725, 59421], [33812, 59422], - [39227, 59423], [39245, 59424], [59425, 162566], [15869, 59426], 0, - [19311, 59428], [39338, 59429], [39516, 59430], [59431, 166757], - [59432, 153800], [27279, 59433], [39457, 59434], [23294, 59435], - [39471, 59436], [59437, 170225], [19344, 59438], [59439, 170312], - [39356, 59440], [19389, 59441], [19351, 59442], [37757, 59443], - [22642, 59444], [59445, 135938], [22562, 59446], [59447, 149944], - [59448, 136424], [30788, 59449], [59450, 141087], [59451, 146872], - [26821, 59452], [15741, 59453], [37976, 59454], [14631, 59455], - [24912, 59456], [59457, 141185], [59458, 141675], [24839, 59459], - [40015, 59460], [40019, 59461], [40059, 59462], [39989, 59463], - [39952, 59464], [39807, 59465], [39887, 59466], [59467, 171565], - [39839, 59468], [59469, 172533], [59470, 172286], [40225, 59471], - [19630, 59472], [59473, 147716], [40472, 59474], [19632, 59475], - [40204, 59476], [59477, 172468], [59478, 172269], [59479, 172275], - [59480, 170287], [40357, 59481], [33981, 59482], [59483, 159250], - [59484, 159711], [59485, 158594], [34300, 59486], [17715, 59487], - [59488, 159140], [59489, 159364], [59490, 159216], [33824, 59491], - [34286, 59492], [59493, 159232], [59494, 145367], [59495, 155748], - [31202, 59496], [59497, 144796], [59498, 144960], [59500, 149982], - [15714, 59501], [37851, 59502], [37566, 59503], [37704, 59504], - [59505, 131775], [30905, 59506], [37495, 59507], [37965, 59508], - [20452, 59509], [13376, 59510], [36964, 59511], [59512, 152925], - [30781, 59513], [30804, 59514], [30902, 59515], [30795, 59516], - [59517, 137047], [59518, 143817], [59519, 149825], [13978, 59520], - [20338, 59521], [28634, 59522], [28633, 59523], 0, [28702, 59524, 59525], - [21524, 59526], [59527, 147893], [22459, 59528], [22771, 59529], - [22410, 59530], [40214, 59531], [22487, 59532], [28980, 59533], - [13487, 59534], [59535, 147884], [29163, 59536], [59537, 158784], - [59538, 151447], 0, [59540, 137141], [59541, 166473], [24844, 59542], - [23246, 59543], [23051, 59544], [17084, 59545], [59546, 148616], - [14124, 59547], [19323, 59548], [59549, 166396], [37819, 59550], - [37816, 59551], [59552, 137430], [59553, 134941], [33906, 59554], - [59555, 158912], [59556, 136211], [59557, 148218], [59558, 142374], - [59559, 148417], [22932, 59560], [59561, 146871], [59562, 157505], - [32168, 59563], [59564, 155995], [59565, 155812], [59566, 149945], - [59567, 149899], [59568, 166394], [37605, 59569], [29666, 59570], - [16105, 59571], [29876, 59572], [59573, 166755], [59574, 137375], - [16097, 59575], [59576, 150195], [27352, 59577], [29683, 59578], - [29691, 59579], [16086, 59580], [59581, 150078], [59582, 150164], - [59583, 137177], [59584, 150118], [59585, 132007], [59586, 136228], - [59587, 149989], [29768, 59588], [59589, 149782], [28837, 59590], - [59591, 149878], [37508, 59592], [29670, 59593], [37727, 59594], - [59595, 132350], [37681, 59596], [59597, 166606], [59598, 166422], - [37766, 59599], [59600, 166887], [59601, 153045], [18741, 59602], - [59603, 166530], [29035, 59604], [59605, 149827], [59606, 134399], - [22180, 59607], [59608, 132634], [59609, 134123], [59610, 134328], - [21762, 59611], [31172, 59612], [59613, 137210], [32254, 59614], - [59615, 136898], [59616, 150096], [59617, 137298], [17710, 59618], - [37889, 59619], [14090, 59620], [59621, 166592], [59622, 149933], - [22960, 59623], [59624, 137407], [59625, 137347], [59626, 160900], - [23201, 59627], [14050, 59628], [59629, 146779], [14000, 59630], - [37471, 59631], [23161, 59632], [59633, 166529], [59634, 137314], - [37748, 59635], [15565, 59636], [59637, 133812], [19094, 59638], - [14730, 59639], [20724, 59640], [15721, 59641], [15692, 59642], - [59643, 136092], [29045, 59644], [17147, 59645], [59646, 164376], - [28175, 59647], [59648, 168164], [17643, 59649], [27991, 59650], - [59651, 163407], [28775, 59652], [27823, 59653], [15574, 59654], - [59655, 147437], [59656, 146989], [28162, 59657], [28428, 59658], - [15727, 59659], [59660, 132085], [30033, 59661], [14012, 59662], - [13512, 59663], [18048, 59664], [16090, 59665], [18545, 59666], - [22980, 59667], [37486, 59668], [18750, 59669], [36673, 59670], - [59671, 166940], [59672, 158656], [22546, 59673], [22472, 59674], - [14038, 59675], [59676, 136274], [28926, 59677], [59678, 148322], - [59679, 150129], [59680, 143331], [59681, 135856], [59682, 140221], - [26809, 59683], [26983, 59684], [59685, 136088], [59686, 144613], - [59687, 162804], [59688, 145119], [59689, 166531], [59690, 145366], - [59691, 144378], [59692, 150687], [27162, 59693], [59694, 145069], - [59695, 158903], [33854, 59696], [17631, 59697], [17614, 59698], - [59699, 159014], [59700, 159057], [59701, 158850], [59702, 159710], 0, 0, - [33597, 59705], [59706, 137018], [33773, 59707], [59708, 158848], - [59709, 159827], [59710, 137179], [22921, 59711], [23170, 59712], - [59713, 137139], [23137, 59714], [23153, 59715], [59716, 137477], - [59717, 147964], [14125, 59718], [23023, 59719], [59720, 137020], - [14023, 59721], [29070, 59722], [37776, 59723], [26266, 59724], - [59725, 148133], [23150, 59726], [23083, 59727], [59728, 148115], - [27179, 59729], [59730, 147193], [59731, 161590], [59732, 148571], - [59733, 148170], [28957, 59734], [59735, 148057], [59736, 166369], - [20400, 59737], [59738, 159016], [23746, 59739], [59740, 148686], - [59741, 163405], [59742, 148413], [27148, 59743], [59744, 148054], - [59745, 135940], 0, [28979, 59747], [59748, 148457], [15781, 59749], - [27871, 59750], [59751, 194597], [23019, 59754], [24412, 59757], - [59764, 144128], [31955, 59776], [59783, 162548], [59786, 153334], - [59790, 162584], [36972, 59791], [33270, 59795], [30476, 59797], - [27810, 59799], [22269, 59800], [22633, 59828], [26465, 59832], - [23646, 59838], [22770, 59841], [28857, 59843], [26627, 59853], - [36795, 59859], [36796, 59861], [20001, 59871], [31545, 59898], - [15820, 59902], [29482, 57990, 59909], [30048, 59912], [22586, 59920], - [33446, 59932], [27018, 59940], [24803, 59944], [20206, 59984], - [39364, 60002], [40639, 60023], [21249, 60025], [26528, 60038], - [24808, 60046], [20916, 60053], [31363, 60064], [39994, 60075], - [31432, 60093], [26906, 60098], [22956, 60100], [22592, 60102], - [21610, 60114], [24807, 60123], [22138, 60125], [26965, 60132], - [39983, 60133], [34725, 60134], [23584, 60141], [24075, 60143], - [26398, 60147], [33965, 60157], [35713, 60161], [20088, 60166], - [25283, 60176], [26709, 60180], 0, [33533, 60190], [35237, 60194], - [36768, 60196], [38840, 60198], [38983, 60200], [39613, 60201], - [24497, 60218], [26184, 60219], [26303, 60220], [60221, 162425], 0, - [60225, 149946], 0, 0, [60230, 131910], [26382, 60232], [26904, 60233], - [60235, 161367], [60236, 155618], [60239, 161278], [60240, 139418], - [18640, 60241], [19128, 60242], [60244, 166554], [60247, 147515], - [60250, 150085], [60251, 132554], [20946, 60252], [60253, 132625], - [22943, 60254], [60255, 138920], [15294, 60256], [60257, 146687], - [14747, 60262], [60264, 165352], [60265, 170441], [14178, 60266], - [60267, 139715], [35678, 60268], [60269, 166734], 0, [29193, 60274], - [60276, 134264], [60280, 132985], [36570, 60281], [21135, 60283], - [29041, 60285], [60288, 147274], [60289, 150183], [21948, 60290], - [60293, 158546], [13427, 60295], [60297, 161330], [18200, 60299], - [60303, 149823], [20582, 60305], [13563, 60306], [60307, 144332], 0, - [18300, 60310], [60311, 166216], [60315, 138640], 0, [60320, 162834], - [36950, 60321], [60323, 151450], [35682, 60324], [23899, 60327], - [60328, 158711], 0, [60331, 137500], [35562, 60332], [60333, 150006], - [60335, 147439], [19392, 60337], [60340, 141083], [37989, 60341], - [60342, 153569], [24981, 60343], [23079, 60344], [60345, 194765], 0, - [60348, 148769], [20074, 60350], [60351, 149812], [38486, 60352], - [28047, 60353], [60354, 158909], [35191, 60356], [60359, 156689], 0, - [31554, 60363], [60364, 168128], [60365, 133649], 0, [31301, 60369], - [39462, 60372], [13919, 60374], [60375, 156777], [60376, 131105], - [31107, 60377], [23852, 60380], [60381, 144665], 0, [18128, 60384], - [30011, 60386], [34917, 60387], [22710, 60389], [14108, 60390], - [60391, 140685], [15444, 60394], [37505, 60397], [60398, 139642], - [37680, 60400], [60402, 149968], [27705, 60403], [60406, 134904], - [34855, 60407], [35061, 60408], [60409, 141606], [60410, 164979], - [60411, 137137], [28344, 60412], [60413, 150058], [60414, 137248], - [14756, 60415], 0, 0, [17727, 60419], [26294, 60420], [60421, 171181], - [60422, 170148], [35139, 60423], [16607, 60427], [60428, 136714], - [14753, 60429], [60430, 145199], [60431, 164072], [60432, 136133], - [29101, 60433], [33638, 60434], [60436, 168360], 0, [19639, 60438], - [60439, 159919], [60440, 166315], [60445, 147834], [31555, 60446], - [31102, 60447], [28597, 60449], [60450, 172767], [27139, 60451], - [60452, 164632], [21410, 60453], [60454, 159239], [37823, 60455], - [26678, 60456], [38749, 59389, 60457], [60458, 164207], [60460, 158133], - [60461, 136173], [60462, 143919], [23941, 60464], [60465, 166960], - [22293, 60467], [38947, 60468], [60469, 166217], [23979, 60470], - [60471, 149896], [26046, 60472], [27093, 60473], [21458, 60474], - [60475, 150181], [60476, 147329], [15377, 60477], [26422, 60478], - [60482, 139169], [13770, 60490], [18682, 60493], 0, [30728, 60496], - [37461, 60497], [17394, 60499], [17375, 60501], [23032, 60505], 0, - [22155, 60518], [60520, 169449], [36882, 60541], [21953, 60546], - [17673, 60551], [32383, 60552], [28502, 60553], [27313, 60554], - [13540, 60556], [60558, 161949], [14138, 60559], 0, [60562, 163876], - [60565, 162366], [15851, 60567], [60569, 146615], [60574, 156248], - [22207, 60575], [36366, 60577], [23405, 60578], [25566, 60581], 0, - [25904, 60585], [22061, 60586], [21530, 60588], [60591, 171416], - [19581, 60592], [22050, 60593], [22046, 60594], [32585, 60595], - [22901, 60597], [60598, 146752], [34672, 60599], [33047, 60604], - [40286, 60605], [36120, 60606], [30267, 60607], [40005, 60608], - [30286, 60609], [30649, 60610], [37701, 60611], [21554, 60612], - [33096, 60613], [33527, 60614], [22053, 60615], [33074, 60616], - [33816, 60617], [32957, 60618], [21994, 60619], [31074, 60620], - [22083, 60621], [21526, 60622], [60623, 134813], [13774, 60624], - [22021, 57509, 60625], [22001, 60626], [26353, 60627], [60628, 164578], - [13869, 60629], [30004, 60630], [22000, 60631], [21946, 60632], - [21655, 60633], [21874, 60634], [60635, 134209], [60636, 134294], - [24272, 57652, 60637], [60639, 134774], [60640, 142434], [60641, 134818], - [40619, 60642], [32090, 60643], 0, [60645, 135285], [25245, 60646], - [38765, 60647], [21652, 60648], [36045, 60649], [29174, 60650], - [37238, 60651], [25596, 60652], [25529, 60653], [25598, 60654], - [21865, 60655], [60656, 142147], [40050, 60657], [60658, 143027], - [20890, 60659], [13535, 60660], [60661, 134567], [20903, 60662], - [21581, 60663], [21790, 60664], [21779, 60665], [30310, 60666], - [36397, 60667], [60668, 157834], [30129, 60669], [32950, 60670], - [34820, 60671], 0, [35015, 60673], [33206, 60674], [33820, 60675], - [17644, 60677], [29444, 60678], [33547, 60681], [22139, 60683], - [37232, 60690], [37384, 60692], [60696, 134905], [29286, 60697], - [18254, 60699], [60701, 163833], [16634, 60703], [40029, 60704], - [25887, 60705], [18675, 60707], [60708, 149472], [60709, 171388], 0, - [60713, 161187], 60715, [60716, 155720], [29091, 60718], [32398, 60719], - [40272, 60720], [13687, 60723], [27826, 60725], [21351, 60726], - [14812, 60728], [60731, 149016], [33325, 60734], [21579, 60735], 60739, - [14930, 60740], [29556, 60742], [60743, 171692], [19721, 60744], - [39917, 60745], 0, [19547, 60748], [60751, 171998], [33884, 60752], - [60754, 160434], [25390, 60757], [32037, 60758], [14890, 60761], - [36872, 60762], [21196, 60763], [15988, 60764], [13946, 60765], - [17897, 60766], [60767, 132238], [30272, 60768], [23280, 60769], - [60770, 134838], [30842, 60771], [18358, 60772], [22695, 60773], - [16575, 60774], [22140, 60775], [39819, 60776], [23924, 60777], - [30292, 60778], [60779, 173108], [40581, 60780], [19681, 60781], 0, - [14331, 60783], [24857, 60784], [60786, 148466], 60787, [22109, 60788], - [60792, 171526], [21044, 60793], [13741, 60795], 0, [40316, 60797], - [31830, 60798], [39737, 60799], [22494, 60800], [23635, 60802], - [25811, 60803], [60804, 169168], [60805, 156469], [34477, 60807], - [60808, 134440], [60811, 134513], 60812, [20990, 60813], [60814, 139023], - [23950, 60815], [38659, 60816], [60817, 138705], [40577, 60818], - [36940, 60819], [31519, 60820], [39682, 60821], [23761, 60822], - [31651, 60823], [25192, 60824], [25397, 60825], [39679, 60826], - [31695, 60827], [39722, 60828], [31870, 60829], 0, [31810, 60831], - [31878, 60832], [39957, 60833], [31740, 60834], [39689, 60835], 0, 39982, - [40794, 60839], [21875, 60840], [23491, 60841], [20477, 60842], - [40600, 60843], [20466, 60844], [21088, 60845], [21201, 60847], - [22375, 60848], [20566, 60849], [22967, 60850], [24082, 60851], - [38856, 60852], [40363, 60853], [36700, 60854], [21609, 60855], - [38836, 60856], [39232, 60857], [38842, 60858], [21292, 60859], - [24880, 60860], [26924, 60861], [21466, 60862], [39946, 60863], - [40194, 60864], [19515, 60865], [38465, 60866], [27008, 60867], - [20646, 60868], [30022, 60869], [60870, 137069], [39386, 60871], - [21107, 60872], 60873, [37209, 60874], [38529, 60875], [37212, 60876], - 60877, [37201, 60878], [60879, 167575], [25471, 60880], [27338, 60882], - [22033, 60883], [37262, 60884], [30074, 60885], [25221, 60886], - [29519, 60888], [31856, 60889], [60890, 154657], 60892, [30422, 60894], - [39837, 60895], [20010, 60896], [60897, 134356], [33726, 60898], - [34882, 60899], 60900, [23626, 60901], [27072, 60902], 0, 0, - [21023, 60905], [24053, 60906], [20174, 60907], [27697, 60908], - [60909, 131570], [20281, 60910], [21660, 60911], 0, [21146, 60913], - [36226, 60914], [13822, 60915], 0, [13811, 60917], 60918, [27474, 60919], - [37244, 60920], [40869, 60921], [39831, 60922], [38958, 60923], - [39092, 60924], [39610, 60925], [40616, 60926], [40580, 60927], - [31508, 60929], 60930, [27642, 60931], [34840, 60932], [32632, 60933], - 60934, [22048, 60935], [60936, 173642], [36471, 60937], [40787, 60938], - 60939, [36308, 60940], [36431, 60941], [40476, 60942], [36353, 60943], - [25218, 60944], [60945, 164733], [36392, 60946], [36469, 60947], - [31443, 60948], [31294, 60950], [30936, 60951], [27882, 60952], - [35431, 60953], [30215, 60954], [40742, 60956], [27854, 60957], - [34774, 60958], [30147, 60959], [60960, 172722], [30803, 60961], - [36108, 60963], [29410, 60964], [29553, 60965], [35629, 60966], - [29442, 60967], [29937, 60968], [36075, 60969], [60970, 150203], - [34351, 60971], [24506, 60972], [34976, 60973], [17591, 60974], 60975, - [60977, 159237], 60978, [35454, 60979], [60980, 140571], 60981, - [24829, 60982], [30311, 60983], [39639, 60984], [40260, 60985], - [37742, 58859, 60986], [39823, 60987], [34805, 60988], 60989, 0, - [36087, 60991], [29484, 60992], [38689, 60993], [39856, 60994], - [13782, 60995], [29362, 60996], [19463, 60997], [31825, 60998], - [39242, 60999], [24921, 61001], [19460, 61002], [40598, 61003], - [24957, 61004], 61005, [22367, 61006], [24943, 61007], [25254, 61008], - [25145, 61009], 0, [14940, 61011], [25058, 61012], [21418, 61013], - [25444, 61015], [26626, 61016], [13778, 61017], [23895, 61018], - [36826, 61020], [61021, 167481], 61022, [20697, 61023], [30982, 61025], - [21298, 61026], [38456, 61027], [61028, 134971], [16485, 61029], 61030, - [30718, 61031], 61032, [31938, 61033], [61034, 155418], [31962, 61035], - [31277, 61036], [32870, 61037], [32867, 61038], [32077, 61039], - [29957, 61040], [29938, 61041], [35220, 61042], [33306, 61043], - [26380, 61044], [32866, 61045], [61046, 160902], [32859, 61047], - [29936, 61048], [33027, 61049], [30500, 61050], [35209, 61051], - [61052, 157644], [30035, 61053], [34729, 61055], [34766, 61056], - [33224, 61057], [34700, 61058], [35401, 61059], [36013, 61060], - [35651, 61061], [30507, 61062], [29944, 61063], [34010, 61064], - [27058, 61066], [36262, 61067], 61068, [35241, 58392, 61069], 0, - [28089, 61071], [34753, 61072], [61073, 147473], [29927, 61074], - [15835, 61075], [29046, 61076], [24740, 57702, 61077], [24988, 61078], - [15569, 61079], 0, [24695, 61081], 61082, [32625, 61083], 0, - [24809, 61086], [19326, 61087], [57344, 132423], [37595, 57345], - [57346, 132575], [57347, 147397], [34124, 57348], [17077, 57349], - [29679, 57350], [20917, 57351], [13897, 57352], [57353, 149826], - [57354, 166372], [37700, 57355], [57356, 137691], [33518, 57357], - [57358, 146632], [30780, 57359], [26436, 57360], [25311, 57361], - [57362, 149811], [57363, 166314], [57364, 131744], [57365, 158643], - [57366, 135941], [20395, 57367], [57368, 140525], [20488, 57369], - [57370, 159017], [57371, 162436], [57372, 144896], [57373, 150193], - [57374, 140563], 0, [57376, 131966], [24484, 57377], [57378, 131968], - [57379, 131911], [28379, 57380], [57381, 132127], 20702, [20737, 57383], - [13434, 57384], [20750, 57385], [39020, 57386], [14147, 57387], - [33814, 57388], [57389, 149924], [57390, 132231], [20832, 57391], - [57392, 144308], [20842, 57393], [57394, 134143], [57395, 139516], - [57396, 131813], [57397, 140592], [57398, 132494], [57399, 143923], - [57400, 137603], [23426, 57401], [34685, 57402], [57403, 132531], - [57404, 146585], [20914, 57405], [20920, 57406], [40244, 57407], - [20937, 57408], [20943, 57409], [20945, 57410], [15580, 57411], - [20947, 57412], [57413, 150182], [20915, 57414], 0, 0, [20973, 57417], - [33741, 57418], [26942, 57419], [57420, 145197], [24443, 57421], - [21003, 57422], [21030, 57423], [21052, 57424], [21173, 57425], - [21079, 57426], [21140, 57427], [21177, 57428], [21189, 57429], - [31765, 57430], [34114, 57431], [21216, 57432], [34317, 57433], - [57434, 158483], 0, [57436, 166622], [21833, 57437], [28377, 57438], - [57439, 147328], [57440, 133460], [57441, 147436], [21299, 57442], 0, - [57444, 134114], [27851, 57445], [57446, 136998], [26651, 57447], - [29653, 57448], [24650, 57449], [16042, 57450], [14540, 57451], - [57452, 136936], [29149, 57453], [17570, 57454], [21357, 57455], - [21364, 57456], [57457, 165547], [21374, 57458], 0, [57460, 136598], - [57461, 136723], [30694, 57462], [21395, 57463], [57464, 166555], - [21408, 57465], [21419, 57466], [21422, 57467], [29607, 57468], - [57469, 153458], [16217, 57470], [29596, 57471], [21441, 57472], - [21445, 57473], [27721, 57474], [20041, 57475], [22526, 57476], - [21465, 57477], [15019, 57478], [57479, 134031], [21472, 57480], - [57481, 147435], [57482, 142755], [21494, 57483], [57484, 134263], - [21523, 57485], [28793, 57486], [21803, 57487], [26199, 57488], - [27995, 57489], [21613, 57490], [57491, 158547], [57492, 134516], - [21853, 57493], [21647, 57494], [21668, 57495], [18342, 57496], - [57497, 136973], [57498, 134877], [15796, 57499], [57500, 134477], - [57501, 166332], [57502, 140952], [21831, 57503], [19693, 57504], - [21551, 57505], [29719, 57506], [21894, 57507], [21929, 57508], 0, - [57510, 137431], [57511, 147514], [17746, 57512], [57513, 148533], - [26291, 57514], [57515, 135348], [22071, 57516], [26317, 57517], - [57518, 144010], [26276, 57519], 0, [22093, 57521], [22095, 57522], - [30961, 57523], [22257, 57524], [38791, 57525], [21502, 57526], - [22272, 57527], [22255, 57528], [22253, 57529], [57530, 166758], - [13859, 57531], [57532, 135759], [22342, 57533], [57534, 147877], - [27758, 57535], [28811, 57536], [22338, 57537], [14001, 57538], - [57539, 158846], [22502, 57540], [57541, 136214], [22531, 57542], - [57543, 136276], [57544, 148323], [22566, 57545], [57546, 150517], 0, - [22698, 57548], [13665, 57549], [22752, 57550], [22748, 57551], - [57552, 135740], [22779, 57553], [23551, 57554], [22339, 57555], - [57556, 172368], [57557, 148088], [37843, 57558], [13729, 57559], - [22815, 57560], [26790, 57561], [14019, 57562], [28249, 57563], - [57564, 136766], [23076, 57565], 0, [57567, 136850], [34053, 57568], - [22985, 57569], [57570, 134478], [57571, 158849], [57572, 159018], - [57573, 137180], [23001, 57574], [57575, 137211], [57576, 137138], - [57577, 159142], [28017, 57578], [57579, 137256], [57580, 136917], - [23033, 57581], [57582, 159301], [23211, 57583], [23139, 57584], - [14054, 57585], [57586, 149929], 0, [14088, 57588], [23190, 57589], - [29797, 57590], [23251, 57591], [57592, 159649], [57593, 140628], - [57595, 137489], [14130, 57596], [57597, 136888], [24195, 57598], - [21200, 57599], [23414, 57600], [25992, 57601], [23420, 57602], - [57603, 162318], [16388, 57604], [18525, 57605], [57606, 131588], - [23509, 57607], [57609, 137780], [57610, 154060], [57611, 132517], - [23539, 57612], [23453, 57613], [19728, 57614], [23557, 57615], - [57616, 138052], [23571, 57617], [29646, 57618], [23572, 57619], - [57620, 138405], [57621, 158504], [23625, 57622], [18653, 57623], - [23685, 57624], [23785, 57625], [23791, 57626], [23947, 57627], - [57628, 138745], [57629, 138807], [23824, 57630], [23832, 57631], - [23878, 57632], [57633, 138916], [23738, 57634], [24023, 57635], - [33532, 57636], [14381, 57637], [57638, 149761], [57639, 139337], - [57640, 139635], [33415, 57641], [14390, 57642], [15298, 57643], - [24110, 57644], [27274, 57645], 0, 57647, [57648, 148668], [57649, 134355], - [21414, 57650], [20151, 57651], 0, [21416, 57653], [57654, 137073], - [24073, 57655], 57656, [57657, 164994], [24313, 57658], [24315, 57659], - [14496, 57660], [24316, 57661], [26686, 57662], [37915, 57663], - [24333, 57664], [57665, 131521], [57666, 194708], [15070, 57667], - [57669, 135994], [24378, 57670], [57671, 157832], [57672, 140240], - [57674, 140401], [24419, 57675], [57677, 159342], [24434, 57678], - [37696, 57679], [57680, 166454], [24487, 57681], [23990, 57682], - [15711, 57683], [57684, 152144], [57685, 139114], [57686, 159992], - [57687, 140904], [37334, 57688], [57689, 131742], [57690, 166441], - [24625, 57691], [26245, 57692], [14691, 57694], [15815, 57695], - [13881, 57696], [22416, 57697], [57698, 141236], [31089, 57699], - [15936, 57700], [24734, 57701], 0, 0, [57704, 149890], [57705, 149903], - [57706, 162387], [29860, 57707], [20705, 57708], [23200, 57709], - [24932, 57710], [24898, 57712], [57713, 194726], [57714, 159442], - [24961, 57715], [20980, 57716], [57717, 132694], [24967, 57718], - [23466, 57719], [57720, 147383], [57721, 141407], [25043, 57722], - [57723, 166813], [57724, 170333], [25040, 57725], [14642, 57726], - [57727, 141696], [57728, 141505], [24611, 57729], [24924, 57730], - [25886, 57731], [25483, 57732], [57733, 131352], [25285, 57734], - [57735, 137072], [25301, 57736], [57737, 142861], [25452, 57738], - [57739, 149983], [14871, 57740], [25656, 57741], [25592, 57742], - [57743, 136078], [57744, 137212], [28554, 57746], [57747, 142902], 0, - [57750, 153373], [25825, 57751], [25829, 57752], [38011, 57753], - [14950, 57754], [25658, 57755], [14935, 57756], [25933, 57757], - [28438, 57758], [57759, 150056], [57760, 150051], [25989, 57761], - [25965, 57762], [25951, 57763], 0, [26037, 57765], [57766, 149824], - [19255, 57767], [26065, 57768], [16600, 57769], [57770, 137257], 57771, - [26083, 57772], [24543, 57773], [57774, 144384], [26136, 57775], - [57776, 143863], [57777, 143864], [26180, 57778], [57779, 143780], - [57780, 143781], [26187, 57781], [57782, 134773], [26215, 57783], - [57784, 152038], [26227, 57785], 0, [57788, 143921], [57789, 165364], - [57790, 143816], [57791, 152339], [30661, 57792], [57793, 141559], - [39332, 57794], [26370, 57795], [57796, 148380], [57797, 150049], - [27130, 57799], [57800, 145346], 0, [26471, 57802], [26466, 57803], - [57804, 147917], [57805, 168173], [26583, 57806], [17641, 57807], - [26658, 57808], [28240, 57809], [37436, 57810], [26625, 57811], - [57812, 144358], [57813, 159136], [26717, 57814], [57815, 144495], - [27105, 57816], [27147, 57817], [57818, 166623], [26995, 57819], - [26819, 57820], [57821, 144845], [26881, 57822], [26880, 57823], - [14849, 57825], [57826, 144956], [15232, 57827], [26540, 57828], - [26977, 57829], [57830, 166474], [17148, 57831], [26934, 57832], - [27032, 57833], [15265, 57834], [57835, 132041], [33635, 57836], - [20624, 57837], [27129, 57838], [57839, 144985], [57840, 139562], - [27205, 57841], [57842, 145155], [27293, 57843], [15347, 57844], - [26545, 57845], [27336, 57846], [57847, 168348], [15373, 57848], - [27421, 57849], [57850, 133411], [24798, 57851, 60308], [27445, 57852], - [27508, 57853], [57854, 141261], [28341, 57855], [57856, 146139], 0, - [57858, 137560], [14144, 57859], [21537, 57860], [57861, 146266], - [27617, 57862], [57863, 147196], [27612, 57864], [27703, 57865], - [57866, 140427], [57867, 149745], [57868, 158545], [27738, 57869], - [33318, 57870], [27769, 57871], [57872, 146876], [17605, 57873], - [57874, 146877], [57875, 147876], [57876, 149772], [57877, 149760], - [57878, 146633], [14053, 57879], [15595, 57880], [57881, 134450], - [39811, 57882], [57883, 143865], [57884, 140433], [32655, 57885], - [26679, 57886], [57887, 159013], [57888, 159137], [57889, 159211], - [28054, 57890], [27996, 57891], [28284, 57892], [28420, 57893], - [57894, 149887], [57895, 147589], [57896, 159346], [34099, 57897], - [57898, 159604], [20935, 57899], 0, 0, [33838, 57902], [57903, 166689], 0, - [57905, 146991], [29779, 57906], [57907, 147330], [31180, 57908], - [28239, 57909], [23185, 57910], [57911, 143435], [28664, 57912], - [14093, 57913], [28573, 57914], [57915, 146992], [28410, 57916], - [57917, 136343], [57918, 147517], [17749, 57919], [37872, 57920], - [28484, 57921], [28508, 57922], [15694, 57923], [28532, 57924], - [57925, 168304], [15675, 57926], [28575, 57927], [57928, 147780], - [28627, 57929], [57930, 147601], [57931, 147797], [57932, 147513], - [57933, 147440], [57934, 147380], [57935, 147775], [20959, 57936], - [57937, 147798], [57938, 147799], [57939, 147776], [57940, 156125], - [28747, 57941], [28798, 57942], [28839, 57943], 0, [28876, 57945], - [28885, 57946], [28886, 57947], [28895, 57948], [16644, 57949], - [15848, 57950], [29108, 57951], [29078, 57952], [57953, 148087], - [28971, 57954], [28997, 57955], [23176, 57956], [29002, 57957], 0, - [57960, 148325], [29007, 57961], [37730, 57962], [57963, 148161], - [28972, 57964], [57965, 148570], [57966, 150055], [57967, 150050], - [29114, 57968], [57969, 166888], [28861, 57970], [29198, 57971], - [37954, 57972], [29205, 57973], [22801, 57974], [37955, 57975], - [29220, 57976], [37697, 57977], [57978, 153093], [29230, 57979], - [29248, 57980], [57981, 149876], [26813, 57982], [29269, 57983], - [29271, 57984], [15957, 57985], [57986, 143428], [26637, 57987], - [28477, 57988], [29314, 57989], 0, [29483, 57991], [57992, 149539], - [57993, 165931], [18669, 57994], [57995, 165892], [29480, 57996], - [29486, 57997], [29647, 57998], [29610, 57999], [58000, 134202], - [58001, 158254], [29641, 58002], [29769, 58003], [58004, 147938], - [58005, 136935], [58006, 150052], [26147, 58007], [14021, 58008], - [58009, 149943], [58010, 149901], [58011, 150011], [29687, 58012], - [29717, 58013], [26883, 58014], [58015, 150054], [29753, 58016], - [16087, 58018], 0, [58020, 141485], [29792, 58021], [58022, 167602], - [29767, 58023], [29668, 58024], [29814, 58025], [33721, 58026], - [29804, 58027], [29812, 58029], [37873, 58030], [27180, 58031], - [29826, 58032], [18771, 58033], [58034, 150156], [58035, 147807], - [58036, 150137], [58037, 166799], [23366, 58038], [58039, 166915], - [58040, 137374], [29896, 58041], [58042, 137608], [29966, 58043], - [29982, 58045], [58046, 167641], [58047, 137803], [23511, 58048], - [58049, 167596], [37765, 58050], [30029, 58051], [30026, 58052], - [30055, 58053], [30062, 58054], [58055, 151426], [16132, 58056], - [58057, 150803], [30094, 58058], [29789, 58059], [30110, 58060], - [30132, 58061], [30210, 58062], [30252, 58063], [30289, 58064], - [30287, 58065], [30319, 58066], 58067, [58068, 156661], [30352, 58069], - [33263, 58070], [14328, 58071], [58072, 157969], [58073, 157966], - [30369, 58074], [30373, 58075], [30391, 58076], [30412, 58077], - [58078, 159647], [33890, 58079], [58080, 151709], [58081, 151933], - [58082, 138780], [30494, 58083], [30502, 58084], [30528, 58085], - [25775, 58086], [58087, 152096], [30552, 58088], [58089, 144044], - [30639, 58090], [58091, 166244], [58092, 166248], [58093, 136897], - [30708, 58094], 0, [26826, 58098], [30895, 58099], [30919, 58100], - [30931, 58101], [38565, 58102], [31022, 58103], [58104, 153056], - [30935, 58105], [31028, 58106], [30897, 58107], [58108, 161292], - [36792, 58109], [34948, 58110], [58113, 140828], [31110, 58114], - [35072, 58115], [26882, 58116], [31104, 58117], [58118, 153687], - [31133, 58119], [58120, 162617], [31036, 58121], [31145, 58122], - [28202, 58123], [58124, 160038], [16040, 58125], [31174, 58126], - [58127, 168205], [31188, 58128], 0, [21797, 62526], 0, [62528, 134210], - [62529, 134421], [62530, 151851], [21904, 62531], [62532, 142534], - [14828, 62533], [62534, 131905], [36422, 62535], [62536, 150968], - [62537, 169189], 0, [62539, 164030], [30586, 62540], [62541, 142392], - [14900, 62542], [18389, 62543], [62544, 164189], [62545, 158194], - [62546, 151018], [25821, 62547], [62548, 134524], [62549, 135092], - [62550, 134357], 0, [25741, 62552], [36478, 62553], [62554, 134806], 0, - [62556, 135012], [62557, 142505], [62558, 164438], [62559, 148691], 0, - [62561, 134470], [62562, 170573], [62563, 164073], [18420, 62564], - [62565, 151207], [62566, 142530], [39602, 62567], [14951, 62568], - [62569, 169460], [16365, 62570], [13574, 62571], [62572, 152263], - [62573, 169940], 0, [62575, 142660], [40302, 62576], [38933, 62577], 0, - [17369, 62579], 0, [25780, 62581], [21731, 62582], 0, [62584, 142282], 0, - [14843, 62586], 0, [62588, 157402], [62589, 157462], [62590, 162208], - [25834, 62591], [62592, 151634], [62593, 134211], [36456, 62594], 0, - [62596, 166732], [62597, 132913], 0, [18443, 62599], [62600, 131497], - [16378, 62601], [22643, 62602], [62603, 142733], 0, [62605, 148936], - [62606, 132348], [62607, 155799], [62608, 134988], 0, [21881, 62610], 0, - [17338, 62612], 0, [19124, 62614], [62615, 141926], [62616, 135325], - [33194, 62617], [39157, 62618], [62619, 134556], [25465, 62620], - [14846, 62621], [62622, 141173], [36288, 62623], [22177, 62624], - [25724, 62625], [15939, 62626], 0, [62628, 173569], [62629, 134665], - [62630, 142031], 0, 0, [62633, 135368], [62634, 145858], [14738, 62635], - [14854, 62636], [62637, 164507], [13688, 62638], [62639, 155209], - [62640, 139463], 0, 0, [62643, 142514], [62644, 169760], [13500, 62645], - [27709, 62646], [62647, 151099], 0, 0, [62650, 161140], [62651, 142987], - [62652, 139784], [62653, 173659], [62654, 167117], [62655, 134778], - [62656, 134196], [62683, 161337], [62684, 142286], [62687, 142417], - [14872, 62689], [62691, 135367], [62693, 173618], [62695, 167122], - [62696, 167321], [62697, 167114], [38314, 62698], 0, [62706, 161630], - [28992, 62708], 0, [20822, 62385], 0, [20616, 62487], 0, [13459, 62489], - [20870, 62491], [24130, 63037], [20997, 62495], [21031, 62436], - [21113, 62497], 0, [13651, 62504], [21442, 62505], [21343, 62715], 0, - [21823, 62520], 0, [21976, 59986], [13789, 62722], [22049, 63067], 0, - [22100, 60044], [60148, 135291], 0, [60153, 135379], 0, [61095, 135934], 0, - 0, [14265, 60104], [23745, 61099], [23829, 63066], [23894, 63030], - [14392, 63036], [20097, 62477], [24253, 63038], [14612, 63042], - [25017, 63050], [25232, 63054], [25368, 63056], [25690, 63063], - [25745, 62381], [33133, 62709], [33156, 59922], [33171, 59924], - [26624, 63080], [15292, 63093], [29327, 60517], [29389, 59781], 0, - [29497, 59785], [30018, 59811], [30172, 59817], [16320, 59818], - [60278, 151205], [16343, 59820], 0, 30336, [30348, 59824, 151388], - [16552, 59845], [30777, 59846], [16643, 59855], [31377, 59863], - [31771, 59876], [31981, 59884], [32659, 62658], [32686, 59892], 0, - [33535, 59936], [22623, 59981], [34482, 59960], 0, [34699, 59963], - [35143, 59969], 0, [35369, 59972], 0, [36465, 59988], [60484, 164233], - [36528, 59990], 0, [37214, 62443], [37260, 62441], [39182, 60051], - [39196, 60054], 0, 0, [39809, 60066], [40384, 60080], [40339, 60078], - [40620, 60085], [19857, 60540], 0, 37818, [40571, 60084], [28809, 63148], - [29512, 59788], 0, [31129, 59858], [36791, 59997], 0, [39234, 60056], - {s: 193}, 8364, {s: 4}, [12443, 63518], [12444, 63519], [11904, 63520], - {f: 5, c: 62211}, [62216, 131340], 62217, [62218, 131281], [62219, 131277], - {f: 2, c: 62220}, [62222, 131275], [62223, 139240], 62224, [62225, 131274], - {f: 4, c: 62226}, [62230, 131342], {f: 2, c: 62231}, {f: 2, c: 62776}, - [62778, 138177], [62779, 194680], [12205, 38737, 62780], [62781, 131206], - [20059, 62782], [20155, 62783], [13630, 62784], [23587, 62785], - [24401, 62786], [24516, 62787], [14586, 62788], [25164, 62789], - [25909, 62790], [27514, 62791], [27701, 62792], [27706, 62793], - [28780, 62794], [29227, 62795], [20012, 62796], [29357, 62797], - [62798, 149737], [32594, 62799], [31035, 62800], [31993, 62801], - [32595, 62802], [62803, 156266], [13505, 62804], [62806, 156491], - [32770, 62807], [32896, 62808], [62809, 157202], [62810, 158033], - [21341, 62811], [34916, 62812], [35265, 62813], [62814, 161970], - [35744, 62815], [36125, 62816], [38021, 62817], [38264, 62818], - [38271, 62819], [38376, 62820], [62821, 167439], [38886, 62822], - [39029, 62823], [39118, 62824], [39134, 62825], [39267, 62826], - [62827, 170000], [40060, 62828], [40479, 62829], [40644, 62830], - [27503, 62831], [62832, 63751], [20023, 62833], [62834, 131207], - [38429, 62835], [25143, 62836], [38050, 62837], [11908, 63521], - [11910, 63522], [11911, 63523], [11912, 63524], [11914, 63525], - [11916, 63526], [11917, 63527], [11925, 63528], [11932, 63529], - [11941, 63531], [11943, 63532], [11946, 63533], [11948, 63534], - [11950, 63535], [11958, 63536], [11964, 63537], [11966, 63538], - [11978, 63540], [11980, 63541], [11981, 63542], [11983, 63543], - [11990, 63544], [11991, 63545], [11998, 63546], [62368, 172969], - [62369, 135493], [25866, 62371], [20029, 62374], [28381, 62375], - [40270, 62376], [37343, 62377], [62380, 161589], [20250, 62382], - [20264, 62383], [20392, 62384], [20852, 62386], [20892, 62387], - [20964, 62388], [21153, 62389], [21160, 62390], [21307, 62391], - [21326, 62392], [21457, 62393], [21464, 62394], [22242, 62395], - [22768, 62396], [22788, 62397], [22791, 62398], [22834, 62399], - [22836, 62400], [23398, 62401], [23454, 62402], [23455, 62403], - [23706, 62404], [24198, 62405], [24635, 62406], [25993, 62407], - [26622, 62408], [26628, 62409], [26725, 62410], [27982, 62411], - [28860, 62412], [30005, 62413], [32420, 62414], [32428, 62415], - [32442, 62416], [32455, 62417], [32463, 62418], [32479, 62419], - [32518, 62420], [32567, 62421], [33402, 62422], [33487, 62423], - [33647, 62424], [35270, 62425], [35774, 62426], [35810, 62427], - [36710, 62428], [36711, 62429], [36718, 62430], [29713, 62431], - [31996, 62432], [32205, 62433], [26950, 62434], [31433, 62435], - [30904, 62442], [32956, 62444], [36107, 62446], [33014, 62447], - [62448, 133607], [32927, 62451], [40647, 62452], [19661, 62453], - [40393, 62454], [40460, 62455], [19518, 62456], [62457, 171510], - [62458, 159758], [40458, 62459], [62460, 172339], [13761, 62461], - [28314, 62463], [33342, 62464], [29977, 62465], [18705, 62467], - [39532, 62468], [39567, 62469], [40857, 62470], [31111, 62471], - [62472, 164972], [62473, 138698], [62474, 132560], [62475, 142054], - [20004, 62476], [20096, 62478], [20103, 62479], [20159, 62480], - [20203, 62481], [20279, 62482], [13388, 62483], [20413, 62484], - [15944, 62485], [20483, 62486], [13437, 62488], [13477, 62490], - [22789, 62492], [20955, 62493], [20988, 62494], [20105, 62496], - [21136, 62498], [21287, 62499], [13767, 62500], [21417, 62501], - [13649, 62502], [21424, 62503], [21539, 62506], [13677, 62507], - [13682, 62508], [13953, 62509], [21651, 62510], [21667, 62511], - [21684, 62512], [21689, 62513], [21712, 62514], [21743, 62515], - [21784, 62516], [21795, 62517], [21800, 62518], [13720, 62519], - [13733, 62521], [13759, 62522], [21975, 62523], [13765, 62524], - [62525, 163204], [16467, 62538], [62551, 135412], [62555, 134155], - [62574, 161992], [62580, 155813], [62583, 142668], [62585, 135287], - [62587, 135279], [62595, 139681], [62609, 134550], [16571, 62611], - [62631, 142537], [22098, 62641], [62642, 134961], [62657, 157724], - [62659, 135375], [62660, 141315], [62661, 141625], [13819, 62662], - [62663, 152035], [62664, 134796], [62665, 135053], [62666, 134826], - [16275, 62667], [62668, 134960], [62669, 134471], [62670, 135503], - [62671, 134732], [62673, 134827], [62674, 134057], [62675, 134472], - [62676, 135360], [62677, 135485], [16377, 62678], [62679, 140950], - [25650, 62680], [62681, 135085], [62682, 144372], [62685, 134526], - [62686, 134527], [62688, 142421], [62690, 134808], [62692, 134958], - [62694, 158544], [21708, 62699], [33476, 62700], [21945, 62701], - [62703, 171715], [39974, 62704], [39606, 62705], [62707, 142830], - [33004, 62710], [23580, 62711], [62712, 157042], [33076, 62713], - [14231, 62714], [62716, 164029], [37302, 62717], [62718, 134906], - [62719, 134671], [62720, 134775], [62721, 134907], [62723, 151019], - [13833, 62724], [62725, 134358], [22191, 62726], [62727, 141237], - [62728, 135369], [62729, 134672], [62730, 134776], [62731, 135288], - [62732, 135496], [62733, 164359], [62734, 136277], [62735, 134777], - [62736, 151120], [62737, 142756], [23124, 62738], [62739, 135197], - [62740, 135198], [62741, 135413], [62742, 135414], [22428, 62743], - [62744, 134673], [62745, 161428], [62746, 164557], [62747, 135093], - [62748, 134779], [62749, 151934], [14083, 62750], [62751, 135094], - [62752, 135552], [62753, 152280], [62754, 172733], [62755, 149978], - [62756, 137274], [62757, 147831], [62758, 164476], [22681, 62759], - [21096, 62760], [13850, 62761], [62762, 153405], [31666, 62763], - [23400, 62764], [18432, 62765], [19244, 62766], [40743, 62767], - [18919, 62768], [39967, 62769], [39821, 62770], [62771, 154484], - [62772, 143677], [22011, 62773], [13810, 62774], [22153, 62775], - [23870, 63028], [23880, 63029], [15868, 63031], [14351, 63032], - [23972, 63033], [23993, 63034], [14368, 63035], [24357, 63039], - [24451, 63040], [14600, 63041], [14655, 63043], [14669, 63044], - [24791, 63045], [24893, 63046], [23781, 63047], [14729, 63048], - [25015, 63049], [25039, 63051], [14776, 63052], [25132, 63053], - [25317, 63055], [14840, 63057], [22193, 63058], [14851, 63059], - [25570, 63060], [25595, 63061], [25607, 63062], [14923, 63064], - [25792, 63065], [40863, 63068], [14999, 63069], [25990, 63070], - [15037, 63071], [26111, 63072], [26195, 63073], [15090, 63074], - [26258, 63075], [15138, 63076], [26390, 63077], [15170, 63078], - [26532, 63079], [15192, 63081], [26698, 63082], [26756, 63083], - [15218, 63084], [15217, 63085], [15227, 63086], [26889, 63087], - [26947, 63088], [29276, 63089], [26980, 63090], [27039, 63091], - [27013, 63092], [27094, 63094], [15325, 63095], [27237, 63096], - [27252, 63097], [27249, 63098], [27266, 63099], [15340, 63100], - [27289, 63101], [15346, 63102], [27307, 63103], [27317, 63104], - [27348, 63105], [27382, 63106], [27521, 63107], [27585, 63108], - [27626, 63109], [27765, 63110], [27818, 63111], [15563, 63112], - [27906, 63113], [27910, 63114], [27942, 63115], [28033, 63116], - [15599, 63117], [28068, 63118], [28081, 63119], [28181, 63120], - [28184, 63121], [28201, 63122], [28294, 63123], [63124, 166336], - [28347, 63125], [28386, 63126], [28378, 63127], [40831, 63128], - [28392, 63129], [28393, 63130], [28452, 63131], [28468, 63132], - [15686, 63133], [63134, 147265], [28545, 63135], [28606, 63136], - [15722, 63137], [15733, 63138], [29111, 63139], [23705, 63140], - [15754, 63141], [28716, 63142], [15761, 63143], [28752, 63144], - [28756, 63145], [28783, 63146], [28799, 63147], [63149, 131877], - [17345, 63150], [13809, 63151], [63152, 134872], [13902, 58134], - [15789, 58172], [58173, 154725], [26237, 58183], [31860, 58188], - [29837, 58197], [32402, 58215], [17667, 58232], [58260, 151480], - [58270, 133901], [58277, 158474], [13438, 58311], [58317, 143087], - [58325, 146613], [58343, 159385], [34673, 58364], [25537, 58385], - [30583, 58387], [35210, 58390], [58406, 147343], [35660, 58415], - [58440, 150729], [18730, 58464], [58471, 172052], [58472, 165564], - [58473, 165121], [15088, 58490], [28815, 58511], [58529, 140922], - [58637, 158120], [58646, 148043], [26760, 58662], [58664, 139611], - [40802, 58702], [37830, 58793], [58802, 131967], [37734, 58888], - [37519, 58901], [34324, 58954], [58986, 173147], [16784, 59010], - [26511, 59045], [26654, 59048], [14435, 59051], [59077, 149996], - [15129, 59128], [33942, 59176], [59241, 149858], [14818, 59254], - [33920, 59259], [17262, 59328], [38769, 59402], [39323, 59427], - [18733, 59499], [28439, 59703], [59704, 160009], [28838, 59746], - [59752, 150095], [32357, 59753], [23855, 59755], [15859, 59756], - [59758, 150109], [59759, 137183], [32164, 59760], [33830, 59761], - [21637, 59762], [59763, 146170], [59765, 131604], [22398, 59766], - [59767, 133333], [59768, 132633], [16357, 59769], [59770, 139166], - [59771, 172726], [28675, 59772], [59773, 168283], [23920, 59774], - [29583, 59775], [59777, 166489], [59778, 168992], [20424, 59779], - [32743, 59780], [29456, 59782], [29496, 59784], [29505, 59787], - [16041, 59789], [29173, 59792], [59793, 149746], [29665, 59794], - [16074, 59796], [16081, 59798], [29721, 59801], [29726, 59802], - [29727, 59803], [16098, 59804], [16112, 59805], [16116, 59806], - [16122, 59807], [29907, 59808], [16142, 59809], [16211, 59810], - [30061, 59812], [30066, 59813], [30093, 59814], [16252, 59815], - [30152, 59816], [30285, 59819], [30324, 59821], [16348, 59822], - [30330, 59823], [29064, 59825], [22051, 59826], [35200, 59827], - [16413, 59829], [30531, 59830], [16441, 59831], [16453, 59833], - [13787, 59834], [30616, 59835], [16490, 59836], [16495, 59837], - [30654, 59839], [30667, 59840], [30744, 59842], [30748, 59844], - [30791, 59847], [30801, 59848], [30822, 59849], [33864, 59850], - [59851, 152885], [31027, 59852], [31026, 59854], [16649, 59856], - [31121, 59857], [31238, 59860], [16743, 59862], [16818, 59864], - [31420, 59865], [33401, 59866], [16836, 59867], [31439, 59868], - [31451, 59869], [16847, 59870], [31586, 59872], [31596, 59873], - [31611, 59874], [31762, 59875], [16992, 59877], [17018, 59878], - [31867, 59879], [31900, 59880], [17036, 59881], [31928, 59882], - [17044, 59883], [36755, 59885], [28864, 59886], [59887, 134351], - [32207, 59888], [32212, 59889], [32208, 59890], [32253, 59891], - [32692, 59893], [29343, 59894], [17303, 59895], [32800, 59896], - [32805, 59897], [32814, 59899], [32817, 59900], [32852, 59901], - [22452, 59903], [28832, 59904], [32951, 59905], [33001, 59906], - [17389, 59907], [33036, 59908], [33038, 59910], [33042, 59911], - [33044, 59913], [17409, 59914], [15161, 59915], [33110, 59916], - [33113, 59917], [33114, 59918], [17427, 59919], [33148, 59921], - [17445, 59923], [17453, 59925], [33189, 59926], [22511, 59927], - [33217, 59928], [33252, 59929], [33364, 59930], [17551, 59931], - [33398, 59933], [33482, 59934], [33496, 59935], [17584, 59937], - [33623, 59938], [38505, 59939], [33797, 59941], [28917, 59942], - [33892, 59943], [33928, 59945], [17668, 59946], [33982, 59947], - [34017, 59948], [34040, 59949], [34064, 59950], [34104, 59951], - [34130, 59952], [17723, 59953], [34159, 59954], [34160, 59955], - [34272, 59956], [17783, 59957], [34418, 59958], [34450, 59959], - [34543, 59961], [38469, 59962], [17926, 59964], [17943, 59965], - [34990, 59966], [35071, 59967], [35108, 59968], [35217, 59970], - [59971, 162151], [35384, 59973], [35476, 59974], [35508, 59975], - [35921, 59976], [36052, 59977], [36082, 59978], [36124, 59979], - [18328, 59980], [36291, 59982], [18413, 59983], [36410, 59985], - [22356, 59987], [22005, 59989], [18487, 59991], [36558, 59992], - [36578, 59993], [36580, 59994], [36589, 59995], [36594, 59996], - [36801, 59998], [36810, 59999], [36812, 60000], [36915, 60001], - [18605, 60003], [39136, 60004], [37395, 60005], [18718, 60006], - [37416, 60007], [37464, 60008], [37483, 60009], [37553, 60010], - [37550, 60011], [37567, 60012], [37603, 60013], [37611, 60014], - [37619, 60015], [37620, 60016], [37629, 60017], [37699, 60018], - [37764, 60019], [37805, 60020], [18757, 60021], [18769, 60022], - [37911, 60024], [37917, 60026], [37933, 60027], [37950, 60028], - [18794, 60029], [37972, 60030], [38009, 60031], [38189, 60032], - [38306, 60033], [18855, 60034], [38388, 60035], [38451, 60036], - [18917, 60037], [18980, 60039], [38720, 60040], [18997, 60041], - [38834, 60042], [38850, 60043], [19172, 60045], [39097, 60047], - [19225, 60048], [39153, 60049], [22596, 60050], [39193, 60052], - [39223, 60055], [39261, 60057], [39266, 60058], [19312, 60059], - [39365, 60060], [19357, 60061], [39484, 60062], [39695, 60063], - [39785, 60065], [39901, 60067], [39921, 60068], [39924, 60069], - [19565, 60070], [39968, 60071], [14191, 60072], [60073, 138178], - [40265, 60074], [40702, 60076], [22096, 60077], [40381, 60079], - [40444, 60081], [38134, 60082], [36790, 60083], [40625, 60086], - [40637, 60087], [40646, 60088], [38108, 60089], [40674, 60090], - [40689, 60091], [40696, 60092], [40772, 60094], [60095, 131220], - [60096, 131767], [60097, 132000], [38083, 60099], [60101, 132311], - [38081, 60103], [60105, 132565], [60106, 132629], [60107, 132726], - [60108, 136890], [22359, 60109], [29043, 60110], [60111, 133826], - [60112, 133837], [60113, 134079], [60115, 194619], [60116, 134091], - [21662, 60117], [60118, 134139], [60119, 134203], [60120, 134227], - [60121, 134245], [60122, 134268], [60124, 134285], [60126, 134325], - [60127, 134365], [60128, 134381], [60129, 134511], [60130, 134578], - [60131, 134600], [60135, 134660], [60136, 134670], [60137, 134871], - [60138, 135056], [60139, 134957], [60140, 134771], [60142, 135100], - [60144, 135260], [60145, 135247], [60146, 135286], [60149, 135304], - [60150, 135318], [13895, 60151], [60152, 135359], [60154, 135471], - [60155, 135483], [21348, 60156], [60158, 135907], [60159, 136053], - [60160, 135990], [60162, 136567], [60163, 136729], [60164, 137155], - [60165, 137159], [28859, 60167], [60168, 137261], [60169, 137578], - [60170, 137773], [60171, 137797], [60172, 138282], [60173, 138352], - [60174, 138412], [60175, 138952], [60177, 138965], [60178, 139029], - [29080, 60179], [60181, 139333], [27113, 60182], [14024, 60183], - [60184, 139900], [60185, 140247], [60186, 140282], [60187, 141098], - [60188, 141425], [60189, 141647], [60191, 141671], [60192, 141715], - [60193, 142037], [60195, 142056], [60197, 142094], [60199, 142143], - [60202, 142412], [60204, 142472], [60205, 142519], [60206, 154600], - [60207, 142600], [60208, 142610], [60209, 142775], [60210, 142741], - [60211, 142914], [60212, 143220], [60213, 143308], [60214, 143411], - [60215, 143462], [60216, 144159], [60217, 144350], [60222, 144743], - [60223, 144883], [60227, 144922], [60228, 145174], [22709, 60231], - [60234, 146087], [60237, 146961], [60238, 147129], [60243, 147737], - [60245, 148206], [60246, 148237], [60248, 148276], [60249, 148374], - [60258, 148484], [60259, 148694], [22408, 60260], [60261, 149108], - [60263, 149295], [60271, 149522], [60272, 149755], [60273, 150037], - [60275, 150208], [22885, 60277], [60279, 151430], [60282, 151596], - [22335, 60284], [60286, 152217], [60287, 152601], [60291, 152646], - [60292, 152686], [60296, 152895], [60298, 152926], [60300, 152930], - [60301, 152934], [60302, 153543], [60304, 153693], [60309, 153859], - [60312, 154286], [60313, 154505], [60314, 154630], [22433, 60316], - [29009, 60317], [60319, 155906], [60322, 156082], [60325, 156674], - [60326, 156746], [60330, 156804], [60334, 156808], [60336, 156946], - [60338, 157119], [60339, 157365], [22201, 60347], [60349, 157436], - [13848, 60355], [60357, 157593], [60358, 157806], [60360, 157790], - [60362, 157895], [60366, 157990], [60368, 158009], [60371, 158202], - [60373, 158253], [60378, 158260], [60379, 158555], [60383, 158621], - [60385, 158884], [60388, 159150], [60392, 159819], [60393, 160205], - [60395, 160384], [60396, 160389], [60399, 160395], [60401, 160486], - [38047, 60404], [60405, 160848], [14009, 60416], [60424, 161740], - [60425, 161880], [22230, 60426], [60435, 162269], [60441, 162301], - [60442, 162314], [60443, 162571], [60444, 163174], [60448, 163849], - [60459, 163875], [60463, 163912], [60466, 163971], [60479, 163984], - [60480, 164084], [60481, 164142], [60483, 164175], [60485, 164271], - [60486, 164378], [60487, 164614], [60488, 164655], [60489, 164746], - [60491, 164968], [60492, 165546], [25574, 60494], [60495, 166230], - [60498, 166328], [60500, 166375], [60502, 166376], [60503, 166726], - [60504, 166868], [60506, 166921], [60508, 167877], [60509, 168172], - [60511, 168208], [60512, 168252], [15863, 60513], [60514, 168286], - [60515, 150218], [36816, 60516], [60519, 169191], [60521, 169392], - [60522, 169400], [60523, 169778], [60524, 170193], [60525, 170313], - [60526, 170346], [60527, 170435], [60528, 170536], [60529, 170766], - [60530, 171354], [60531, 171419], [32415, 60532], [60533, 171768], - [60534, 171811], [19620, 60535], [38215, 60536], [60537, 172691], - [29090, 60538], [60539, 172799], [60542, 173515], [19868, 60543], - [60544, 134300], [36798, 60545], [36794, 60547], [60548, 140464], - [36793, 60549], [60550, 150163], [20202, 60555], [60557, 166700], - [36480, 60560], [60561, 137205], [60563, 166764], [60564, 166809], - [60566, 157359], [60568, 161365], [60570, 153141], [60571, 153942], - [20122, 60572], [60573, 155265], [60576, 134765], [60579, 147080], - [60580, 150686], [60583, 137206], [60584, 137339], [60587, 154698], - [60589, 152337], [15814, 60590], [60596, 155352], [19996, 60600], - [60601, 135146], [60602, 134473], [60603, 145082], [60638, 151880], - [21982, 60644], [34694, 60672], [60676, 135361], [60679, 149254], - [23440, 60680], [60682, 157843], [60684, 141044], [60685, 163119], - [60686, 147875], [60687, 163187], [60688, 159440], [60689, 160438], - [60691, 135641], [60693, 146684], [60694, 173737], [60695, 134828], - [60698, 138402], [60700, 151490], [60702, 135147], [60706, 142752], - [60710, 135148], [60711, 134666], [60714, 135149], [60717, 135559], - [19994, 60721], [19972, 60722], [23309, 60724], [13996, 60727], - [21373, 60729], [13989, 60730], [22682, 60732], [60733, 150382], - [22442, 60736], [60737, 154261], [60738, 133497], [60741, 140389], - [60746, 146686], [60747, 171824], [60749, 151465], [60750, 169374], - [60753, 146870], [60755, 157619], [60756, 145184], [60759, 147191], - [60760, 146988], [60785, 143578], [60789, 135849], [22439, 60790], - [60791, 149859], [60794, 159918], [60801, 137068], [60806, 160100], - [60809, 159010], [60810, 150242], [39963, 60837], [60838, 149822], - [15878, 60846], [60881, 159011], [60887, 132092], [60891, 146685], - [60893, 149785], [22394, 60904], [21722, 60912], [29050, 60928], - [60949, 150135], [60955, 166490], [60962, 194624], [60976, 137275], - [61000, 155993], [61014, 144373], [61019, 166850], [61024, 138566], - [61054, 159441], [13877, 61065], [61084, 166701], [21024, 61088], - [15384, 61089], [61090, 146631], [61091, 155351], [61092, 161366], - [61093, 152881], [61094, 137540], [61096, 170243], [61097, 159196], - [61098, 159917], [61100, 156077], [61101, 166415], [61102, 145015], - [61103, 131310], [61104, 157766], [61105, 151310], [17762, 61106], - [23327, 61107], [61108, 156492], [40784, 61109], [40614, 61110], - [61111, 156267], [20962, 57415], [21314, 57416], [26285, 57520], - [22620, 57547], [21843, 57566], [15749, 57594], [24928, 57608], - [18606, 57668], [38845, 57676], [57693, 137335], [24755, 57703], - [33828, 57711], [38932, 57748], [57749, 147596], [57764, 143486], - [57787, 138813], [15147, 57798], [15666, 57824], [57857, 132021], - [28801, 57944], [23708, 57959], [58017, 132547], [14128, 58028], - [58096, 136054], [58097, 150034], [58111, 166699], [58112, 155779], - [256, 62233], [193, 62234], [461, 62235], [192, 62236], [274, 62237], - [201, 62238], [282, 62239], [200, 62240], [332, 62241], [211, 62242], - [465, 62243], [210, 62244], 62245, [7870, 62246], 62247, [7872, 62248], - [202, 62249], [257, 62250], [225, 62251], [462, 62252], [224, 62253], - [593, 62254], [275, 62255], [233, 62256], [283, 62257], [232, 62258], - [299, 62259], [237, 62260], [464, 62261], [236, 62262], [333, 62263], - [243, 62264], [466, 62265], [242, 62266], [363, 62267], [250, 62268], - [468, 62269], [249, 62270], [470, 62271], [472, 62272], [474, 62273], - [476, 62274], [252, 62275], 62276, [7871, 62277], 62278, [7873, 62279], - [234, 62280], [609, 62281], [643, 63551], [592, 63552], [603, 63553], - [596, 63554], [629, 63555], [339, 63556], [248, 63557], [331, 63558], - [650, 63559], [618, 63560], {f: 2, c: 62282}, [11933, 63530], - [11974, 63539], [12003, 63547], 20539, 28158, [62841, 171123], 62842, - [15817, 62843], 34959, [62845, 147790], 28791, 23797, [19232, 62848], - [62849, 152013], [13657, 62850], [62851, 154928], 24866, [62853, 166450], - 36775, 37366, 29073, 26393, 29626, [62859, 144001], [62860, 172295], - [15499, 62861], [62862, 137600], [19216, 62863], 30948, 29698, 20910, - [62867, 165647], [16393, 62868], 27235, [62870, 172730], [16931, 62871], - 34319, 31274, [62875, 170311], [62876, 166634], 38741, 28749, 21284, - [62880, 139390], 37876, 30425, [62883, 166371], 62884, 30685, 20131, 20464, - 20668, 20015, 20247, 62891, 21556, 32139, 22674, 22736, [62896, 138678], - 24210, 24217, 24514, [62900, 141074], 25995, [62902, 144377], 26905, 27203, - [62905, 146531], 27903, 29184, [62909, 148741], 29580, [16091, 62911], - [62912, 150035], 23317, 29881, 35715, [62916, 154788], [62917, 153237], - 31379, 31724, 31939, 32364, 33528, 34199, 62924, 34960, 62926, 36537, - 62928, 36815, 34143, 39392, 37409, 62933, [62934, 167353], [62935, 136255], - [16497, 62936], [17058, 62937], 23066, 39016, 26475, [17014, 62944], 22333, - 34262, [62948, 149883], 33471, [62950, 160013], [19585, 62951], - [62952, 159092], 23931, [62954, 158485], [62955, 159678], {f: 2, c: 62956}, - 23446, 62959, 32347], - 'Adobe-GB1': [{f: 95, c: 32}, {f: 3, c: 12288}, [183, 12539], 713, 711, 168, - 12291, 12293, 8212, 65374, 8214, [8230, 8943], {f: 2, c: 8216}, - {f: 2, c: 8220}, {f: 2, c: 12308}, {f: 8, c: 12296}, {f: 2, c: 12310}, - {f: 2, c: 12304}, 177, 215, 247, 8758, {f: 2, c: 8743}, 8721, 8719, 8746, - 8745, 8712, 8759, 8730, 8869, 8741, 8736, 8978, 8857, 8747, 8750, 8801, - 8780, 8776, 8765, 8733, 8800, {f: 2, c: 8814}, {f: 2, c: 8804}, 8734, 8757, - 8756, 9794, 9792, 176, {f: 2, c: 8242}, 8451, 65284, 164, {f: 2, c: 65504}, - 8240, 167, 8470, 9734, 9733, 9675, 9679, 9678, 9671, 9670, 9633, 9632, - 9651, 9650, 8251, 8594, {f: 2, c: 8592}, 8595, 12307, {f: 20, c: 9352}, - {f: 20, c: 9332}, {f: 10, c: 9312}, {f: 10, c: 12832}, {f: 12, c: 8544}, - {f: 3, c: 65281}, 65509, {f: 89, c: 65285}, 65507, {f: 83, c: 12353}, - {f: 86, c: 12449}, {f: 17, c: 913}, {f: 7, c: 931}, {f: 17, c: 945}, - {f: 7, c: 963}, {f: 7, c: 59277}, {f: 2, c: 65077}, {f: 2, c: 65081}, - {f: 2, c: 65087}, {f: 2, c: 65085}, {f: 4, c: 65089}, {f: 2, c: 59284}, - {f: 2, c: 65083}, {f: 2, c: 65079}, 65073, 59286, {f: 2, c: 65075}, - {f: 6, c: 1040}, 1025, {f: 32, c: 1046}, 1105, {f: 26, c: 1078}, 257, 225, - 462, 224, 275, 233, 283, 232, 299, 237, 464, 236, 333, 243, 466, 242, 363, - 250, 468, 249, 470, 472, 474, 476, 252, 234, 593, 7743, 324, 328, 505, 609, - {f: 37, c: 12549}, 0, {f: 76, c: 9472}, {s: 126}, 21834, 38463, 22467, - 25384, 21710, 21769, 21696, 30353, 30284, 34108, 30702, 33406, 30861, - 29233, 38552, 38797, 27688, 23433, 20474, 25353, 26263, 23736, 33018, - 26696, 32942, 26114, 30414, 20985, 25942, 29100, 32753, 34948, 20658, - 22885, 25034, 28595, 33453, 25420, 25170, 21485, 21543, 31494, - [12043, 20843], 30116, 24052, 25300, 36299, 38774, 25226, 32793, 22365, - 38712, 32610, 29240, [12137, 30333], 26575, 30334, 25670, 20336, 36133, - 25308, 31255, 26001, 29677, 25644, 25203, 33324, 39041, 26495, 29256, - 25198, 25292, 20276, 29923, 21322, 21150, 32458, 37030, 24110, 26758, - 27036, 33152, 32465, 26834, 30917, 34444, 38225, 20621, 35876, 33502, - 32990, 21253, 35090, 21093, 34180, 38649, 20445, 22561, 39281, 23453, - 25265, 25253, 26292, 35961, 40077, 29190, 26479, 30865, 24754, 21329, - 21271, 36744, 32972, 36125, 38049, 20493, 29384, 22791, 24811, 28953, - 34987, 22868, 33519, 26412, 31528, 23849, 32503, 29997, 27893, 36454, - 36856, 36924, [12240, 40763], [12112, 27604], 37145, 31508, 24444, 30887, - 34006, 34109, 27605, 27609, 27606, 24065, 24199, 30201, 38381, 25949, - 24330, 24517, 36767, 22721, 33218, 36991, 38491, 38829, 36793, 32534, - 36140, 25153, 20415, 21464, 21342, {f: 2, c: 36776}, 36779, 36941, 26631, - 24426, 33176, 34920, 40150, 24971, 21035, 30250, 24428, 25996, 28626, - 28392, 23486, 25672, 20853, 20912, 26564, 19993, 31177, 39292, 28851, - 30149, 24182, 29627, 33760, 25773, 25320, 38069, 27874, 21338, 21187, - 25615, 38082, 31636, 20271, 24091, 33334, 33046, 33162, 28196, 27850, - 39539, 25429, [12056, 21340], 21754, 34917, 22496, 19981, 24067, 27493, - 31807, 37096, 24598, 25830, 29468, 35009, 26448, 25165, 36130, 30572, - 36393, 37319, 24425, 33756, 34081, 39184, 21442, 34453, 27531, 24813, - 24808, 28799, 33485, 33329, 20179, 27815, 34255, 25805, 31961, 27133, - 26361, 33609, 21397, 31574, 20391, 20876, 27979, 23618, 36461, 25554, - 21449, 33580, 33590, 26597, 30900, 25661, 23519, 23700, 24046, 35815, - 25286, 26612, 35962, 25600, 25530, 34633, 39307, 35863, 32544, 38130, - 20135, 38416, 39076, 26124, 29462, 22330, 23581, 24120, 38271, 20607, - 32928, [12058, 21378], 25950, 30021, 21809, 20513, 36229, 25220, 38046, - 26397, 22066, 28526, 24034, 21557, 28818, 36710, 25199, 25764, 25507, - 24443, 28552, 37108, [12162, 33251], [12192, 36784], 23576, 26216, 24561, - 27785, 38472, 36225, 34924, 25745, 31216, 22478, 27225, 25104, 21576, - 20056, 31243, 24809, 28548, 35802, 25215, 36894, 39563, 31204, 21507, - 30196, 25345, 21273, 27744, 36831, 24347, 39536, 32827, 40831, 20360, - 23610, [12186, 36196], 32709, 26021, 28861, 20805, 20914, [12173, 34411], - 23815, 23456, 25277, 37228, 30068, 36364, 31264, 24833, 31609, 20167, - 32504, 30597, 19985, 33261, 21021, 20986, 27249, 21416, 36487, 38148, - 38607, 28353, 38500, 26970, 30784, 20648, 30679, 25616, 35302, 22788, - 25571, 24029, 31359, 26941, 20256, 33337, 21912, 20018, 30126, 31383, - 24162, 24202, 38383, 21019, 21561, 28810, 25462, 38180, 22402, 26149, - 26943, 37255, 21767, 28147, 32431, 34850, 25139, 32496, 30133, 33576, - 30913, 38604, 36766, 24904, 29943, 35789, 27492, 21050, 36176, 27425, - 32874, 33905, 22257, 21254, 20174, 19995, 20945, 31895, 37259, 31751, - 20419, 36479, 31713, 31388, 25703, 23828, 20652, 33030, 30209, 31929, - 28140, 32736, 26449, 23384, [12072, 23544], 30923, 25774, 25619, 25514, - 25387, 38169, 25645, 36798, 31572, 30249, 25171, [12068, 22823], 21574, - [12109, 27513], 20643, 25140, 24102, 27526, 20195, 36151, 34955, 24453, - 36910, 24608, 32829, 25285, 20025, 21333, 37112, 25528, 32966, 26086, - 27694, 20294, 24814, 28129, 35806, 24377, 34507, 24403, 25377, 20826, - 33633, 26723, [12049, 20992], 25443, 36424, 20498, 23707, 31095, 23548, - 21040, 31291, 24764, 36947, 30423, 24503, 24471, 30340, 36460, 28783, - 30331, 31561, 30634, 20979, 37011, 22564, 20302, 28404, 36842, 25932, - 31515, 29380, 28068, 32735, 23265, 25269, 24213, 22320, 33922, 31532, - 24093, 24351, 36882, 32532, 39072, 25474, 28359, 30872, 28857, 20856, - 38747, 22443, 30005, 20291, 30008, 24215, 24806, 22880, 28096, 27583, - 30857, 21500, 38613, 20939, 20993, 25481, 21514, 38035, 35843, 36300, - 29241, 30879, 34678, 36845, 35853, 21472, 19969, 30447, 21486, 38025, - 39030, [12237, 40718], 38189, 23450, 35746, 20002, 19996, 20908, 33891, - 25026, 21160, 26635, 20375, 24683, 20923, 27934, 20828, 25238, - [12099, 26007], 38497, [12182, 35910], 36887, 30168, 37117, 30563, 27602, - 29322, 29420, 35835, 22581, 30585, 36172, 26460, 38208, 32922, 24230, - 28193, 22930, 31471, 30701, 38203, 27573, 26029, 32526, 22534, 20817, - 38431, 23545, 22697, 21544, 36466, 25958, 39039, 22244, 38045, 30462, - 36929, 25479, 21702, 22810, 22842, 22427, 36530, 26421, 36346, 33333, - 21057, 24816, 22549, 34558, 23784, 40517, 20420, 39069, 35769, 23077, - 24694, 21380, 25212, 36943, 37122, 39295, 24681, [12157, 32780], - [12041, 20799], [12159, 32819], 23572, 39285, 27953, [12038, 20108], 36144, - 21457, 32602, 31567, 20240, 20047, 38400, 27861, 29648, 34281, 24070, - 30058, 32763, 27146, 30718, 38034, 32321, 20961, 28902, 21453, 36820, - 33539, 36137, 29359, 39277, 27867, 22346, 33459, [12101, 26041], 32938, - 25151, 38450, 22952, 20223, 35775, 32442, 25918, 33778, [12206, 38750], - 21857, 39134, 32933, 21290, 35837, 21536, 32954, 24223, 27832, 36153, - 33452, 37210, 21545, 27675, 20998, 32439, 22367, 28954, 27774, 31881, - 22859, 20221, 24575, 24868, 31914, 20016, 23553, 26539, 34562, 23792, - 38155, 39118, 30127, 28925, 36898, 20911, 32541, 35773, 22857, 20964, - 20315, 21542, 22827, 25975, 32932, 23413, 25206, 25282, 36752, 24133, - 27679, 31526, 20239, 20440, 26381, 28014, 28074, 31119, 34993, 24343, - 29995, 25242, 36741, 20463, 37340, 26023, 33071, 33105, 24220, 33104, - 36212, 21103, 35206, 36171, 22797, 20613, 20184, [12201, 38428], - [12119, 29238], 33145, 36127, 23500, 35747, 38468, 22919, 32538, 21648, - 22134, 22030, 35813, 25913, 27010, 38041, 30422, 28297, [12082, 24178], - [12130, 29976], 26438, 26577, 31487, 32925, 36214, 24863, 31174, 25954, - 36195, 20872, 21018, 38050, 32568, 32923, 32434, 23703, 28207, 26464, - 31705, 30347, [12220, 39640], 33167, 32660, 31957, 25630, 38224, 31295, - 21578, 21733, 27468, 25601, [12093, 25096], 40509, 33011, 30105, 21106, - [12208, 38761], 33883, 26684, 34532, 38401, 38548, 38124, 20010, 21508, - 32473, 26681, 36319, 32789, 26356, 24218, 32697, 22466, 32831, 26775, - [12079, 24037], 25915, 21151, 24685, 40858, 20379, 36524, 20844, 23467, - [12088, 24339], 24041, 27742, 25329, 36129, 20849, 38057, 21246, 27807, - 33503, 29399, 22434, 26500, 36141, 22815, 36764, 33735, 21653, 31629, - 20272, 27837, 23396, 22993, [12238, 40723], 21476, 34506, [12219, 39592], - [12181, 35895], 32929, 25925, 39038, 22266, 38599, 21038, [12128, 29916], - 21072, 23521, 25346, 35074, 20054, 25296, 24618, 26874, 20851, 23448, - 20896, 35266, 31649, 39302, 32592, 24815, 28748, 36143, 20809, - [12084, 24191], 36891, 29808, 35268, 22317, 30789, 24402, 40863, 38394, - 36712, [12225, 39740], 35809, 30328, 26690, 26588, 36330, 36149, 21053, - 36746, 28378, 26829, 38149, 37101, 22269, 26524, 35065, 36807, 21704, - 39608, 23401, 28023, 27686, 20133, 23475, 39559, 37219, 25000, 37039, - 38889, 21547, 28085, 23506, 20989, 21898, 32597, 32752, 25788, 25421, - 26097, 25022, 24717, 28938, 27735, 27721, 22831, 26477, 33322, 22741, - 22158, 35946, 27627, 37085, 22909, 32791, 21495, 28009, 21621, 21917, - 33655, 33743, 26680, [12146, 31166], 21644, 20309, 21512, 30418, 35977, - 38402, 27827, 28088, 36203, 35088, 40548, 36154, 22079, [12234, 40657], - 30165, 24456, 29408, 24680, 21756, 20136, 27178, 34913, 24658, 36720, - 21700, 28888, 34425, 40511, 27946, 23439, 24344, 32418, 21897, 20399, - 29492, 21564, 21402, 20505, 21518, 21628, 20046, 24573, 29786, 22774, - 33899, 32993, 34676, 29392, 31946, 28246, 24359, 34382, 21804, 25252, - 20114, 27818, 25143, 33457, 21719, 21326, 29502, 28369, 30011, 21010, - 21270, 35805, 27088, 24458, 24576, 28142, 22351, 27426, 29615, 26707, - 36824, 32531, 25442, 24739, 21796, 30186, 35938, 28949, 28067, 23462, - 24187, 33618, 24908, 40644, 30970, 34647, 31783, 30343, 20976, 24822, - 29004, 26179, 24140, 24653, 35854, 28784, 25381, 36745, 24509, 24674, - 34516, 22238, 27585, 24724, 24935, 21321, 24800, 26214, 36159, 31229, - 20250, 28905, 27719, 35763, 35826, 32472, 33636, 26127, 23130, 39746, - 27985, 28151, 35905, 27963, 20249, [12117, 28779], 33719, 25110, 24785, - 38669, 36135, 31096, 20987, 22334, 22522, 26426, 30072, 31293, 31215, - 31637, 32908, 39269, 36857, 28608, 35749, 40481, 23020, 32489, 32521, - 21513, 26497, 26840, 36753, 31821, 38598, 21450, 24613, 30142, 27762, - 21363, 23241, 32423, 25380, [12047, 20960], 33034, [12080, 24049], 34015, - 25216, 20864, 23395, 20238, 31085, 21058, 24760, 27982, 23492, 23490, - 35745, 35760, 26082, 24524, 38469, 22931, 32487, 32426, 22025, 26551, - 22841, 20339, 23478, 21152, 33626, 39050, 36158, 30002, 38078, 20551, - 31292, 20215, 26550, 39550, 23233, 27516, 30417, 22362, 23574, 31546, - 38388, 29006, 20860, 32937, 33392, 22904, 32516, 33575, 26816, 26604, - 30897, 30839, 25315, 25441, 31616, 20461, 21098, 20943, 33616, 27099, - 37492, 36341, 36145, 35265, 38190, 31661, 20214, 20581, 33328, 21073, - 39279, 28176, 28293, 28071, 24314, 20725, 23004, 23558, 27974, 27743, - 30086, 33931, 26728, 22870, 35762, 21280, 37233, 38477, 34121, 26898, - 30977, 28966, 33014, 20132, 37066, 27975, 39556, 23047, 22204, 25605, - 38128, 30699, 20389, 33050, 29409, [12179, 35282], 39290, 32564, 32478, - 21119, 25945, 37237, 36735, 36739, 21483, 31382, 25581, 25509, 30342, - 31224, 34903, 38454, 25130, 21163, 33410, 26708, 26480, 25463, 30571, - 31469, 27905, 32467, 35299, 22992, 25106, 34249, 33445, 30028, 20511, - 20171, 30117, 35819, 23626, [12081, 24062], 31563, [12100, 26020], - [12198, 37329], 20170, 27941, 35167, 32039, 38182, 20165, 35880, 36827, - 38771, 26187, 31105, 36817, 28908, 28024, 23613, 21170, 33606, 20834, - 33550, 30555, 26230, 40120, 20140, 24778, 31934, 31923, 32463, 20117, - 35686, 26223, 39048, 38745, 22659, 25964, 38236, 24452, 30153, 38742, - 31455, 31454, 20928, 28847, 31384, 25578, 31350, 32416, 29590, - [12210, 38893], 20037, 28792, 20061, 37202, 21417, 25937, 26087, - [12165, 33276], 33285, 21646, 23601, 30106, 38816, 25304, 29401, 30141, - 23621, 39545, 33738, 23616, 21632, 30697, 20030, 27822, 32858, 25298, - 25454, 24040, 20855, 36317, 36382, 38191, 20465, 21477, 24807, 28844, - 21095, 25424, 40515, 23071, 20518, 30519, 21367, 32482, 25733, 25899, - 25225, 25496, 20500, 29237, 35273, 20915, 35776, 32477, 22343, 33740, - 38055, 20891, 21531, 23803, 20426, 31459, 27994, 37089, 39567, 21888, - 21654, 21345, 21679, 24320, 25577, 26999, 20975, 24936, 21002, 22570, - 21208, 22350, 30733, 30475, 24247, 24951, 31968, 25179, 25239, 20130, - 28821, 32771, 25335, 28900, 38752, 22391, 33499, 26607, 26869, 30933, - 39063, 31185, 22771, 21683, 21487, 28212, 20811, 21051, 23458, 35838, - 32943, 21827, 22438, 24691, 22353, 21549, 31354, 24656, 23380, 25511, - 25248, [12061, 21475], 25187, 23495, 26543, 21741, 31391, 33510, 37239, - 24211, 35044, 22840, 22446, 25358, 36328, 33007, 22359, 31607, 20393, - 24555, 23485, 27454, 21281, 31568, 29378, 26694, 30719, 30518, 26103, - 20917, 20111, 30420, 23743, 31397, 33909, 22862, 39745, 20608, 39304, - 24871, 28291, 22372, 26118, 25414, 22256, 25324, 25193, 24275, 38420, - 22403, 25289, 21895, 34593, 33098, 36771, 21862, 33713, 26469, 36182, - 34013, 23146, 26639, 25318, 31726, 38417, 20848, 28572, 35888, 25597, - 35272, 25042, 32518, 28866, 28389, 29701, 27028, 29436, 24266, 37070, - 26391, 28010, 25438, 21171, 29282, [12156, 32769], 20332, 23013, 37226, - 28889, 28061, 21202, 20048, 38647, 38253, 34174, 30922, 32047, 20769, - 22418, 25794, 32907, 31867, 27882, 26865, 26974, 20919, 21400, 26792, - 29313, 40654, 31729, 29432, 31163, 28435, 29702, 26446, [12197, 37324], - 40100, 31036, 33673, 33620, 21519, 26647, 20029, 21385, 21169, 30782, - 21382, 21033, 20616, 20363, 20432, 30178, [12148, 31435], 31890, 27813, - [12202, 38582], [12050, 21147], 29827, 21737, 20457, 32852, 33714, 36830, - 38256, 24265, 24604, 28063, 24088, 25947, 33080, 38142, 24651, 28860, - 32451, 31918, 20937, 26753, 31921, 33391, 20004, 36742, 37327, 26238, - 20142, 35845, 25769, 32842, 20698, 30103, 29134, 23525, 36797, 28518, - 20102, 25730, 38243, 24278, 26009, 21015, 35010, 28872, 21155, 29454, - 29747, 26519, 30967, 38678, 20020, 37051, 40158, 28107, 20955, 36161, - 21533, 25294, 29618, 33777, 38646, 40836, 38083, 20278, 32666, 20940, - 28789, 38517, 23725, 39046, 21478, 20196, 28316, 29705, 27060, 30827, - 39311, 30041, 21016, 30244, 27969, 26611, 20845, 40857, 32843, 21657, - 31548, 31423, 38534, 22404, 25314, 38471, 27004, 23044, 25602, 31699, - 28431, 38475, 33446, 21346, 39045, 24208, 28809, 25523, 21348, 34383, - 40065, 40595, 30860, 38706, 36335, 36162, [12229, 40575], 28510, 31108, - 24405, 38470, 25134, 39540, 21525, 38109, 20387, 26053, 23653, 23649, - 32533, 34385, 27695, 24459, 29575, 28388, 32511, 23782, 25371, 23402, - 28390, 21365, 20081, 25504, 30053, 25249, 36718, 20262, 20177, 27814, - 32438, 35770, 33821, 34746, 32599, 36923, 38179, 31657, 39585, 35064, - 33853, 27931, 39558, 32476, 22920, [12231, 40635], 29595, 30721, 34434, - 39532, 39554, 22043, 21527, 22475, 20080, 40614, 21334, 36808, 33033, - 30610, 39314, 34542, 28385, 34067, 26364, 24930, 28459, 35881, 33426, - 33579, 30450, 27667, 24537, 33725, 29483, 33541, 38170, [12113, 27611], - [12141, 30683], 38086, 21359, 33538, 20882, 24125, 35980, 36152, 20040, - 29611, 26522, 26757, 37238, 38665, 29028, 27809, 30473, 23186, 38209, - 27599, 32654, 26151, 23504, 22969, 23194, 38376, 38391, 20204, 33804, - 33945, 27308, 30431, 38192, 29467, 26790, 23391, 30511, 37274, 38753, - 31964, 36855, 35868, 24357, [12150, 31859], 31192, 35269, 27852, 34588, - 23494, 24130, 26825, 30496, 32501, 20885, 20813, 21193, 23081, 32517, - [12207, 38754], 33495, 25551, 30596, 34256, 31186, 28218, 24217, 22937, - 34065, 28781, 27665, 25279, [12139, 30399], 25935, 24751, 38397, 26126, - 34719, 40483, 38125, 21517, 21629, 35884, {f: 2, c: 25720}, 34321, 27169, - 33180, 30952, 25705, 39764, 25273, 26411, 33707, 22696, 40664, 27819, - 28448, 23518, 38476, 35851, 29279, 26576, 25287, 29281, 20137, 22982, - 27597, 22675, 26286, 24149, 21215, 24917, [12106, 26408], [12140, 30446], - 30566, 29287, 31302, 25343, 21738, 21584, 38048, 37027, 23068, 32435, - 27670, 20035, 22902, 32784, 22856, 21335, 30007, 38590, 22218, 25376, - 33041, 24700, 38393, 28118, 21602, 39297, 20869, 23273, 33021, 22958, - 38675, 20522, 27877, 23612, 25311, 20320, 21311, 33147, 36870, 28346, - 34091, 25288, 24180, 30910, 25781, 25467, 24565, 23064, 37247, 40479, - 23615, 25423, 32834, 23421, 21870, 38218, 38221, 28037, 24744, 26592, - 29406, 20957, 23425, 25319, 27870, [12124, 29275], 25197, 38062, 32445, - 33043, 27987, 20892, 24324, 22900, 21162, 24594, [12069, 22899], 26262, - 34384, 30111, 25386, 25062, 31983, 35834, 21734, 27431, 40485, 27572, - 34261, 21589, 20598, 27812, 21866, 36276, 29228, 24085, 24597, 29750, - 25293, 25490, 29260, 24472, 28227, 27966, 25856, 28504, 30424, 30928, - 30460, 30036, 21028, 21467, 20051, 24222, 26049, 32810, 32982, 25243, - 21638, 21032, 28846, 34957, 36305, 27873, 21624, 32986, 22521, 35060, - 36180, 38506, 37197, 20329, 27803, 21943, 30406, 30768, 25256, 28921, - 28558, 24429, 34028, 26842, 30844, 31735, 33192, 26379, 40527, 25447, - 30896, 22383, 30738, 38713, 25209, 25259, 21128, 29749, 27607, 21860, - 33086, 30130, [12138, 30382], 21305, 30174, 20731, 23617, 35692, 31687, - 20559, [12122, 29255], 39575, 39128, 28418, 29922, 31080, 25735, 30629, - 25340, 39057, 36139, 21697, 32856, 20050, 22378, 33529, 33805, 24179, - 20973, 29942, 35780, 23631, 22369, 27900, 39047, 23110, 30772, 39748, - 36843, 31893, 21078, 25169, 38138, 20166, 33670, 33889, 33769, 33970, - 22484, 26420, 22275, 26222, 28006, 35889, 26333, 28689, 26399, 27450, - 26646, 25114, 22971, 19971, 20932, 28422, 26578, 27791, 20854, 26827, - 22855, 27495, 30054, 23822, 33040, 40784, 26071, 31048, 31041, 39569, - 36215, 23682, 20062, 20225, 21551, 22865, 30732, 22120, [12115, 27668], - 36804, 24323, 27773, 27875, 35755, 25488, 24688, 27965, 29301, 25190, - 38030, 38085, 21315, 36801, 31614, 20191, 35878, 20094, 40660, 38065, - 38067, 21069, 28508, 36963, 27973, 35892, 22545, 23884, [12107, 27424], - 27465, 26538, 21595, 33108, 32652, 22681, 34103, 24378, 25250, 27207, - 38201, 25970, 24708, 26725, 30631, 20052, 20392, 24039, 38808, 25772, - 32728, 23789, 20431, 31373, 20999, 33540, 19988, 24623, 31363, 38054, - 20405, 20146, 31206, 29748, 21220, 33465, 25810, 31165, 23517, 27777, - 38738, 36731, 27682, 20542, 21375, 28165, 25806, 26228, 27696, 24773, - 39031, 35831, 24198, 29756, 31351, 31179, 19992, 37041, 29699, 27714, - 22234, 37195, 27845, 36235, 21306, 34502, 26354, 36527, 23624, 39537, - 28192, 21462, 23094, 40843, 36259, 21435, 22280, 39079, 26435, 37275, - 27849, 20840, 30154, 25331, [12125, 29356], 21048, 21149, 32570, 28820, - 30264, 21364, 40522, 27063, 30830, 38592, 35033, 32676, 28982, 29123, - 20873, 26579, 29924, 22756, 25880, 22199, 35753, 39286, 25200, 32469, - 24825, 28909, 22764, 20161, [12040, 20154], 24525, 38887, 20219, 35748, - 20995, 22922, 32427, 25172, 20173, [12103, 26085], 25102, 33592, 33993, - 33635, 34701, 29076, 28342, 23481, 32466, 20887, 25545, 26580, - [12161, 32905], 33593, 34837, 20754, 23418, 22914, 36785, 20083, 27741, - [12042, 20837], 35109, 36719, 38446, 34122, 29790, 38160, 38384, 28070, - 33509, 24369, 25746, 27922, 33832, 33134, 40131, 22622, 36187, 19977, - 21441, 20254, 25955, 26705, 21971, 20007, 25620, 39578, 25195, 23234, - 29791, [12170, 33394], 28073, 26862, 20711, 33678, 30722, 26432, 21049, - 27801, 32433, 20667, 21861, 29022, 31579, 26194, 29642, 33515, 26441, - [12077, 23665], 21024, 29053, 34923, 38378, 38485, 25797, 36193, 33203, - 21892, 27733, 25159, 32558, 22674, 20260, 21830, 36175, 26188, 19978, - 23578, 35059, 26786, 25422, 31245, 28903, 33421, 21242, 38902, 23569, - 21736, 37045, 32461, 22882, 36170, 34503, [12166, 33292], 33293, 36198, - 25668, 23556, 24913, 28041, 31038, 35774, 30775, 30003, 21627, 20280, - [12189, 36523], 28145, 23072, 32453, 31070, 27784, 23457, 23158, 29978, - 32958, 24910, 28183, 22768, [12131, 29983], 29989, 29298, 21319, 32499, - 30465, 30427, 21097, 32988, 22307, 24072, 22833, 29422, 26045, 28287, - 35799, [12075, 23608], 34417, [12055, 21313], [12143, 30707], 25342, 26102, - 20160, [12215, 39135], 34432, 23454, 35782, 21490, [12142, 30690], 20351, - 23630, 39542, 22987, 24335, [12144, 31034], [12064, 22763], 19990, 26623, - 20107, 25325, 35475, 36893, 21183, 26159, 21980, 22124, 36866, 20181, - 20365, 37322, 39280, [12114, 27663], 24066, 24643, 23460, 35270, 35797, - 25910, [12095, 25163], [12216, 39318], 23432, 23551, 25480, 21806, 21463, - 30246, 20861, 34092, 26530, 26803, 27530, 25234, 36755, 21460, 33298, - 28113, 30095, 20070, 36174, 23408, 29087, 34223, 26257, 26329, 32626, - 34560, [12233, 40653], [12239, 40736], 23646, 26415, 36848, 26641, 26463, - 25101, 31446, 22661, 24246, 25968, 28465, 24661, 21047, 32781, 25684, - 34928, 29993, 24069, 26643, 25332, 38684, 21452, 29245, 35841, - [12116, 27700], 30561, 31246, 21550, 30636, 39034, 33308, 35828, 30805, - 26388, 28865, 26031, 25749, 22070, 24605, 31169, 21496, 19997, 27515, - 32902, 23546, 21987, 22235, 20282, 20284, 39282, 24051, 26494, 32824, - 24578, 39042, 36865, 23435, 35772, 35829, 25628, 33368, 25822, 22013, - 33487, 37221, 20439, 32032, 36895, 31903, 20723, 22609, 28335, 23487, - 35785, 32899, 37240, 33948, 31639, 34429, 38539, 38543, 32485, 39635, - 30862, 23681, 31319, 36930, 38567, 31071, 23385, 25439, 31499, 34001, - 26797, 21766, 32553, 29712, 32034, 38145, 25152, 22604, 20182, 23427, - 22905, 22612, 29549, 25374, 36427, 36367, 32974, 33492, 25260, 21488, - 27888, 37214, 22826, 24577, 27760, 22349, 25674, 36138, 30251, 28393, - 22363, 27264, 30192, 28525, 35885, 35848, 22374, 27631, 34962, 30899, - 25506, 21497, 28845, 27748, 22616, 25642, 22530, 26848, 33179, 21776, - 31958, 20504, 36538, 28108, 36255, 28907, 25487, 28059, 28372, 32486, - 33796, 26691, 36867, 28120, 38518, 35752, 22871, 29305, 34276, 33150, - 30140, 35466, 26799, 21076, 36386, 38161, 25552, 39064, 36420, 21884, - 20307, 26367, 22159, 24789, 28053, 21059, 23625, 22825, 28155, 22635, - [12133, 30000], 29980, 24684, 33300, 33094, 25361, 26465, 36834, 30522, - 36339, 36148, 38081, 24086, 21381, 21548, 28867, 27712, 24311, 20572, - 20141, 24237, 25402, 33351, 36890, 26704, 37230, 30643, 21516, 38108, - 24420, 31461, 26742, 25413, 31570, 32479, 30171, 20599, 25237, 22836, - 36879, 20984, 31171, 31361, 22270, 24466, 36884, 28034, 23648, - [12063, 22303], 21520, 20820, 28237, 22242, 25512, 39059, 33151, 34581, - 35114, 36864, 21534, 23663, 33216, 25302, 25176, 33073, 40501, 38464, - 39534, 39548, 26925, 22949, 25299, 21822, 25366, 21703, 34521, 27964, - 23043, [12129, 29926], 34972, 27498, 22806, 35916, 24367, 28286, 29609, - 39037, 20024, 28919, 23436, 30871, 25405, 26202, 30358, 24779, 23451, - 23113, 19975, 33109, 27754, 29579, 20129, 26505, [12153, 32593], 24448, - 26106, 26395, 24536, 22916, 23041, 24013, 24494, 21361, 38886, 36829, - 26693, 22260, 21807, 24799, 20026, 28493, 32500, 33479, 33806, 22996, - 20255, 20266, 23614, 32428, 26410, 34074, 21619, 30031, 32963, 21890, - 39759, 20301, 28205, 35859, 23561, 24944, 21355, 30239, 28201, 34442, - [12098, 25991], 38395, 32441, 21563, 31283, 32010, 38382, 21985, 32705, - 29934, 25373, 34583, 28065, 31389, 25105, 26017, 21351, 25569, 27779, - 24043, 21596, 38056, 20044, 27745, 35820, 23627, [12102, 26080], 33436, - 26791, 21566, 21556, [12111, 27595], 27494, 20116, 25410, 21320, 33310, - 20237, 20398, 22366, 25098, 38654, 26212, 29289, 21247, 21153, 24735, - 35823, 26132, 29081, 26512, 35199, 30802, 30717, 26224, 22075, 21560, - 38177, 29306, 31232, 24687, 24076, 24713, 33181, [12067, 22805], 24796, - 29060, 28911, 28330, 27728, 29312, 27268, 34989, 24109, 20064, 23219, - 21916, 38115, 27927, 31995, 38553, 25103, 32454, 30606, 34430, 21283, - 38686, 36758, 26247, 23777, 20384, 29421, 19979, 21414, 22799, 21523, - 25472, 38184, 20808, 20185, 40092, 32420, 21688, 36132, 34900, 33335, - 38386, 28046, 24358, 23244, 26174, 38505, 29616, 29486, 21439, 33146, - 39301, 32673, 23466, 38519, 38480, 32447, 30456, 21410, 38262, - [12217, 39321], 31665, 35140, 28248, 20065, 32724, 31077, 35814, 24819, - 21709, 20139, 39033, 24055, 27233, 20687, 21521, 35937, 33831, 30813, - 38660, 21066, 21742, 22179, 38144, 28040, 23477, 28102, 26195, - [12073, 23567], 23389, 26657, 32918, 21880, 31505, 25928, 26964, 20123, - 27463, 34638, 38795, 21327, 25375, 25658, 37034, 26012, 32961, 35856, - 20889, 26800, 21368, 34809, 25032, 27844, 27899, 35874, 23633, 34218, - 33455, 38156, 27427, [12191, 36763], 26032, 24571, [12092, 24515], 20449, - 34885, 26143, 33125, 29481, 24826, 20852, 21009, 22411, 24418, 37026, - [12175, 34892], 37266, 24184, 26447, 24615, 22995, 20804, 20982, 33016, - 21256, 27769, 38596, 29066, 20241, 20462, 32670, 26429, 21957, 38152, - 31168, 34966, 32483, 22687, 25100, 38656, 34394, 22040, 39035, 24464, - 35768, 33988, 37207, 21465, 26093, 24207, 30044, 24676, 32110, 23167, - 32490, 32493, 36713, 21927, 23459, 24748, 26059, [12126, 29572], 36873, - 30307, 30505, 32474, 38772, 34203, 23398, [12147, 31348], 38634, - [12174, 34880], 21195, 29071, 24490, 26092, 35810, 23547, 39535, 24033, - 27529, 27739, 35757, 35759, 36874, 36805, 21387, 25276, 40486, 40493, - 21568, 20011, 33469, [12123, 29273], 34460, 23830, 34905, 28079, 38597, - 21713, 20122, 35766, 28937, 21693, 38409, 28895, 28153, 30416, 20005, - 30740, 34578, 23721, 24310, [12180, 35328], 39068, 38414, 28814, 27839, - 22852, 25513, 30524, 34893, 28436, 33395, 22576, 29141, 21388, 30746, - 38593, 21761, 24422, 28976, 23476, 35866, 39564, 27523, 22830, 40495, - 31207, 26472, 25196, 20335, 30113, [12154, 32650], 27915, 38451, 27687, - 20208, 30162, 20859, 26679, 28478, 36992, 33136, 22934, 29814, 25671, - 23591, 36965, 31377, 35875, 23002, 21676, 33280, 33647, 35201, 32768, - 26928, 22094, 32822, 29239, 37326, 20918, 20063, 39029, 25494, 19994, - 21494, 26355, 33099, 22812, 28082, [12032, 19968], 22777, 21307, 25558, - 38129, 20381, 20234, [12176, 34915], 39056, 22839, 36951, 31227, 20202, - 33008, 30097, 27778, 23452, 23016, 24413, 26885, 34433, 20506, 24050, - [12036, 20057], 30691, 20197, 33402, 25233, 26131, [12194, 37009], 23673, - 20159, 24441, 33222, 36920, 32900, 30123, 20134, 35028, 24847, 27589, - 24518, 20041, 30410, 28322, 35811, 35758, 35850, 35793, 24322, 32764, - 32716, 32462, 33589, 33643, 22240, 27575, [12211, 38899], 38452, 23035, - 21535, 38134, 28139, 23493, 39278, 23609, 24341, 38544, 21360, 33521, - 27185, 23156, 40560, 24212, 32552, 33721, {f: 2, c: 33828}, 33639, 34631, - 36814, 36194, 30408, 24433, 39062, 30828, 26144, 21727, 25317, 20323, - 33219, 30152, 24248, 38605, 36362, 34553, 21647, 27891, 28044, 27704, - 24703, 21191, [12132, 29992], 24189, 20248, 24736, 24551, 23588, 30001, - 37038, 38080, 29369, 27833, 28216, [12195, 37193], 26377, 21451, 21491, - 20305, 37321, 35825, [12060, 21448], 24188, 36802, 28132, 20110, 30402, - 27014, 34398, 24858, 33286, 20313, 20446, 36926, 40060, 24841, 28189, - 28180, 38533, 20104, 23089, [12204, 38632], 19982, 23679, 31161, 23431, - 35821, [12155, 32701], [12127, 29577], 22495, 33419, 37057, 21505, 36935, - 21947, 23786, 24481, 24840, 27442, 29425, 32946, 35465, 28020, 23507, - 35029, 39044, 35947, 39533, 40499, 28170, 20900, 20803, 22435, 34945, - 21407, 25588, 36757, 22253, 21592, 22278, 29503, 28304, 32536, 36828, - 33489, 24895, 24616, 38498, [12104, 26352], 32422, 36234, 36291, 38053, - 23731, 31908, [12105, 26376], 24742, 38405, 32792, 20113, 37095, 21248, - 38504, 20801, 36816, 34164, 37213, 26197, 38901, 23381, 21277, 30776, - 26434, 26685, 21705, 28798, 23472, 36733, 20877, 22312, 21681, 25874, - 26242, 36190, 36163, 33039, 33900, 36973, 31967, 20991, 34299, 26531, - 26089, 28577, 34468, 36481, 22122, 36896, 30338, 28790, 29157, 36131, - 25321, 21017, 27901, 36156, 24590, 22686, 24974, 26366, 36192, 25166, - 21939, 28195, 26413, 36711, 38113, 38392, 30504, 26629, 27048, 21643, - 20045, 28856, 35784, 25688, 25995, 23429, 31364, 20538, 23528, 30651, - 27617, 35449, 31896, 27838, 30415, 26025, 36759, 23853, 23637, 34360, - 26632, 21344, 25112, 31449, 28251, 32509, 27167, 31456, 24432, 28467, - 24352, 25484, 28072, 26454, 19976, 24080, 36134, 20183, 32960, 30260, - 38556, 25307, 26157, 25214, 27836, 36213, 29031, 32617, 20806, 32903, - 21484, 36974, 25240, 21746, 34544, 36761, 32773, 38167, 34071, 36825, - 27993, 29645, 26015, 30495, 29956, 30759, 33275, 36126, 38024, 20390, - 26517, 30137, 35786, 38663, 25391, 38215, 38453, 33976, 25379, 30529, - 24449, 29424, 20105, 24596, 25972, 25327, 27491, 25919, 24103, 30151, - 37073, 35777, 33437, 26525, [12096, 25903], 21553, 34584, 30693, 32930, - 33026, 27713, 20043, 32455, 32844, 30452, 26893, 27542, 25191, 20540, - 20356, 22336, 25351, [12108, 27490], 36286, 21482, 26088, 32440, 24535, - 25370, 25527, [12164, 33267], 33268, 32622, 24092, 23769, 21046, 26234, - 31209, 31258, 36136, 28825, 30164, 28382, 27835, 31378, 20013, 30405, - 24544, 38047, 34935, 32456, 31181, 32959, 37325, 20210, 20247, - [12168, 33311], 21608, 24030, 27954, 35788, 31909, 36724, 32920, 24090, - 21650, 30385, 23449, 26172, 39588, 29664, 26666, 34523, 26417, 29482, - 35832, 35803, 36880, [12149, 31481], 28891, 29038, 25284, 30633, 22065, - 20027, 33879, 26609, 21161, 34496, 36142, 38136, 31569, 20303, 27880, - 31069, 39547, 25235, [12118, 29226], 25341, 19987, 30742, 36716, 25776, - 36186, 31686, 26729, 24196, 35013, 22918, 25758, 22766, 29366, 26894, - 38181, 36861, 36184, 22368, 32512, 35846, 20934, 25417, 25305, 21331, - 26700, 29730, 33537, 37196, 21828, 30528, 28796, 27978, 20857, 21672, - 36164, 23039, 28363, 28100, 23388, 32043, 20180, 31869, 28371, - [12070, 23376], [12163, 33258], 28173, 23383, 39683, 26837, 36394, 23447, - 32508, 24635, 32437, 37049, [12187, 36208], 22863, 25549, 31199, - [12188, 36275], 21330, 26063, 31062, 35781, 38459, 32452, 38075, 32386, - 22068, 37257, 26368, 32618, 23562, 36981, 26152, 24038, 20304, 26590, - 20570, 20316, 22352, 24231, 20109, 19980, 20800, 19984, 24319, 21317, - 19989, 20120, 19998, [12224, 39730], 23404, 22121, [12033, 20008], 31162, - [12035, 20031], [12052, 21269], 20039, 22829, [12120, 29243], 21358, 27664, - 22239, 32996, 39319, 27603, 30590, 40727, [12034, 20022], 20127, 40720, - 20060, 20073, 20115, 33416, 23387, 21868, 22031, 20164, 21389, 21405, - 21411, 21413, 21422, 38757, 36189, [12053, 21274], 21493, 21286, 21294, - 21310, 36188, 21350, 21347, 20994, 21000, 21006, 21037, 21043, - {f: 2, c: 21055}, 21068, 21086, 21089, 21084, 33967, 21117, 21122, 21121, - 21136, 21139, [12044, 20866], 32596, 20155, 20163, 20169, 20162, 20200, - 20193, 20203, 20190, 20251, 20211, 20258, 20324, 20213, 20261, 20263, - 20233, 20267, 20318, 20327, 25912, 20314, 20317, 20319, 20311, 20274, - 20285, 20342, 20340, 20369, 20361, 20355, 20367, 20350, 20347, 20394, - 20348, 20396, 20372, 20454, 20456, 20458, 20421, 20442, 20451, 20444, - 20433, 20447, 20472, 20521, 20556, 20467, 20524, 20495, 20526, 20525, - 20478, 20508, 20492, 20517, 20520, 20606, 20547, 20565, 20552, 20558, - 20588, 20603, 20645, 20647, 20649, 20666, 20694, 20742, 20717, 20716, - 20710, 20718, 20743, 20747, 20189, 27709, 20312, 20325, 20430, - [12245, 40864], 27718, 31860, 20846, 24061, 40649, 39320, 20865, 22804, - [12051, 21241], 21261, 35335, 21264, 20971, 22809, 20821, [12039, 20128], - 20822, 20147, 34926, 34980, 20149, 33044, 35026, 31104, 23348, 34819, - 32696, [12046, 20907], 20913, 20925, 20924, 20935, [12045, 20886], 20898, - 20901, 35744, {f: 2, c: 35750}, 35754, {f: 2, c: 35764}, 35767, - {f: 2, c: 35778}, 35787, 35791, 35790, {f: 3, c: 35794}, 35798, - {f: 2, c: 35800}, 35804, {f: 2, c: 35807}, 35812, {f: 2, c: 35816}, 35822, - 35824, 35827, 35830, 35833, 35836, {f: 2, c: 35839}, 35842, 35844, 35847, - 35852, 35855, {f: 2, c: 35857}, {f: 3, c: 35860}, 35865, 35867, 35864, - 35869, {f: 3, c: 35871}, 35877, 35879, {f: 2, c: 35882}, {f: 2, c: 35886}, - {f: 2, c: 35890}, {f: 2, c: 35893}, [12057, 21353], 21370, 38429, 38434, - 38433, 38449, 38442, 38461, 38460, 38466, 38473, 38484, 38495, 38503, - 38508, 38514, 38516, 38536, 38541, 38551, 38576, 37015, 37019, 37021, - 37017, 37036, 37025, 37044, 37043, 37046, 37050, 37048, 37040, 37071, - 37061, 37054, 37072, 37060, 37063, 37075, 37094, 37090, 37084, 37079, - 37083, 37099, 37103, 37118, 37124, 37154, 37150, 37155, 37169, 37167, - 37177, 37187, 37190, 21005, 22850, 21154, {f: 2, c: 21164}, 21182, 21759, - 21200, 21206, 21232, 21471, 29166, 30669, [12085, 24308], [12048, 20981], - 20988, [12223, 39727], [12059, 21430], 24321, 30042, 24047, 22348, 22441, - 22433, 22654, 22716, 22725, 22737, 22313, 22316, 22314, 22323, 22329, - {f: 2, c: 22318}, 22364, 22331, 22338, 22377, 22405, 22379, 22406, 22396, - 22395, 22376, 22381, 22390, 22387, 22445, 22436, 22412, 22450, 22479, - 22439, 22452, 22419, 22432, 22485, 22488, 22490, 22489, 22482, 22456, - 22516, 22511, 22520, 22500, 22493, 22539, 22541, 22525, 22509, 22528, - 22558, 22553, 22596, 22560, 22629, 22636, 22657, 22665, 22682, 22656, - 39336, 40729, 25087, 33401, 33405, 33407, 33423, 33418, 33448, 33412, - 33422, 33425, 33431, 33433, 33451, 33464, 33470, 33456, 33480, 33482, - 33507, 33432, 33463, 33454, {f: 2, c: 33483}, 33473, 33449, 33460, 33441, - 33450, 33439, 33476, 33486, 33444, 33505, 33545, 33527, 33508, 33551, - 33543, 33500, 33524, 33490, 33496, 33548, 33531, 33491, 33553, 33562, - 33542, {f: 2, c: 33556}, 33504, 33493, 33564, 33617, {f: 2, c: 33627}, - 33544, 33682, 33596, 33588, 33585, 33691, 33630, 33583, 33615, 33607, - 33603, 33631, 33600, 33559, 33632, 33581, 33594, 33587, 33638, 33637, - 33640, 33563, 33641, 33644, 33642, {f: 2, c: 33645}, 33712, 33656, - {f: 2, c: 33715}, 33696, 33706, 33683, 33692, 33669, 33660, 33718, 33705, - 33661, 33720, 33659, 33688, 33694, 33704, 33722, 33724, 33729, 33793, - 33765, 33752, 22535, 33816, 33803, 33757, 33789, 33750, 33820, 33848, - 33809, 33798, 33748, 33759, 33807, 33795, {f: 2, c: 33784}, 33770, 33733, - 33728, 33830, 33776, 33761, 33884, 33873, 33882, 33881, 33907, - {f: 2, c: 33927}, 33914, 33929, 33912, 33852, 33862, 33897, 33910, 33932, - 33934, 33841, 33901, 33985, 33997, 34000, 34022, 33981, 34003, 33994, - 33983, 33978, 34016, 33953, 33977, 33972, 33943, 34021, 34019, 34060, - 29965, 34104, 34032, 34105, 34079, 34106, 34134, 34107, 34047, 34044, - 34137, 34120, 34152, 34148, 34142, 34170, 30626, 34115, 34162, 34171, - 34212, 34216, 34183, 34191, 34169, 34222, 34204, 34181, 34233, 34231, - 34224, 34259, 34241, 34268, 34303, 34343, 34309, 34345, 34326, 34364, - [12086, 24318], 24328, 22844, 22849, 32823, 22869, 22874, 22872, 21263, - [12074, 23586], 23589, 23596, 23604, 25164, 25194, 25247, 25275, 25290, - 25306, 25303, 25326, 25378, 25334, 25401, 25419, 25411, 25517, 25590, - 25457, 25466, 25486, 25524, 25453, 25516, 25482, 25449, 25518, 25532, - 25586, 25592, 25568, 25599, 25540, 25566, 25550, 25682, 25542, 25534, - 25669, 25665, 25611, 25627, 25632, 25612, 25638, 25633, 25694, 25732, - 25709, 25750, 25722, {f: 2, c: 25783}, 25753, 25786, 25792, 25808, 25815, - 25828, 25826, 25865, 25893, 25902, [12087, 24331], 24530, 29977, 24337, - 21343, 21489, 21501, 21481, 21480, 21499, 21522, 21526, 21510, 21579, - {f: 3, c: 21586}, 21590, 21571, 21537, 21591, 21593, 21539, 21554, 21634, - 21652, 21623, 21617, 21604, {f: 2, c: 21658}, 21636, 21622, 21606, 21661, - 21712, 21677, 21698, 21684, 21714, 21671, 21670, {f: 2, c: 21715}, 21618, - 21667, 21717, 21691, 21695, 21708, {f: 2, c: 21721}, 21724, - {f: 2, c: 21673}, 21668, 21725, 21711, 21726, 21787, 21735, 21792, 21757, - 21780, 21747, {f: 2, c: 21794}, 21775, 21777, 21799, 21802, 21863, 21903, - 21941, 21833, 21869, 21825, 21845, 21823, 21840, 21820, 21815, 21846, - {f: 3, c: 21877}, 21811, 21808, 21852, 21899, 21970, 21891, 21937, 21945, - 21896, 21889, 21919, 21886, 21974, 21905, 21883, 21983, {f: 2, c: 21949}, - 21908, 21913, 21994, 22007, 21961, 22047, 21969, {f: 2, c: 21995}, 21972, - 21990, 21981, 21956, 21999, 21989, {f: 2, c: 22002}, {f: 2, c: 21964}, - 21992, 22005, 21988, 36756, 22046, 22024, 22028, 22017, 22052, 22051, - 22014, 22016, 22055, 22061, 22104, 22073, 22103, 22060, 22093, 22114, - 22105, 22108, 22092, 22100, 22150, 22116, 22129, 22123, {f: 2, c: 22139}, - 22149, 22163, 22191, 22228, [12062, 22231], 22237, 22241, 22261, 22251, - 22265, 22271, 22276, 22282, 22281, 22300, 24079, 24089, 24084, 24081, - 24113, {f: 2, c: 24123}, 24119, 24132, 24148, 24155, 24158, 24161, 23692, - 23674, 23693, 23696, 23702, 23688, {f: 2, c: 23704}, 23697, 23706, 23708, - 23733, 23714, 23741, 23724, 23723, 23729, 23715, 23745, 23735, 23748, - 23762, 23780, 23755, 23781, {f: 2, c: 23810}, 23847, 23846, 23854, 23844, - 23838, 23814, 23835, 23896, 23870, 23860, 23869, 23916, 23899, 23919, - 23901, 23915, 23883, 23882, 23913, 23924, 23938, 23961, 23965, 35955, - 23991, 24005, [12091, 24435], 24439, 24450, 24455, 24457, 24460, 24469, - 24473, 24476, 24488, 24493, 24501, 24508, 34914, [12090, 24417], 29357, - 29360, 29364, {f: 2, c: 29367}, 29379, 29377, 29390, 29389, 29394, 29416, - 29423, 29417, 29426, 29428, 29431, 29441, 29427, 29443, {f: 2, c: 29434}, - 29463, 29459, 29473, 29450, 29470, 29469, 29461, 29474, 29497, 29477, - 29484, 29496, 29489, 29520, 29517, 29527, 29536, 29548, 29551, 29566, - [12167, 33307], 22821, 39143, 22820, [12065, 22786], 39267, - {f: 6, c: 39271}, 39284, 39287, 39293, 39296, 39300, 39303, 39306, 39309, - {f: 2, c: 39312}, {f: 3, c: 39315}, 24192, 24209, 24203, 24214, 24229, - 24224, 24249, 24245, 24254, 24243, 36179, 24274, 24273, 24283, 24296, - 24298, 33210, 24516, 24521, 24534, 24527, 24579, 24558, 24580, 24545, - 24548, 24574, {f: 2, c: 24581}, 24554, 24557, 24568, 24601, 24629, 24614, - 24603, 24591, 24589, 24617, 24619, 24586, 24639, 24609, {f: 2, c: 24696}, - 24699, 24698, 24642, 24682, 24701, 24726, 24730, 24749, 24733, 24707, - 24722, 24716, 24731, 24812, 24763, 24753, 24797, 24792, 24774, 24794, - 24756, 24864, 24870, 24853, 24867, 24820, 24832, 24846, 24875, 24906, - 24949, 25004, 24980, 24999, 25015, 25044, 25077, 24541, 38579, 38377, - 38379, 38385, 38387, {f: 2, c: 38389}, 38396, 38398, {f: 2, c: 38403}, - 38406, 38408, {f: 4, c: 38410}, 38415, 38418, {f: 3, c: 38421}, - {f: 2, c: 38425}, 20012, [12121, 29247], 25109, 27701, 27732, 27740, 27722, - 27811, 27781, 27792, 27796, 27788, {f: 2, c: 27752}, 27764, 27766, 27782, - 27817, 27856, 27860, 27821, {f: 2, c: 27895}, 27889, 27863, 27826, 27872, - 27862, 27898, 27883, 27886, 27825, 27859, 27887, 27902, 27961, 27943, - 27916, 27971, 27976, 27911, 27908, 27929, 27918, 27947, 27981, 27950, - 27957, 27930, 27983, 27986, 27988, 27955, 28049, 28015, 28062, 28064, - 27998, {f: 2, c: 28051}, 27996, 28000, 28028, 28003, 28186, 28103, 28101, - 28126, 28174, 28095, 28128, 28177, 28134, 28125, 28121, 28182, 28075, - 28172, 28078, 28203, 28270, 28238, 28267, 28338, 28255, 28294, - {f: 2, c: 28243}, 28210, 28197, 28228, 28383, 28337, 28312, 28384, 28461, - 28386, 28325, 28327, 28349, 28347, 28343, 28375, 28340, 28367, 28303, - 28354, 28319, 28514, {f: 2, c: 28486}, 28452, 28437, 28409, 28463, 28470, - 28491, 28532, 28458, 28425, 28457, 28553, 28557, 28556, 28536, 28530, - 28540, 28538, 28625, 28617, 28583, 28601, 28598, 28610, 28641, 28654, - 28638, 28640, 28655, 28698, 28707, 28699, 28729, 28725, 28751, 28766, - [12071, 23424], 23428, 23445, 23443, 23461, 23480, 29999, 39582, 25652, - 23524, 23534, 35120, 23536, 36423, 35591, 36790, 36819, 36821, 36837, - 36846, 36836, 36841, 36838, 36851, 36840, 36869, 36868, 36875, 36902, - 36881, 36877, 36886, 36897, {f: 2, c: 36917}, 36909, 36911, 36932, - {f: 2, c: 36945}, 36944, 36968, 36952, 36962, 36955, 26297, 36980, 36989, - 36994, 37000, 36995, 37003, [12089, 24400], 24407, 24406, 24408, 23611, - 21675, 23632, 23641, 23409, 23651, 23654, 32700, 24362, 24361, 24365, - 33396, 24380, 39739, [12076, 23662], 22913, 22915, 22925, {f: 2, c: 22953}, - 22947, 22935, 22986, 22955, 22942, 22948, 22994, 22962, 22959, 22999, - 22974, {f: 2, c: 23045}, 23005, 23048, 23011, 23000, 23033, 23052, 23049, - 23090, 23092, 23057, 23075, 23059, 23104, 23143, 23114, 23125, 23100, - 23138, 23157, 33004, 23210, 23195, 23159, 23162, 23230, 23275, 23218, - 23250, 23252, 23224, 23264, 23267, 23281, 23254, 23270, 23256, 23260, - 23305, 23319, 23318, 23346, 23351, 23360, 23573, 23580, 23386, 23397, - 23411, 23377, 23379, 23394, 39541, {f: 2, c: 39543}, 39546, 39551, 39549, - {f: 2, c: 39552}, 39557, 39560, 39562, 39568, {f: 2, c: 39570}, 39574, - 39576, {f: 3, c: 39579}, {f: 2, c: 39583}, {f: 2, c: 39586}, 39589, 39591, - 32415, 32417, 32419, 32421, {f: 2, c: 32424}, 32429, 32432, 32446, - {f: 3, c: 32448}, 32457, {f: 2, c: 32459}, 32464, 32468, 32471, 32475, - {f: 2, c: 32480}, 32488, 32491, {f: 2, c: 32494}, {f: 2, c: 32497}, 32525, - 32502, {f: 2, c: 32506}, 32510, {f: 3, c: 32513}, {f: 2, c: 32519}, - {f: 2, c: 32523}, 32527, {f: 2, c: 32529}, 32535, 32537, 32540, 32539, - 32543, {f: 7, c: 32545}, {f: 4, c: 32554}, {f: 5, c: 32559}, 32565, - [12083, 24186], 30079, [12078, 24027], 30014, 37013, 29582, 29585, 29614, - 29602, 29599, 29647, 29634, 29649, 29623, 29619, 29632, 29641, 29640, - 29669, 29657, 39036, 29706, 29673, 29671, 29662, 29626, 29682, 29711, - 29738, 29787, 29734, 29733, 29736, 29744, 29742, 29740, 29723, 29722, - 29761, 29788, 29783, 29781, 29785, 29815, 29805, 29822, 29852, 29838, - {f: 2, c: 29824}, 29831, 29835, 29854, {f: 2, c: 29864}, 29840, 29863, - 29906, 29882, {f: 3, c: 38890}, 26444, 26451, 26462, 26440, 26473, 26533, - 26503, 26474, 26483, 26520, 26535, 26485, 26536, 26526, 26541, 26507, - 26487, 26492, 26608, 26633, 26584, 26634, 26601, 26544, 26636, 26585, - 26549, 26586, 26547, 26589, 26624, 26563, 26552, 26594, 26638, 26561, - 26621, {f: 2, c: 26674}, {f: 2, c: 26720}, 26702, 26722, 26692, 26724, - 26755, 26653, 26709, 26726, 26689, 26727, 26688, 26686, 26698, 26697, - 26665, 26805, 26767, 26740, 26743, 26771, 26731, 26818, 26990, 26876, - {f: 2, c: 26911}, 26873, 26916, 26864, 26891, 26881, 26967, 26851, 26896, - 26993, 26937, 26976, 26946, 26973, 27012, 26987, 27008, 27032, 27000, - 26932, 27084, {f: 2, c: 27015}, 27086, 27017, 26982, 26979, 27001, 27035, - 27047, 27067, 27051, 27053, 27092, 27057, 27073, 27082, 27103, 27029, - 27104, 27021, 27135, 27183, 27117, {f: 2, c: 27159}, 27237, 27122, 27204, - 27198, 27296, 27216, 27227, 27189, 27278, 27257, 27197, 27176, 27224, - 27260, 27281, 27280, 27305, 27287, 27307, 29495, 29522, {f: 2, c: 27521}, - 27527, 27524, {f: 2, c: 27538}, 27533, {f: 2, c: 27546}, 27553, 27562, - 36715, 36717, {f: 3, c: 36721}, {f: 2, c: 36725}, 36728, 36727, - {f: 2, c: 36729}, 36732, 36734, {f: 2, c: 36737}, 36740, 36743, 36747, - {f: 3, c: 36749}, 36760, 36762, 36558, 25099, 25111, 25115, 25119, 25122, - 25121, 25125, 25124, 25132, 33255, 29935, 29940, 29951, 29967, 29969, - 29971, [12097, 25908], {f: 3, c: 26094}, 26122, 26137, 26482, 26115, 26133, - 26112, 28805, 26359, 26141, 26164, 26161, 26166, 26165, 32774, 26207, - 26196, 26177, 26191, 26198, 26209, 26199, 26231, 26244, 26252, 26279, - 26269, 26302, {f: 2, c: 26331}, 26342, 26345, {f: 2, c: 36146}, 36150, - 36155, 36157, 36160, {f: 2, c: 36165}, {f: 2, c: 36168}, 36167, 36173, - 36181, 36185, 35271, {f: 3, c: 35274}, {f: 4, c: 35278}, 29294, 29343, - 29277, 29286, 29295, {f: 2, c: 29310}, 29316, 29323, 29325, 29327, 29330, - 25352, 25394, 25520, 25663, 25816, 32772, 27626, 27635, 27645, 27637, - 27641, 27653, 27655, 27654, 27661, 27669, {f: 3, c: 27672}, 27681, 27689, - 27684, 27690, 27698, 25909, 25941, 25963, 29261, 29266, 29270, 29232, - 34402, 21014, 32927, 32924, 32915, 32956, 26378, 32957, 32945, 32939, - 32941, 32948, 32951, {f: 4, c: 32999}, 32987, 32962, 32964, 32985, 32973, - 32983, 26384, 32989, 33003, 33009, 33012, 33005, {f: 2, c: 33037}, 33010, - 33020, 26389, 33042, 35930, 33078, 33054, 33068, 33048, 33074, 33096, - 33100, 33107, 33140, {f: 2, c: 33113}, 33137, 33120, 33129, - {f: 2, c: 33148}, 33133, 33127, 22605, 23221, 33160, 33154, 33169, 28373, - 33187, 33194, 33228, 26406, 33226, 33211, 33217, 33190, 27428, 27447, - 27449, 27459, 27462, 27481, {f: 3, c: 39121}, 39125, {f: 2, c: 39129}, - [12110, 27571], 24384, 27586, 35315, 26000, 40785, 26003, 26044, 26054, - 26052, 26051, 26060, 26062, 26066, 26070, 28800, 28828, 28822, 28829, - 28859, 28864, 28855, 28843, 28849, 28904, 28874, 28944, 28947, 28950, - 28975, 28977, 29043, 29020, 29032, 28997, 29042, 29002, 29048, 29050, - 29080, 29107, 29109, 29096, 29088, 29152, 29140, 29159, 29177, 29213, - 29224, 28780, 28952, 29030, 29113, 25150, 25149, 25155, {f: 2, c: 25160}, - 31035, 31040, 31046, 31049, {f: 2, c: 31067}, 31059, 31066, 31074, 31063, - 31072, 31087, 31079, 31098, 31109, 31114, 31130, 31143, 31155, 24529, - 24528, 24636, 24669, 24666, 24679, 24641, 24665, 24675, 24747, 24838, - 24845, 24925, 25001, 24989, 25035, 25041, 25094, 32896, [12160, 32895], - 27795, 27894, 28156, 30710, 30712, 30720, 30729, {f: 2, c: 30743}, 30737, - 26027, 30765, {f: 2, c: 30748}, {f: 3, c: 30777}, 30751, 30780, 30757, - 30764, 30755, 30761, 30798, 30829, {f: 2, c: 30806}, 30758, 30800, 30791, - 30796, 30826, 30875, 30867, 30874, 30855, 30876, 30881, 30883, 30898, - 30905, 30885, 30932, 30937, 30921, 30956, 30962, 30981, 30964, 30995, - 31012, 31006, 31028, 40859, [12235, 40697], {f: 2, c: 40699}, 30449, 30468, - 30477, 30457, {f: 2, c: 30471}, 30490, 30498, 30489, 30509, 30502, 30517, - 30520, {f: 2, c: 30544}, 30535, 30531, 30554, 30568, 30562, 30565, 30591, - 30605, 30589, 30592, 30604, 30609, {f: 2, c: 30623}, 30640, 30645, 30653, - 30010, 30016, 30030, 30027, 30024, 30043, 30066, 30073, 30083, 32600, - 32609, 32607, 35400, 32616, 32628, 32625, 32633, 32641, 32638, 30413, - 30437, 34866, {f: 3, c: 38021}, 38027, 38026, {f: 2, c: 38028}, - {f: 2, c: 38031}, 38036, 38039, 38037, {f: 3, c: 38042}, {f: 2, c: 38051}, - 38059, 38058, 38061, 38060, {f: 2, c: 38063}, 38066, 38068, - {f: 5, c: 38070}, {f: 2, c: 38076}, 38079, 38084, {f: 7, c: 38088}, - {f: 3, c: 38096}, {f: 3, c: 38101}, 38105, 38104, 38107, {f: 3, c: 38110}, - 38114, {f: 2, c: 38116}, {f: 2, c: 38119}, 38122, 38121, 38123, - {f: 2, c: 38126}, {f: 3, c: 38131}, 38135, 38137, {f: 2, c: 38140}, 38143, - 38147, 38146, {f: 2, c: 38150}, {f: 2, c: 38153}, {f: 3, c: 38157}, - {f: 5, c: 38162}, 38168, 38171, {f: 3, c: 38173}, 38178, {f: 2, c: 38186}, - 38185, 38188, {f: 2, c: 38193}, 38196, {f: 3, c: 38198}, 38204, - {f: 2, c: 38206}, 38210, 38197, {f: 3, c: 38212}, 38217, 38220, - {f: 2, c: 38222}, {f: 3, c: 38226}, {f: 4, c: 38230}, 38235, - {f: 2, c: 38238}, 38237, {f: 2, c: 38241}, {f: 9, c: 38244}, 38255, - {f: 3, c: 38257}, 38202, 30695, 30700, 38601, 31189, 31213, 31203, 31211, - 31238, 23879, 31235, 31234, 31262, 31252, 31289, 31287, 31313, 40655, - 39333, 31344, 30344, 30350, 30355, 30361, 30372, 29918, 29920, 29996, - 40480, 40482, {f: 5, c: 40488}, 40498, 40497, 40502, 40504, 40503, - {f: 2, c: 40505}, 40510, {f: 2, c: 40513}, 40516, {f: 4, c: 40518}, - {f: 2, c: 40523}, 40526, 40529, 40533, 40535, {f: 3, c: 40538}, 40542, - 40547, {f: 7, c: 40550}, 40561, 40557, 40563, [12135, 30098], 30100, 30102, - 30112, 30109, 30124, 30115, {f: 2, c: 30131}, 30136, 30148, 30129, 30128, - 30147, 30146, 30166, 30157, 30179, 30184, 30182, 30180, 30187, 30183, - 30211, 30193, 30204, 30207, 30224, 30208, 30213, 30220, 30231, 30218, - 30245, 30232, 30229, 30233, 30235, 30268, 30242, 30240, 30272, 30253, - 30256, 30271, 30261, 30275, 30270, 30259, 30285, 30302, 30292, 30300, - 30294, 30315, 30319, 32714, 31462, {f: 2, c: 31352}, 31360, 31366, 31368, - 31381, 31398, 31392, 31404, 31400, 31405, 31411, 34916, 34921, 34930, - 34941, 34943, 34946, 34978, 35014, 34999, 35004, 35017, 35042, 35022, - 35043, 35045, 35057, 35098, 35068, 35048, 35070, 35056, 35105, 35097, - 35091, 35099, 35082, 35124, 35115, 35126, 35137, 35174, 35195, - [12134, 30091], 32997, 30386, 30388, 30684, [12158, 32786], 32788, 32790, - 32796, 32800, 32802, {f: 3, c: 32805}, 32809, 32808, 32817, 32779, 32821, - 32835, 32838, 32845, 32850, 32873, 32881, 35203, 39032, 39040, 39043, - 39049, {f: 2, c: 39052}, 39055, 39060, {f: 2, c: 39066}, {f: 2, c: 39070}, - {f: 2, c: 39073}, {f: 2, c: 39077}, [12172, 34381], 34388, 34412, 34414, - 34431, 34426, 34428, 34427, 34472, 34445, 34443, 34476, 34461, 34471, - 34467, 34474, 34451, 34473, 34486, 34500, 34485, 34510, 34480, 34490, - 34481, 34479, 34505, 34511, 34484, 34537, {f: 2, c: 34545}, 34541, 34547, - 34512, 34579, 34526, 34548, 34527, 34520, 34513, 34563, 34567, 34552, - 34568, 34570, 34573, 34569, 34595, 34619, 34590, 34597, 34606, 34586, - 34622, 34632, 34612, 34609, 34601, 34615, 34623, 34690, 34594, - {f: 2, c: 34685}, 34683, 34656, 34672, 34636, 34670, 34699, 34643, 34659, - 34684, 34660, 34649, 34661, 34707, 34735, 34728, 34770, 34758, 34696, - 34693, 34733, 34711, 34691, 34731, 34789, 34732, 34741, 34739, 34763, - 34771, 34749, 34769, 34752, 34762, 34779, 34794, 34784, 34798, 34838, - 34835, 34814, 34826, 34843, 34849, 34873, 34876, [12152, 32566], 32578, - {f: 2, c: 32580}, 33296, 31482, 31485, 31496, {f: 2, c: 31491}, 31509, - 31498, 31531, 31503, 31559, 31544, 31530, 31513, 31534, 31537, 31520, - 31525, 31524, 31539, 31550, 31518, 31576, 31578, 31557, 31605, 31564, - 31581, 31584, 31598, 31611, 31586, 31602, 31601, 31632, {f: 2, c: 31654}, - 31672, 31660, 31645, 31656, 31621, 31658, 31644, 31650, 31659, 31668, - 31697, 31681, 31692, 31709, 31706, {f: 2, c: 31717}, 31722, 31756, 31742, - 31740, 31759, 31766, 31755, 31775, 31786, 31782, 31800, 31809, 31808, - 33278, {f: 2, c: 33281}, 33284, 33260, 34884, {f: 3, c: 33313}, 33325, - 33327, 33320, 33323, 33336, 33339, {f: 2, c: 33331}, 33342, 33348, 33353, - 33355, 33359, 33370, 33375, 33384, 34942, 34949, 34952, 35032, 35039, - 35166, 32669, 32671, 32679, {f: 2, c: 32687}, 32690, 31868, 25929, 31889, - 31901, 31900, 31902, 31906, 31922, {f: 2, c: 31932}, 31937, 31943, - {f: 2, c: 31948}, 31944, 31941, 31959, 31976, [12169, 33390], 26280, 32703, - 32718, 32725, 32741, 32737, 32742, 32745, 32750, 32755, [12151, 31992], - 32119, 32166, 32174, 32327, 32411, 40632, 40628, 36211, 36228, 36244, - 36241, 36273, 36199, 36205, 35911, 35913, 37194, 37200, {f: 2, c: 37198}, - 37220, 37218, 37217, 37232, 37225, 37231, {f: 2, c: 37245}, 37234, 37236, - 37241, 37260, 37253, 37264, 37261, 37265, {f: 2, c: 37282}, 37290, - {f: 3, c: 37293}, 37301, 37300, 37306, [12183, 35925], 40574, 36280, 36331, - 36357, 36441, 36457, 36277, 36287, 36284, 36282, 36292, {f: 2, c: 36310}, - 36314, 36318, {f: 2, c: 36302}, 36315, 36294, 36332, {f: 2, c: 36343}, - 36323, 36345, 36347, 36324, 36361, 36349, 36372, 36381, 36383, 36396, - 36398, 36387, 36399, 36410, 36416, 36409, 36405, 36413, 36401, 36425, - {f: 2, c: 36417}, {f: 2, c: 36433}, 36426, 36464, 36470, 36476, 36463, - 36468, 36485, 36495, 36500, 36496, 36508, 36510, [12184, 35960], 35970, - 35978, 35973, 35992, 35988, 26011, 35286, 35294, 35290, 35292, 35301, - 35307, 35311, 35390, 35622, 38739, 38633, 38643, 38639, 38662, 38657, - 38664, 38671, 38670, 38698, 38701, 38704, 38718, 40832, 40835, - {f: 6, c: 40837}, 40844, 40702, 40715, 40717, [12203, 38585], - {f: 2, c: 38588}, 38606, 38610, 30655, 38624, 37518, 37550, 37576, 37694, - 37738, 37834, 37775, 37950, 37995, 40063, 40066, {f: 4, c: 40069}, 31267, - 40075, 40078, {f: 3, c: 40080}, {f: 2, c: 40084}, {f: 2, c: 40090}, - {f: 6, c: 40094}, {f: 5, c: 40101}, 40107, {f: 2, c: 40109}, - {f: 8, c: 40112}, {f: 4, c: 40122}, {f: 4, c: 40132}, {f: 7, c: 40138}, - {f: 3, c: 40147}, {f: 3, c: 40151}, {f: 2, c: 40156}, 40159, 40162, 38780, - 38789, {f: 2, c: 38801}, 38804, 38831, 38827, 38819, 38834, 38836, 39601, - 39600, 39607, 40536, 39606, 39610, 39612, 39617, 39616, 39621, 39618, - {f: 2, c: 39627}, 39633, 39749, 39747, 39751, 39753, 39752, 39757, 39761, - 39144, 39181, 39214, 39253, 39252, [12221, 39647], 39649, 39654, 39663, - 39659, 39675, 39661, 39673, 39688, 39695, 39699, 39711, 39715, - {f: 2, c: 40637}, 32315, 40578, {f: 2, c: 40583}, 40587, 40594, 37846, - 40605, 40607, {f: 3, c: 40667}, 40672, 40671, 40674, 40681, 40679, 40677, - 40682, 40687, 40738, 40748, 40751, 40761, 40759, {f: 2, c: 40765}, 40772, - 12295, {s: 13}, 30362, 34297, 31001, 24859, 39599, 35158, 22761, 32631, - 25850, 25943, 38930, 36774, 32070, 24171, 32129, 37770, 35607, 39165, - 23542, 22577, 39825, 36649, [12185, 35997], 37575, 29437, 20633, 24970, - 32179, 31558, 30050, 25987, 24163, 38281, 37002, 32232, 36022, 35722, - 36783, 36782, 27161, 40009, 30303, 28693, 28657, 36051, 25839, 39173, - 25765, 37474, 37457, 39361, 35036, 36001, 21443, 34870, 27544, 24922, - 24920, 29158, 33980, 33369, 20489, 28356, 21408, 20596, 28204, 23652, - 35435, 25881, 25723, 34796, 39262, 35730, 32399, 37855, 29987, 38369, - 39019, 22580, 22039, [12199, 38263], 20767, 33144, 24288, 26274, 37396, - [12190, 36554], 24505, 22645, 38515, 35183, 31281, 25074, 35488, 39425, - 36978, 39347, [12242, 40786], 29118, 34909, 34802, 23541, 30087, 36490, - 31820, 32162, 37276, 37604, 38619, 30990, 20786, 35320, 34389, 20659, - 30241, 38358, 21109, 37656, 32020, 32189, 36781, 35422, 36060, 32880, - 24478, 21474, 36517, 31428, 37679, 36948, 24118, 36024, 25812, 21934, - 37170, 25763, 33213, 24986, 35477, 24392, 30070, 25803, 40680, 34153, - 27284, 25623, 23798, 31153, 23566, 29128, 37159, 25973, 28364, 36958, - 32224, 39003, 40670, 22666, 38651, 28593, 37347, 35519, 35548, 37336, - 38914, 37664, 35330, 26481, 21205, 26847, 20941, [12222, 39717], 29346, - 29544, 35712, 36077, 37709, 37723, 26039, 32222, 38538, 23565, 22136, - 38931, 37389, 22890, 22702, 40285, 38989, 35355, 24801, 39187, 20818, - 29246, 39180, 36019, 30332, 32624, 38309, 31020, 37353, 29033, 31684, - 36009, 39151, 35370, 32033, [12214, 39131], 35513, 24290, 36027, 32027, - 22707, 22894, 24996, 31966, 35920, 26963, 37586, [12213, 39080], 30219, - 39342, 32299, 35575, 40179, 33178, 36667, 25771, 36628, 36070, 24489, - 36000, 35331, 23142, 32283, 35442, 37411, 33995, 24185, 36245, 36123, - 23713, 21083, 37628, 32177, 23831, 37804, 25841, 40255, 38307, 37499, - 20491, 32102, 40852, 38799, 36002, 37390, 28317, 27083, 36092, 34865, - 39015, 21102, 38364, 35264, 39208, 24931, 36011, 24291, 35215, 27512, - [12244, 40860], 38312, 36556, 35437, 27331, 36020, 21130, 36645, 37707, - 22283, 36942, 39405, 38867, 28450, 34399, 38305, 40372, 36032, 36703, - 40251, 32005, 22778, 35703, 28396, 22057, 33775, 30059, 21123, 35441, - 25079, 22750, 27489, 29872, 36996, 32233, 35594, 25582, 36637, 36036, - 31330, 26371, 29172, 21295, 35569, 35496, 32362, 33911, 28222, 29554, - 36008, 31117, 25802, 27231, 31309, 39249, 35663, 40388, 32318, 32221, - 26997, 36655, 32026, 25824, 24190, 34186, 21137, 28639, 35336, 35352, - 38555, 32380, 32000, 22846, 33698, 38960, 36040, 37440, 20729, 39381, - 27570, 30435, 22533, 31627, 38291, 33393, 32216, 32365, 27298, 40572, - 25536, 25791, 31777, 20745, 34214, 27323, 37970, 36368, 36068, - [12178, 35211], 37749, 33382, 21133, 39198, 28472, 28666, 28567, 23559, - 28479, 34083, 27123, 22892, 35611, 37292, 33184, 28550, 39509, 23308, - 25898, 37496, 30703, 20709, 39171, 32371, 32094, 36686, 36611, 38542, - 31680, 28500, 32080, 35489, 32202, 37670, 20677, 35641, 36914, 29180, - 30433, 21185, 33686, 39912, 39514, 32147, 38968, 37857, 24465, 30169, - 31478, 31998, 33290, 39378, 33289, 25818, 37624, 25084, 21127, 40273, - 32121, 35258, 35363, 32118, 37406, 36557, 39423, 38283, 20977, 38982, - 27579, 35506, 22718, 25031, 25715, 24235, 35122, 35463, 22602, 20744, - 23532, 31014, 26336, 34407, 24011, 31418, 39243, 28528, 25844, 38346, - 34847, 33240, 33802, 20358, 36084, 34253, 27396, 25876, 31811, 38348, - 34349, 28734, 35733, 25900, 35261, 25078, 32412, 29211, 28651, 25736, - 21214, 28551, 27138, 37939, 22744, 39006, 31852, 38626, 28757, 35023, - 39881, 31150, 40599, 21426, 21237, 31019, 27511, 28701, 38584, 20486, - 32879, 34030, 36899, 37934, 24976, 28451, 31806, 25986, 33225, 37832, - 25088, 29001, 32244, 31975, 20841, 36635, 35538, 30274, 36988, 37904, - 29557, 33256, 37168, 40023, 36035, 40801, 37428, 38728, 23994, 38936, - 39230, 21129, [12243, 40845], 32894, 22184, 31840, 22751, 25871, 38580, - 27155, 23105, 25695, 31757, 34310, 30439, 39025, 24300, 29200, 25796, - 28407, 34396, 39791, 36034, 37682, 38520, 39522, 37569, 23650, 32311, - 24942, 28670, 32209, 24018, 25891, 23423, 28772, 20098, 25476, 36650, - 20523, 20374, 28138, 32184, 35542, 34367, 32645, 37007, 38012, 31854, - 39486, 39409, 32097, 23229, 29802, 30908, 34718, [12218, 39340], 39393, - 21966, 36023, [12230, 40613], 36067, 36993, 30622, 39237, 34875, 28415, - 35646, 37672, 37466, 36031, 37762, [12200, 38272], 24758, 20497, 37683, - 22818, 35598, 24396, 35219, 32191, 32236, 24287, 28357, 25003, 38313, - 40180, 37528, 35628, 35584, 30045, 37385, 32013, 38627, 25747, 33126, - 24817, 39719, 39186, 25836, 33193, 25862, 37312, [12227, 40165], 32886, - 22169, 38007, 37811, 27320, 29552, 23527, 25840, 28632, 37397, 32016, - 33215, 28611, 36786, 30247, 35582, 27472, 40407, 27590, 22036, 28442, - 30436, 40848, 36064, 22132, 40300, 39449, 39108, 38971, 36007, 34315, - 24977, 35413, 28497, 38935, 25778, 37610, 20693, 27192, 35676, 33229, - [12241, 40778], 39438, 35912, 21843, 27683, 35350, 29309, 37370, 37467, - 36983, 31805, 35609, 37666, 37463, 28154, 35700, 22649, 27085, 21958, - 22715, 34196, 25654, 37740, 27211, 21932, 20689, 32761, 31429, 31434, - 27453, 35242, 23522, 36629, 27691, 20670, 38915, 35531, 24950, 29898, - 31406, 36264, 21312, 36544, 39493, 40818, 39028, 27402, 21240, 40306, - 30906, 35731, 39250, 25854, 32350, 29105, 38860, 35469, 32009, 27054, - 32104, 36575, 37613, 38287, 28516, 28753, 34217, 39955, 36093, 20632, - 21930, 39479, 25475, 28544, 27578, 32023, 31721, 26348, 38275, 38493, - 36109, 32341, 20663, 36062, 29138, 32057, 36050, 25448, 25885, 25086, - 35373, 32051, 23529, 23352, 33102, 28402, 32882, 32361, 21213, 32854, - 24107, 29509, 28629, 35433, 26178, 34645, 23526, 35672, 39387, 21218, - 36969, 37323, 39166, 35222, 35430, 22781, 29560, 27166, 36664, 26360, - 36118, 23660, 34899, 27193, 31466, 25976, 24101, 38617, 35504, 38918, - 35500, 30889, 29197, 32114, 39164, 39686, 32883, 24939, 38924, 35359, - 35494, 25851, 34311, 35380, 32901, 38614, 38568, 32143, 27506, 23403, - 25613, 32302, 29795, 37782, 29562, 25787, 33274, 24907, 25892, 36010, - 30321, 28760, 22727, 35674, 35527, 22022, 28271, 29145, 28644, 32295, - 35342, 39472, 35588, 37563, 38988, 39636, 26781, 36028, 37941, 24307, - 32893, 28916, 37509, 32113, 38957, 22294, 22615, 22296, 38973, 40213, - 39345, 39389, 27234, 31402, 35178, 24398, 28771, 38929, 33836, 32178, - [12209, 38859], 36949, 22285, 29234, 28656, 32173, 33894, 20553, 20702, - 32239, 35586, 34907, 32862, 32011, 31337, 21839, 25790, 34680, 28198, - 31401, 21978, 37794, 28879, 35491, 28961, 34154, 22626, 38695, 21209, - 35492, 37675, 29351, 35186, 32722, 37521, 25138, 32048, 34662, 36676, - 23805, 20448, 29433, 22151, 37697, 39854, 32406, 36066, 37532, 38289, - 39023, 38570, 29694, 29563, 32291, 39201, 25010, 32171, 38002, 37129, - 35443, 38911, 38917, 34157, 22210, 37559, 26313, 22063, 21332, 25406, - 33029, 35559, 23531, 28681, 35613, 37573, 37313, 33288, 37561, 32137, - 38920, 35377, 32210, 32396, 36562, 25080, 36984, 30316, 32098, 23416, - 21211, 35426, 23563, 39348, 35347, 35338, 36956, 22739, 40201, 40232, - 21854, 20126, 35357, 38329, 40573, 22196, 38996, 38331, 33399, 21421, - 30831, 35578, 39511, 40230, 26954, 25562, 30221, 38525, 30306, 39178, - 27171, 22575, 35617, 34277, 29242, [12212, 38913], 26989, 33865, 37291, - 37541, 38948, 36986, 20736, 34811, 34269, 20740, 25014, 32681, 35427, - 35696, 35516, 35695, 32377, 34093, 38512, 37504, 39154, 38577, 27387, - 23344, 40441, 25033, 32403, 29801, 34722, 29151, 29074, 34821, 36111, - 31310, 21938, 25793, 20653, 30320, 36404, 20778, 24962, 37109, 37438, - 29494, 35480, 36671, 39192, [12226, 39770], 28417, 33287, 23996, 35486, - 39729, 29508, 35709, 38928, 39341, 40219, 28149, 36677, 22290, 21729, - 22291, 32227, 36960, 39000, 32004, 36493, 38000, 38322, 38642, 37142, - 38549, 36939, 34292, 37270, 26248, 38620, 36617, 25890, 26283, 36106, - 36124, 33247, 38015, 26839, 31432, 36012, 25799, 21063, 28580, 36042, - 36104, 36555, 37720, 38296, 35408, 40779, 20661, 27656, 30430, 26028, - 36670, 23940, 26855, 25136, 32187, 24373, 28466, 24115, 36076, 33081, - 36249, 34756, 36685, 37754, 36889, 35998, 37341, 20597, 35386, 37806, - 38499, 24128, 30309, 37165, 35657, 32340, 32887, 22519, 34937, 32025, - 25711, 25842, 24159, 36074, 28399, 37912, 32066, 31278, 33131, 34886, - 35589, 36600, 30394, 26205, 39519, 35576, 35461, 29165, 30682, 22225, - 36015, 37956, 31689, 39376, 23560, 30938, 36681, 36090, 27137, 33674, - 35037, 22941, 22767, 29376, 37648, 36101, 22684, 32180, 35524, 28310, - 28609, 36039, 28460, 32156, 32317, 32305, 37138, 35419, 32068, 38013, - 21959, 21401, 21428, 38760, 36107, 21293, 21297, 36094, 21060, 21132, - 21108, 20660, 20480, 20630, 20757, 20738, 20756, 20796, 20791, 20712, - 20674, 20795, 20752, 20794, 20681, 31988, 40652, 22213, 40172, 35131, - 33248, 35329, 35344, 35340, 35349, 35635, 35406, 35365, 35393, 35382, - 35398, 35412, 35416, 35410, 35462, 35460, 35455, 35440, 35452, 35445, - 35436, 35438, 35533, 35554, 35425, 35482, 35493, {f: 2, c: 35473}, 35535, - 35537, 35529, 35547, 35543, 35522, 35510, 35574, 35563, 35604, 35585, - 35556, 35565, 35580, 35571, 35558, 35566, 35550, 35624, 35740, 35606, - 35610, 35600, 35627, 35629, 35670, 35673, 35662, 35742, 35691, 35734, - 38488, 37178, 37140, 37172, 37087, 37174, 37126, 37192, 33467, 21233, - 24048, 22538, 22745, 22754, 22752, 22746, 22497, 22607, 22550, 22610, - 22557, 22628, 34188, 34131, 34294, 33703, 33799, 34031, 33511, 34338, - 34086, 22603, 29026, 34136, 34045, 34126, 34184, 34234, 29334, 28366, - 34113, 34254, 34130, 33984, 33874, 33892, 33940, 33845, 34207, 34133, - 40367, 33939, 32264, 34118, 34146, 34078, 39488, 34362, 37795, 34167, - 34334, 34298, 34308, 34282, 34330, 22889, 23607, 25451, 25718, 25759, - 25681, 25692, 25779, 25860, 25878, 25847, 25852, 25883, 22064, 22072, - 22216, 22182, 21764, 21692, 22144, 22109, 22112, 22069, 22006, 22118, - 22130, 22156, 22117, 22044, 22062, 21993, 22038, 22208, 22029, 22195, - 22209, 22127, 36705, 22198, 22165, 22279, 24131, 24172, 24152, 24151, - 23943, 23796, 23888, 23852, 23975, 23968, 23959, 23821, 23992, 23937, - 24020, 24480, 29559, 29505, 29546, 29499, 29547, 29568, 29564, 39136, - 39219, 39145, 39228, {f: 2, c: 39146}, 39149, 39156, 39177, 39185, 39195, - 39223, 39231, 39235, {f: 3, c: 39240}, 39244, 39266, 24289, 36065, 25082, - 25006, 24938, 24894, 24757, 24884, 25036, 24927, 25064, 24827, 24887, - 24818, 24947, 24860, 24978, 38274, 38278, 38344, 38286, 38292, 38284, - 38373, 38317, 38315, 39726, 38316, 38334, 38326, 39721, 38335, 38333, - 38332, 38339, 38347, 38356, 38352, 38357, 38366, 28739, 28505, 28711, - 28696, 28668, 28039, 28025, 28254, 28590, 28687, 28408, 28527, 28150, - 28543, 28678, 28576, 28683, 28775, 28740, 28677, 28535, 28704, 28703, - 28722, 28712, 28765, 39467, 36999, 36885, 37008, 23656, 24371, 23285, - 23255, 23296, 23149, 23304, 23372, 23207, 23291, 23307, 23329, 23338, - 23321, 39380, 39391, 39385, 39478, 39515, 39377, 39384, 39501, 39498, - 39394, 39530, 39439, 39437, 39429, 39490, 39469, 39446, 39489, 39470, - 39480, {f: 2, c: 39491}, 39503, 39525, 39524, 31993, 32006, 32002, - {f: 2, c: 32007}, 32394, 32028, 32021, 32019, 32058, 32050, 32049, 32272, - 32060, 32064, 32063, 32093, 32078, 32115, 32134, 32131, 32136, 32190, - 32186, 32203, 32212, 32196, 32158, 32172, 32185, 32163, 32176, 32199, - 32217, 32215, 32249, 32242, 32354, 32230, 32246, 32241, 32267, 32225, - 32265, 32285, 32287, 32286, 32301, 32266, 32273, 32381, 32313, 32309, - 32306, 32326, 32325, 32392, 32346, 32338, 32366, 32382, 32368, 32367, - 32408, 29859, 29771, 29903, 38922, 29885, 29759, 29833, 29862, 29908, - 29914, 38873, 38878, 38876, 27050, 27370, 26776, 26838, 27141, 26783, - 27355, 27379, 27368, 27359, 27273, 26895, 27208, 26984, 27071, 27194, - 27292, 27410, 27422, 27357, 27111, 27407, 27414, 27372, 27354, 27384, - 27315, 27367, 27299, 27347, 27358, 27556, 27550, 27566, 27563, 27567, - 36564, 36571, 36594, 36603, 36708, 36601, 36604, 36587, 36580, 36706, - 36602, 36606, 36618, 36615, 36613, 36626, 36646, {f: 2, c: 36638}, 36636, - 36659, 36678, 36692, 25108, 25127, 29964, 26311, 26308, 26249, 26326, - 36033, 36016, 36026, 36029, 36100, 36018, 36037, 36112, 36049, 36058, - 36053, 36075, 36071, 36091, 35224, 35244, 35233, 35263, 35238, 35247, - 35250, 35255, 27647, 27660, 27692, 29272, 26407, 33110, 33242, 33051, - 33214, 33121, 33231, 27487, {f: 2, c: 39086}, 39094, 39100, 39110, 39112, - 36674, 40783, 26005, 29036, 29010, 29079, 29121, 29148, 29182, 31152, - 31118, 31146, 25055, 24932, 25059, 25095, 28585, 30959, 30893, 30824, - 30904, 31018, 31025, 30820, 30973, 30951, 30947, 40853, 30616, 30558, - 30652, 32646, 32648, {f: 3, c: 37330}, 37337, 37335, 37333, 37367, 37351, - 37348, 37702, 37365, 37369, 37384, 37414, 37445, 37393, 37392, 37377, - 37415, 37380, 37413, 37376, 37434, 37478, 37431, 37427, 37461, 37437, - 37432, 37470, {f: 2, c: 37484}, 37439, 37984, 37424, 37449, 37448, 37453, - 37422, 37433, 37944, 37548, 37536, 37498, 37546, 37614, 37583, 37891, - 37603, 37946, 37553, 37542, 37799, 37526, 37580, 37545, 37877, 37523, - 37503, 37801, 37530, 37658, 37547, 37507, 37899, 37544, 37539, 37906, - 37688, 37617, 37847, 37605, 37616, 37615, 37608, 37564, 37597, 37622, - {f: 2, c: 37926}, 37571, 37599, 37606, 37650, 37638, 37737, 37659, 37696, - 37633, 37653, 37678, 37699, {f: 2, c: 37639}, 37663, 37657, 37733, 37703, - 37750, 37716, 37732, 37802, 37744, 37764, 37860, 37848, 37928, 37767, - 37836, 37784, 37816, 37823, 37798, 37808, 37813, 37964, 37858, - {f: 2, c: 37852}, 37837, 37854, 37827, 37831, 37841, 37908, 37917, 37879, - 37989, 37907, 37997, 37920, 38009, 37881, 37913, 37962, 37938, 37951, - 37972, 37987, 37758, 31329, 40169, 40182, 40199, 40198, 40227, 40327, - 40469, 40221, 40223, 40421, 40239, 40409, 40240, 40258, 40478, 40275, - 40477, 40288, 40274, 40435, 40284, 40289, 40339, 40298, 40303, 40329, - 40344, 40346, 40384, 40357, 40361, 40386, 40380, 40474, 40403, 40410, - 40431, 40422, 40434, 40440, 40460, 40442, 40475, 30308, 30296, 30311, - 30210, {f: 2, c: 30278}, 30281, 30238, 30267, {f: 2, c: 30317}, 30313, - 30322, 31431, 31414, 35168, 35123, 35165, 35143, 35128, 35172, 30392, - 32814, 32812, 32889, 32885, 38919, {f: 2, c: 38926}, 38945, 38940, 28481, - 38950, 38967, 38990, 38995, 39027, 39010, 39001, 39013, 39020, 39024, - 34787, 34822, 34566, 34851, 34806, 34554, 34799, 34692, 34832, 34760, - 34833, 34747, 34766, 32588, 31716, 31591, 31849, 31731, 31744, 31691, - 31836, 31774, 31787, 31779, 31850, 31839, 33380, 33387, 35018, 32677, - 31986, 31990, 31965, 32310, 40617, 36274, 37317, 37315, 40570, 36489, - 36428, 36498, 36474, 36437, 36506, 36491, 36499, 36497, 36513, 36451, - 36522, 36518, 35316, 35318, 38746, 38722, 38717, 38724, 40788, 40799, - 40793, 40800, 40796, 40806, 40812, 40810, 40823, [12236, 40701], 40703, - 40713, 35726, 38014, 37864, 39799, 39796, 39809, 39811, 39822, 40056, - 31308, 39826, 40031, 39824, 39853, 39834, 39850, 39838, 40045, 39851, - 39837, 40024, 39873, 40058, 39985, 39993, 39971, 39991, 39872, 39882, - 39879, 39933, 39894, {f: 2, c: 39914}, 39905, 39908, 39911, 39901, 39906, - 39920, 39899, 39924, 39892, 40029, 39944, 39952, 39949, 39954, 39945, - 39935, 39968, 39986, 39981, 39976, 39973, 39977, 39987, 39998, 40008, - 39995, 39989, 40005, 40022, 40020, 40018, 40039, 38851, 38845, 38857, - 40379, 39631, 39638, 39637, 39768, 39758, 39255, 39260, 39714, 40695, - 40690, 35180, 38342, 37686, 24390, 34068, 32404, 40803, 22137, 40725, - 22081, 39662, 35079, 31296, 39091, 38308, 39693, 36852, 24409, 31339, - 39138, 20642, 34193, 20760, 25458, 21067, 30543, 32397, 26310, 30637, - [12228, 40565], 22217, 40692, 28635, 25054, 30663, 28720, 40629, 34890, - 38370, 38854, 31844, 32308, 38822, 40623, 22220, 39089, 27311, 32590, - 31984, 20418, 32363, 40569, 22190, 39706, 33903, 31142, 31858, 39634, - 38587, 32251, 35069, 30787, {f: 10, c: 8560}, {f: 2, c: 714}, 729, 8211, - 8213, 8229, 8245, 8453, 8457, {f: 4, c: 8598}, 8725, 8735, 8739, 8786, - {f: 2, c: 8806}, 8895, {f: 36, c: 9552}, {f: 15, c: 9601}, {f: 3, c: 9619}, - {f: 2, c: 9660}, {f: 4, c: 9698}, 9737, 8853, 12306, {f: 2, c: 12317}, - {f: 9, c: 12321}, 12963, {f: 2, c: 13198}, {f: 3, c: 13212}, 13217, 13252, - 13262, {f: 2, c: 13265}, 13269, 65072, 65506, 65508, 8481, 12849, 8208, - 12540, {f: 2, c: 12443}, {f: 2, c: 12541}, 12294, {f: 2, c: 12445}, - {f: 10, c: 65097}, {f: 4, c: 65108}, {f: 14, c: 65113}, {f: 4, c: 65128}, - 12350, {f: 12, c: 12272}, 19970, {f: 3, c: 19972}, 19983, 19986, 19991, - {f: 3, c: 19999}, 20003, 20006, 20009, {f: 2, c: 20014}, 20017, 20019, - 20021, 20023, 20028, {f: 3, c: 20032}, 20036, 20038, 20042, 20049, 20053, - 20055, {f: 2, c: 20058}, {f: 4, c: 20066}, {f: 2, c: 20071}, - {f: 6, c: 20074}, 20082, {f: 10, c: 20084}, {f: 3, c: 20095}, - {f: 2, c: 20099}, [12037, 20101], 20103, 20106, 20112, {f: 2, c: 20118}, - 20121, {f: 2, c: 20124}, 20131, 20138, {f: 3, c: 20143}, 20148, - {f: 4, c: 20150}, {f: 3, c: 20156}, 20168, 20172, {f: 2, c: 20175}, 20178, - {f: 3, c: 20186}, 20192, 20194, {f: 2, c: 20198}, 20201, {f: 3, c: 20205}, - 20209, 20212, {f: 3, c: 20216}, 20220, 20222, 20224, {f: 7, c: 20226}, - {f: 2, c: 20235}, {f: 5, c: 20242}, {f: 2, c: 20252}, 20257, 20259, - {f: 2, c: 20264}, {f: 3, c: 20268}, 20273, 20275, 20277, 20279, 20281, - 20283, {f: 5, c: 20286}, {f: 2, c: 20292}, {f: 6, c: 20295}, 20306, 20308, - 20310, {f: 2, c: 20321}, 20326, 20328, {f: 2, c: 20330}, {f: 2, c: 20333}, - {f: 2, c: 20337}, 20341, {f: 4, c: 20343}, 20349, {f: 3, c: 20352}, 20357, - 20359, 20362, 20364, 20366, 20368, {f: 2, c: 20370}, 20373, - {f: 3, c: 20376}, 20380, {f: 2, c: 20382}, {f: 2, c: 20385}, 20388, 20395, - 20397, {f: 5, c: 20400}, {f: 9, c: 20406}, {f: 2, c: 20416}, - {f: 4, c: 20422}, {f: 3, c: 20427}, {f: 5, c: 20434}, 20441, 20443, 20450, - {f: 2, c: 20452}, 20455, {f: 2, c: 20459}, 20464, 20466, {f: 4, c: 20468}, - 20473, {f: 3, c: 20475}, 20479, {f: 5, c: 20481}, {f: 2, c: 20487}, 20490, - 20494, 20496, 20499, {f: 3, c: 20501}, 20507, {f: 2, c: 20509}, 20512, - {f: 3, c: 20514}, 20519, {f: 11, c: 20527}, 20539, 20541, {f: 4, c: 20543}, - {f: 3, c: 20548}, {f: 2, c: 20554}, 20557, {f: 5, c: 20560}, - {f: 4, c: 20566}, 20571, {f: 8, c: 20573}, {f: 6, c: 20582}, - {f: 7, c: 20589}, {f: 3, c: 20600}, {f: 2, c: 20604}, {f: 4, c: 20609}, - {f: 2, c: 20614}, {f: 4, c: 20617}, {f: 8, c: 20622}, 20631, - {f: 8, c: 20634}, 20644, 20646, {f: 2, c: 20650}, {f: 4, c: 20654}, 20662, - {f: 2, c: 20664}, {f: 2, c: 20668}, {f: 3, c: 20671}, {f: 2, c: 20675}, - {f: 3, c: 20678}, {f: 5, c: 20682}, 20688, {f: 3, c: 20690}, - {f: 3, c: 20695}, {f: 3, c: 20699}, {f: 6, c: 20703}, {f: 3, c: 20713}, - {f: 4, c: 20719}, 20724, {f: 3, c: 20726}, 20730, {f: 4, c: 20732}, 20737, - 20739, 20741, 20746, {f: 4, c: 20748}, 20753, 20755, {f: 2, c: 20758}, - {f: 6, c: 20761}, 20768, {f: 8, c: 20770}, {f: 7, c: 20779}, - {f: 4, c: 20787}, {f: 2, c: 20792}, {f: 2, c: 20797}, 20802, 20807, 20810, - 20812, {f: 3, c: 20814}, 20819, {f: 3, c: 20823}, 20827, {f: 5, c: 20829}, - {f: 2, c: 20835}, {f: 2, c: 20838}, 20842, 20847, 20850, 20858, - {f: 2, c: 20862}, {f: 2, c: 20867}, {f: 2, c: 20870}, {f: 2, c: 20874}, - {f: 4, c: 20878}, {f: 2, c: 20883}, 20888, 20890, {f: 3, c: 20893}, 20897, - 20899, {f: 5, c: 20902}, {f: 2, c: 20909}, 20916, {f: 3, c: 20920}, - {f: 2, c: 20926}, {f: 3, c: 20929}, 20933, 20936, 20938, 20942, 20944, - {f: 9, c: 20946}, 20956, {f: 2, c: 20958}, {f: 2, c: 20962}, - {f: 6, c: 20965}, 20972, 20974, 20978, 20980, 20983, 20990, - {f: 2, c: 20996}, 21001, {f: 2, c: 21003}, {f: 2, c: 21007}, - {f: 3, c: 21011}, 21020, {f: 2, c: 21022}, {f: 3, c: 21025}, - {f: 3, c: 21029}, 21034, 21036, 21039, {f: 2, c: 21041}, {f: 2, c: 21044}, - 21052, 21054, {f: 2, c: 21061}, {f: 2, c: 21064}, {f: 2, c: 21070}, - {f: 2, c: 21074}, 21077, {f: 4, c: 21079}, 21085, {f: 2, c: 21087}, - {f: 3, c: 21090}, 21094, 21096, {f: 3, c: 21099}, {f: 2, c: 21104}, 21107, - {f: 7, c: 21110}, 21118, 21120, {f: 3, c: 21124}, 21131, {f: 2, c: 21134}, - 21138, {f: 7, c: 21140}, 21148, {f: 4, c: 21156}, {f: 3, c: 21166}, - {f: 10, c: 21172}, 21184, 21186, {f: 3, c: 21188}, 21192, 21194, - {f: 4, c: 21196}, 21201, {f: 2, c: 21203}, 21207, 21210, 21212, - {f: 2, c: 21216}, 21219, {f: 11, c: 21221}, {f: 3, c: 21234}, - {f: 2, c: 21238}, {f: 3, c: 21243}, {f: 4, c: 21249}, 21255, - {f: 4, c: 21257}, 21262, {f: 4, c: 21265}, 21272, {f: 2, c: 21275}, - {f: 2, c: 21278}, 21282, {f: 2, c: 21284}, {f: 3, c: 21287}, - {f: 2, c: 21291}, 21296, {f: 6, c: 21298}, [12054, 21304], - {f: 2, c: 21308}, 21314, 21316, 21318, {f: 3, c: 21323}, 21328, - {f: 2, c: 21336}, 21339, 21341, 21349, 21352, 21354, {f: 2, c: 21356}, - 21362, 21366, 21369, {f: 4, c: 21371}, {f: 2, c: 21376}, 21379, - {f: 2, c: 21383}, 21386, {f: 7, c: 21390}, {f: 2, c: 21398}, - {f: 2, c: 21403}, 21406, 21409, 21412, 21415, {f: 3, c: 21418}, - {f: 3, c: 21423}, 21427, 21429, {f: 4, c: 21431}, {f: 3, c: 21436}, 21440, - {f: 4, c: 21444}, {f: 3, c: 21454}, {f: 2, c: 21458}, 21461, 21466, - {f: 3, c: 21468}, 21473, 21479, 21492, 21498, {f: 3, c: 21502}, 21506, - 21509, 21511, 21515, 21524, {f: 3, c: 21528}, 21532, 21538, - {f: 2, c: 21540}, 21546, 21552, 21555, {f: 2, c: 21558}, 21562, 21565, - 21567, {f: 2, c: 21569}, {f: 2, c: 21572}, 21575, 21577, {f: 4, c: 21580}, - 21585, 21594, {f: 5, c: 21597}, 21603, 21605, 21607, {f: 8, c: 21609}, - 21620, {f: 2, c: 21625}, {f: 2, c: 21630}, 21633, 21635, 21637, - {f: 4, c: 21639}, 21645, 21649, 21651, {f: 2, c: 21655}, 21660, - {f: 5, c: 21662}, 21669, 21678, 21680, 21682, {f: 3, c: 21685}, - {f: 2, c: 21689}, 21694, 21699, 21701, {f: 2, c: 21706}, 21718, 21720, - 21723, 21728, {f: 3, c: 21730}, {f: 2, c: 21739}, {f: 3, c: 21743}, - {f: 6, c: 21748}, 21755, 21758, 21760, {f: 2, c: 21762}, 21765, 21768, - {f: 5, c: 21770}, {f: 2, c: 21778}, {f: 6, c: 21781}, {f: 4, c: 21788}, - 21793, {f: 2, c: 21797}, {f: 2, c: 21800}, 21803, 21805, 21810, - {f: 3, c: 21812}, {f: 4, c: 21816}, 21821, 21824, 21826, 21829, - {f: 2, c: 21831}, {f: 4, c: 21835}, {f: 2, c: 21841}, 21844, - {f: 5, c: 21847}, 21853, {f: 2, c: 21855}, {f: 2, c: 21858}, - {f: 2, c: 21864}, 21867, {f: 6, c: 21871}, {f: 2, c: 21881}, 21885, 21887, - {f: 2, c: 21893}, {f: 3, c: 21900}, 21904, {f: 2, c: 21906}, - {f: 3, c: 21909}, {f: 2, c: 21914}, 21918, {f: 7, c: 21920}, - {f: 2, c: 21928}, 21931, 21933, {f: 2, c: 21935}, 21940, 21942, 21944, - 21946, 21948, {f: 5, c: 21951}, 21960, {f: 2, c: 21962}, {f: 2, c: 21967}, - 21973, {f: 3, c: 21975}, 21979, 21982, 21984, 21986, 21991, - {f: 2, c: 21997}, {f: 2, c: 22000}, 22004, {f: 5, c: 22008}, 22015, - {f: 4, c: 22018}, 22023, {f: 2, c: 22026}, {f: 4, c: 22032}, 22037, - {f: 2, c: 22041}, 22045, {f: 3, c: 22048}, {f: 2, c: 22053}, 22056, - {f: 2, c: 22058}, 22067, 22071, 22074, {f: 3, c: 22076}, 22080, - {f: 10, c: 22082}, {f: 5, c: 22095}, {f: 2, c: 22101}, {f: 2, c: 22106}, - {f: 2, c: 22110}, 22113, 22115, 22119, {f: 2, c: 22125}, 22128, 22131, - 22133, 22135, 22138, {f: 3, c: 22141}, {f: 4, c: 22145}, {f: 4, c: 22152}, - 22157, {f: 3, c: 22160}, 22164, {f: 3, c: 22166}, {f: 9, c: 22170}, - {f: 2, c: 22180}, 22183, {f: 5, c: 22185}, {f: 3, c: 22192}, 22197, - {f: 4, c: 22200}, {f: 3, c: 22205}, {f: 2, c: 22211}, {f: 2, c: 22214}, - 22219, {f: 4, c: 22221}, {f: 2, c: 22226}, {f: 2, c: 22229}, - {f: 2, c: 22232}, 22236, 22243, {f: 6, c: 22245}, 22252, {f: 2, c: 22254}, - {f: 2, c: 22258}, {f: 3, c: 22262}, {f: 2, c: 22267}, {f: 3, c: 22272}, - 22277, 22284, {f: 4, c: 22286}, {f: 2, c: 22292}, 22295, {f: 3, c: 22297}, - {f: 2, c: 22301}, {f: 3, c: 22304}, {f: 4, c: 22308}, 22315, - {f: 2, c: 22321}, {f: 5, c: 22324}, {f: 2, c: 22332}, 22335, 22337, - {f: 4, c: 22339}, {f: 2, c: 22344}, 22347, {f: 5, c: 22354}, - {f: 2, c: 22360}, {f: 2, c: 22370}, 22373, 22375, 22380, 22382, - {f: 3, c: 22384}, {f: 2, c: 22388}, {f: 3, c: 22392}, {f: 5, c: 22397}, - {f: 4, c: 22407}, {f: 5, c: 22413}, {f: 7, c: 22420}, {f: 4, c: 22428}, - 22437, 22440, 22442, 22444, {f: 3, c: 22447}, 22451, {f: 3, c: 22453}, - {f: 9, c: 22457}, {f: 7, c: 22468}, {f: 2, c: 22476}, {f: 2, c: 22480}, - 22483, {f: 2, c: 22486}, {f: 2, c: 22491}, 22494, {f: 2, c: 22498}, - {f: 8, c: 22501}, 22510, {f: 4, c: 22512}, {f: 2, c: 22517}, - {f: 2, c: 22523}, {f: 2, c: 22526}, 22529, {f: 2, c: 22531}, - {f: 2, c: 22536}, 22540, {f: 3, c: 22542}, {f: 3, c: 22546}, - {f: 2, c: 22551}, {f: 3, c: 22554}, 22559, {f: 2, c: 22562}, - {f: 5, c: 22565}, {f: 4, c: 22571}, {f: 2, c: 22578}, {f: 14, c: 22582}, - {f: 5, c: 22597}, 22606, 22608, 22611, {f: 2, c: 22613}, {f: 5, c: 22617}, - {f: 3, c: 22623}, 22627, {f: 5, c: 22630}, {f: 8, c: 22637}, - {f: 3, c: 22646}, {f: 4, c: 22650}, 22655, 22658, 22660, {f: 3, c: 22662}, - {f: 7, c: 22667}, {f: 5, c: 22676}, 22683, 22685, {f: 8, c: 22688}, - {f: 4, c: 22698}, {f: 4, c: 22703}, {f: 7, c: 22708}, 22717, - {f: 2, c: 22719}, {f: 3, c: 22722}, 22726, {f: 9, c: 22728}, 22738, 22740, - {f: 2, c: 22742}, {f: 3, c: 22747}, 22753, 22755, {f: 4, c: 22757}, 22762, - 22765, {f: 2, c: 22769}, {f: 2, c: 22772}, {f: 2, c: 22775}, - {f: 2, c: 22779}, {f: 4, c: 22782}, 22787, {f: 2, c: 22789}, - {f: 2, c: 22792}, [12066, 22794], {f: 2, c: 22795}, 22798, - {f: 4, c: 22800}, {f: 2, c: 22807}, 22811, {f: 2, c: 22813}, - {f: 2, c: 22816}, 22819, 22822, 22824, 22828, 22832, {f: 2, c: 22834}, - {f: 2, c: 22837}, 22843, 22845, {f: 2, c: 22847}, 22851, {f: 2, c: 22853}, - 22858, {f: 2, c: 22860}, 22864, {f: 2, c: 22866}, 22873, {f: 5, c: 22875}, - 22881, {f: 2, c: 22883}, {f: 3, c: 22886}, 22891, 22893, {f: 4, c: 22895}, - 22901, 22903, {f: 3, c: 22906}, {f: 3, c: 22910}, 22917, 22921, - {f: 2, c: 22923}, {f: 4, c: 22926}, {f: 2, c: 22932}, 22936, - {f: 3, c: 22938}, {f: 4, c: 22943}, {f: 2, c: 22950}, {f: 2, c: 22956}, - {f: 2, c: 22960}, {f: 6, c: 22963}, 22970, {f: 2, c: 22972}, - {f: 7, c: 22975}, {f: 3, c: 22983}, {f: 4, c: 22988}, {f: 2, c: 22997}, - 23001, 23003, {f: 5, c: 23006}, 23012, {f: 2, c: 23014}, {f: 3, c: 23017}, - {f: 12, c: 23021}, 23034, {f: 3, c: 23036}, 23040, 23042, {f: 2, c: 23050}, - {f: 4, c: 23053}, 23058, {f: 4, c: 23060}, {f: 3, c: 23065}, - {f: 2, c: 23069}, {f: 2, c: 23073}, 23076, {f: 3, c: 23078}, - {f: 7, c: 23082}, 23091, 23093, {f: 5, c: 23095}, {f: 3, c: 23101}, - {f: 4, c: 23106}, {f: 2, c: 23111}, {f: 10, c: 23115}, {f: 4, c: 23126}, - {f: 7, c: 23131}, {f: 3, c: 23139}, {f: 2, c: 23144}, {f: 2, c: 23147}, - {f: 6, c: 23150}, {f: 2, c: 23160}, {f: 4, c: 23163}, {f: 18, c: 23168}, - {f: 7, c: 23187}, {f: 11, c: 23196}, {f: 2, c: 23208}, {f: 7, c: 23211}, - 23220, {f: 2, c: 23222}, {f: 4, c: 23225}, {f: 2, c: 23231}, - {f: 6, c: 23235}, {f: 2, c: 23242}, {f: 5, c: 23245}, 23251, 23253, - {f: 3, c: 23257}, {f: 3, c: 23261}, 23266, {f: 2, c: 23268}, - {f: 2, c: 23271}, 23274, {f: 5, c: 23276}, {f: 3, c: 23282}, - {f: 5, c: 23286}, {f: 4, c: 23292}, {f: 7, c: 23297}, 23306, - {f: 9, c: 23309}, 23320, {f: 7, c: 23322}, {f: 8, c: 23330}, - {f: 5, c: 23339}, 23345, 23347, {f: 2, c: 23349}, {f: 7, c: 23353}, - {f: 11, c: 23361}, {f: 3, c: 23373}, 23378, 23382, 23390, {f: 2, c: 23392}, - {f: 2, c: 23399}, {f: 3, c: 23405}, 23410, 23412, {f: 2, c: 23414}, 23417, - {f: 2, c: 23419}, 23422, 23426, 23430, 23434, {f: 2, c: 23437}, - {f: 3, c: 23440}, 23444, 23446, 23455, {f: 3, c: 23463}, {f: 4, c: 23468}, - {f: 2, c: 23473}, 23479, {f: 3, c: 23482}, {f: 2, c: 23488}, 23491, - {f: 4, c: 23496}, {f: 3, c: 23501}, 23505, {f: 9, c: 23508}, 23520, 23523, - 23530, 23533, 23535, {f: 4, c: 23537}, 23543, {f: 2, c: 23549}, 23552, - {f: 2, c: 23554}, 23557, 23564, 23568, {f: 2, c: 23570}, 23575, 23577, - 23579, {f: 4, c: 23582}, 23587, 23590, {f: 4, c: 23592}, {f: 4, c: 23597}, - {f: 2, c: 23602}, {f: 2, c: 23605}, {f: 2, c: 23619}, {f: 2, c: 23622}, - {f: 2, c: 23628}, {f: 3, c: 23634}, {f: 3, c: 23638}, {f: 4, c: 23642}, - 23647, 23655, {f: 3, c: 23657}, 23661, 23664, {f: 7, c: 23666}, - {f: 4, c: 23675}, 23680, {f: 5, c: 23683}, {f: 3, c: 23689}, - {f: 2, c: 23694}, {f: 2, c: 23698}, 23701, {f: 4, c: 23709}, - {f: 5, c: 23716}, 23722, {f: 3, c: 23726}, 23730, 23732, 23734, - {f: 4, c: 23737}, 23742, 23744, {f: 2, c: 23746}, {f: 6, c: 23749}, - {f: 6, c: 23756}, {f: 6, c: 23763}, {f: 7, c: 23770}, {f: 2, c: 23778}, - 23783, 23785, {f: 2, c: 23787}, {f: 2, c: 23790}, {f: 3, c: 23793}, 23797, - {f: 4, c: 23799}, 23804, {f: 4, c: 23806}, {f: 2, c: 23812}, - {f: 5, c: 23816}, {f: 5, c: 23823}, 23829, {f: 3, c: 23832}, - {f: 2, c: 23836}, {f: 5, c: 23839}, 23845, 23848, {f: 2, c: 23850}, - {f: 5, c: 23855}, {f: 8, c: 23861}, {f: 8, c: 23871}, {f: 2, c: 23880}, - {f: 3, c: 23885}, {f: 7, c: 23889}, {f: 2, c: 23897}, 23900, - {f: 11, c: 23902}, 23914, {f: 2, c: 23917}, {f: 4, c: 23920}, - {f: 12, c: 23925}, 23939, {f: 2, c: 23941}, {f: 15, c: 23944}, 23960, - {f: 3, c: 23962}, {f: 2, c: 23966}, {f: 6, c: 23969}, {f: 15, c: 23976}, - 23993, 23995, {f: 8, c: 23997}, {f: 5, c: 24006}, 24012, {f: 4, c: 24014}, - 24019, {f: 6, c: 24021}, 24028, {f: 2, c: 24031}, {f: 2, c: 24035}, 24042, - {f: 2, c: 24044}, {f: 2, c: 24053}, {f: 5, c: 24056}, {f: 2, c: 24063}, - 24068, 24071, {f: 3, c: 24073}, {f: 2, c: 24077}, {f: 2, c: 24082}, 24087, - {f: 7, c: 24094}, {f: 3, c: 24104}, 24108, {f: 2, c: 24111}, 24114, - {f: 2, c: 24116}, {f: 2, c: 24121}, {f: 2, c: 24126}, 24129, - {f: 6, c: 24134}, {f: 7, c: 24141}, 24150, {f: 2, c: 24153}, - {f: 2, c: 24156}, 24160, {f: 7, c: 24164}, {f: 5, c: 24173}, 24181, 24183, - {f: 3, c: 24193}, 24197, {f: 2, c: 24200}, {f: 3, c: 24204}, 24210, 24216, - 24219, 24221, {f: 4, c: 24225}, {f: 3, c: 24232}, 24236, {f: 5, c: 24238}, - 24244, {f: 4, c: 24250}, {f: 10, c: 24255}, {f: 6, c: 24267}, - {f: 2, c: 24276}, {f: 4, c: 24279}, {f: 3, c: 24284}, {f: 4, c: 24292}, - 24297, 24299, {f: 6, c: 24301}, 24309, {f: 2, c: 24312}, {f: 3, c: 24315}, - {f: 3, c: 24325}, 24329, {f: 3, c: 24332}, 24336, 24338, 24340, 24342, - {f: 2, c: 24345}, {f: 3, c: 24348}, {f: 4, c: 24353}, 24360, - {f: 2, c: 24363}, 24366, 24368, 24370, 24372, {f: 3, c: 24374}, 24379, - {f: 3, c: 24381}, {f: 5, c: 24385}, 24391, {f: 3, c: 24393}, 24397, 24399, - 24401, 24404, {f: 3, c: 24410}, {f: 3, c: 24414}, 24419, 24421, - {f: 2, c: 24423}, 24427, {f: 2, c: 24430}, 24434, {f: 3, c: 24436}, 24440, - 24442, {f: 3, c: 24445}, 24451, 24454, {f: 3, c: 24461}, {f: 2, c: 24467}, - 24470, {f: 2, c: 24474}, 24477, 24479, {f: 6, c: 24482}, {f: 2, c: 24491}, - {f: 6, c: 24495}, 24502, 24504, {f: 2, c: 24506}, {f: 5, c: 24510}, - {f: 2, c: 24519}, {f: 2, c: 24522}, 24526, {f: 3, c: 24531}, - {f: 3, c: 24538}, {f: 2, c: 24542}, {f: 2, c: 24546}, {f: 2, c: 24549}, - {f: 2, c: 24552}, 24556, {f: 2, c: 24559}, {f: 3, c: 24562}, - {f: 2, c: 24566}, {f: 2, c: 24569}, 24572, {f: 3, c: 24583}, - {f: 2, c: 24587}, {f: 2, c: 24592}, 24595, {f: 2, c: 24599}, 24602, - {f: 2, c: 24606}, {f: 3, c: 24610}, {f: 3, c: 24620}, {f: 5, c: 24624}, - {f: 5, c: 24630}, {f: 2, c: 24637}, 24640, {f: 7, c: 24644}, 24652, - {f: 2, c: 24654}, 24657, {f: 2, c: 24659}, {f: 3, c: 24662}, - {f: 2, c: 24667}, {f: 4, c: 24670}, {f: 2, c: 24677}, 24686, - {f: 2, c: 24689}, {f: 2, c: 24692}, 24695, 24702, {f: 3, c: 24704}, - {f: 4, c: 24709}, {f: 2, c: 24714}, {f: 4, c: 24718}, 24723, 24725, - {f: 3, c: 24727}, 24732, 24734, {f: 2, c: 24737}, {f: 2, c: 24740}, 24743, - {f: 2, c: 24745}, 24750, 24752, 24755, 24759, {f: 2, c: 24761}, - {f: 8, c: 24765}, {f: 3, c: 24775}, {f: 5, c: 24780}, {f: 3, c: 24786}, - {f: 2, c: 24790}, 24793, 24795, 24798, {f: 4, c: 24802}, 24810, 24821, - {f: 2, c: 24823}, {f: 4, c: 24828}, {f: 4, c: 24834}, 24839, - {f: 3, c: 24842}, {f: 5, c: 24848}, {f: 4, c: 24854}, {f: 2, c: 24861}, - {f: 2, c: 24865}, 24869, {f: 3, c: 24872}, {f: 8, c: 24876}, - {f: 2, c: 24885}, {f: 6, c: 24888}, {f: 8, c: 24896}, 24905, 24909, - {f: 2, c: 24911}, {f: 3, c: 24914}, {f: 2, c: 24918}, 24921, - {f: 2, c: 24923}, 24926, {f: 2, c: 24928}, {f: 2, c: 24933}, 24937, - {f: 2, c: 24940}, 24943, {f: 2, c: 24945}, 24948, {f: 10, c: 24952}, - {f: 7, c: 24963}, {f: 2, c: 24972}, 24975, 24979, {f: 5, c: 24981}, - {f: 2, c: 24987}, {f: 6, c: 24990}, {f: 2, c: 24997}, 25002, 25005, - {f: 3, c: 25007}, {f: 3, c: 25011}, {f: 6, c: 25016}, {f: 3, c: 25023}, - {f: 4, c: 25027}, {f: 4, c: 25037}, 25043, {f: 9, c: 25045}, - {f: 3, c: 25056}, {f: 2, c: 25060}, 25063, {f: 9, c: 25065}, - {f: 2, c: 25075}, 25081, 25083, 25085, {f: 5, c: 25089}, 25097, 25107, - 25113, {f: 3, c: 25116}, 25120, 25123, 25126, {f: 2, c: 25128}, 25131, - 25133, 25135, 25137, 25141, [12094, 25142], {f: 5, c: 25144}, 25154, - {f: 3, c: 25156}, 25162, {f: 2, c: 25167}, {f: 3, c: 25173}, - {f: 2, c: 25177}, {f: 7, c: 25180}, {f: 2, c: 25188}, 25192, - {f: 2, c: 25201}, {f: 2, c: 25204}, {f: 2, c: 25207}, {f: 2, c: 25210}, - 25213, {f: 3, c: 25217}, {f: 4, c: 25221}, {f: 6, c: 25227}, 25236, 25241, - {f: 3, c: 25244}, 25251, {f: 2, c: 25254}, {f: 2, c: 25257}, - {f: 4, c: 25261}, {f: 3, c: 25266}, {f: 3, c: 25270}, 25274, 25278, - {f: 2, c: 25280}, 25283, 25291, 25295, 25297, 25301, {f: 2, c: 25309}, - {f: 2, c: 25312}, 25316, {f: 2, c: 25322}, 25328, 25330, 25333, - {f: 4, c: 25336}, 25344, {f: 4, c: 25347}, {f: 4, c: 25354}, - {f: 2, c: 25359}, {f: 4, c: 25362}, {f: 3, c: 25367}, 25372, - {f: 2, c: 25382}, 25385, {f: 3, c: 25388}, {f: 2, c: 25392}, - {f: 6, c: 25395}, {f: 2, c: 25403}, {f: 3, c: 25407}, 25412, - {f: 2, c: 25415}, 25418, {f: 4, c: 25425}, {f: 8, c: 25430}, 25440, - {f: 3, c: 25444}, 25450, 25452, {f: 2, c: 25455}, {f: 3, c: 25459}, - {f: 2, c: 25464}, {f: 4, c: 25468}, 25473, {f: 2, c: 25477}, 25483, 25485, - 25489, {f: 3, c: 25491}, 25495, {f: 7, c: 25497}, 25505, 25508, 25510, - 25515, 25519, {f: 2, c: 25521}, {f: 2, c: 25525}, 25529, 25531, 25533, - 25535, {f: 3, c: 25537}, 25541, {f: 2, c: 25543}, {f: 3, c: 25546}, 25553, - {f: 3, c: 25555}, {f: 3, c: 25559}, {f: 3, c: 25563}, 25567, 25570, - {f: 5, c: 25572}, {f: 2, c: 25579}, {f: 3, c: 25583}, 25587, 25589, 25591, - {f: 4, c: 25593}, 25598, {f: 2, c: 25603}, {f: 5, c: 25606}, 25614, - {f: 2, c: 25617}, {f: 2, c: 25621}, {f: 3, c: 25624}, 25629, 25631, - {f: 4, c: 25634}, {f: 3, c: 25639}, 25643, {f: 6, c: 25646}, 25653, - {f: 3, c: 25655}, {f: 2, c: 25659}, 25662, 25664, {f: 2, c: 25666}, 25673, - {f: 6, c: 25675}, 25683, {f: 3, c: 25685}, {f: 3, c: 25689}, 25693, - {f: 7, c: 25696}, 25704, {f: 3, c: 25706}, 25710, {f: 3, c: 25712}, - {f: 2, c: 25716}, 25719, {f: 6, c: 25724}, 25731, 25734, {f: 8, c: 25737}, - 25748, {f: 2, c: 25751}, {f: 4, c: 25754}, {f: 3, c: 25760}, - {f: 3, c: 25766}, 25770, 25775, 25777, 25780, 25782, 25785, 25789, 25795, - 25798, {f: 2, c: 25800}, 25804, 25807, 25809, 25811, {f: 2, c: 25813}, - 25817, {f: 3, c: 25819}, 25823, 25825, 25827, 25829, {f: 5, c: 25831}, - {f: 2, c: 25837}, 25843, {f: 2, c: 25845}, {f: 2, c: 25848}, 25853, 25855, - {f: 3, c: 25857}, 25861, {f: 2, c: 25863}, {f: 5, c: 25866}, - {f: 2, c: 25872}, 25875, 25877, 25879, 25882, 25884, {f: 4, c: 25886}, - {f: 4, c: 25894}, 25901, {f: 4, c: 25904}, 25911, 25914, {f: 2, c: 25916}, - {f: 5, c: 25920}, {f: 2, c: 25926}, {f: 2, c: 25930}, {f: 2, c: 25933}, - 25936, {f: 3, c: 25938}, 25944, 25946, 25948, {f: 3, c: 25951}, - {f: 2, c: 25956}, {f: 4, c: 25959}, {f: 3, c: 25965}, 25969, 25971, 25974, - {f: 9, c: 25977}, {f: 3, c: 25988}, {f: 3, c: 25992}, {f: 3, c: 25997}, - 26002, 26004, 26006, 26008, 26010, {f: 2, c: 26013}, 26016, - {f: 2, c: 26018}, 26022, 26024, 26026, 26030, {f: 6, c: 26033}, 26040, - {f: 2, c: 26042}, {f: 3, c: 26046}, 26050, {f: 4, c: 26055}, 26061, - {f: 2, c: 26064}, {f: 3, c: 26067}, {f: 8, c: 26072}, 26081, - {f: 2, c: 26083}, {f: 2, c: 26090}, {f: 4, c: 26098}, {f: 2, c: 26104}, - {f: 5, c: 26107}, 26113, {f: 2, c: 26116}, {f: 3, c: 26119}, 26123, 26125, - {f: 3, c: 26128}, {f: 3, c: 26134}, {f: 3, c: 26138}, 26142, - {f: 4, c: 26145}, 26150, {f: 4, c: 26153}, 26158, 26160, {f: 2, c: 26162}, - {f: 5, c: 26167}, 26173, {f: 2, c: 26175}, {f: 7, c: 26180}, - {f: 2, c: 26189}, {f: 2, c: 26192}, {f: 2, c: 26200}, {f: 2, c: 26203}, - 26206, 26208, {f: 2, c: 26210}, 26213, 26215, {f: 5, c: 26217}, - {f: 3, c: 26225}, 26229, {f: 2, c: 26232}, {f: 3, c: 26235}, - {f: 3, c: 26239}, 26243, {f: 2, c: 26245}, {f: 2, c: 26250}, - {f: 4, c: 26253}, {f: 4, c: 26258}, {f: 5, c: 26264}, {f: 4, c: 26270}, - {f: 4, c: 26275}, {f: 2, c: 26281}, {f: 2, c: 26284}, {f: 5, c: 26287}, - {f: 4, c: 26293}, {f: 4, c: 26298}, {f: 5, c: 26303}, 26309, 26312, - {f: 12, c: 26314}, {f: 2, c: 26327}, 26330, {f: 2, c: 26334}, - {f: 5, c: 26337}, {f: 2, c: 26343}, {f: 2, c: 26346}, {f: 3, c: 26349}, - 26353, {f: 2, c: 26357}, {f: 2, c: 26362}, 26365, {f: 2, c: 26369}, - {f: 4, c: 26372}, 26380, {f: 2, c: 26382}, {f: 3, c: 26385}, 26390, - {f: 3, c: 26392}, 26396, 26398, {f: 6, c: 26400}, 26409, 26414, 26416, - {f: 2, c: 26418}, {f: 4, c: 26422}, {f: 2, c: 26427}, {f: 2, c: 26430}, - 26433, {f: 2, c: 26436}, 26439, {f: 2, c: 26442}, 26445, 26450, - {f: 2, c: 26452}, {f: 5, c: 26455}, 26461, {f: 3, c: 26466}, - {f: 2, c: 26470}, {f: 2, c: 26475}, 26478, 26484, 26486, {f: 4, c: 26488}, - 26493, 26496, {f: 2, c: 26498}, {f: 2, c: 26501}, 26504, 26506, - {f: 4, c: 26508}, {f: 4, c: 26513}, 26518, 26521, 26523, {f: 3, c: 26527}, - 26532, 26534, 26537, 26540, 26542, {f: 2, c: 26545}, 26548, - {f: 8, c: 26553}, 26562, {f: 10, c: 26565}, {f: 3, c: 26581}, 26587, 26591, - 26593, {f: 2, c: 26595}, {f: 3, c: 26598}, {f: 2, c: 26602}, - {f: 2, c: 26605}, 26610, {f: 8, c: 26613}, 26622, {f: 4, c: 26625}, 26630, - 26637, 26640, 26642, {f: 2, c: 26644}, {f: 5, c: 26648}, {f: 3, c: 26654}, - {f: 7, c: 26658}, {f: 7, c: 26667}, {f: 3, c: 26676}, {f: 2, c: 26682}, - 26687, 26695, 26699, 26701, 26703, 26706, {f: 10, c: 26710}, 26730, - {f: 8, c: 26732}, 26741, {f: 9, c: 26744}, 26754, 26756, {f: 8, c: 26759}, - {f: 3, c: 26768}, {f: 3, c: 26772}, {f: 4, c: 26777}, 26782, - {f: 2, c: 26784}, {f: 3, c: 26787}, {f: 4, c: 26793}, 26798, - {f: 2, c: 26801}, 26804, {f: 10, c: 26806}, 26817, {f: 6, c: 26819}, 26826, - 26828, {f: 4, c: 26830}, {f: 2, c: 26835}, 26841, {f: 4, c: 26843}, - {f: 2, c: 26849}, {f: 3, c: 26852}, {f: 6, c: 26856}, 26863, - {f: 3, c: 26866}, {f: 3, c: 26870}, 26875, {f: 4, c: 26877}, - {f: 3, c: 26882}, {f: 5, c: 26886}, 26892, 26897, {f: 12, c: 26899}, - {f: 3, c: 26913}, {f: 8, c: 26917}, {f: 2, c: 26926}, {f: 3, c: 26929}, - {f: 4, c: 26933}, {f: 3, c: 26938}, 26942, {f: 2, c: 26944}, - {f: 7, c: 26947}, {f: 8, c: 26955}, {f: 2, c: 26965}, {f: 2, c: 26968}, - {f: 2, c: 26971}, 26975, {f: 2, c: 26977}, {f: 2, c: 26980}, 26983, - {f: 2, c: 26985}, 26988, {f: 2, c: 26991}, {f: 3, c: 26994}, 26998, - {f: 2, c: 27002}, {f: 3, c: 27005}, 27009, 27011, 27013, {f: 3, c: 27018}, - {f: 6, c: 27022}, {f: 2, c: 27030}, {f: 2, c: 27033}, {f: 10, c: 27037}, - 27049, 27052, {f: 2, c: 27055}, {f: 2, c: 27058}, {f: 2, c: 27061}, - {f: 3, c: 27064}, {f: 3, c: 27068}, 27072, {f: 8, c: 27074}, 27087, - {f: 3, c: 27089}, {f: 6, c: 27093}, {f: 3, c: 27100}, {f: 6, c: 27105}, - {f: 5, c: 27112}, {f: 4, c: 27118}, {f: 9, c: 27124}, 27134, 27136, - {f: 2, c: 27139}, {f: 4, c: 27142}, {f: 8, c: 27147}, {f: 3, c: 27156}, - {f: 4, c: 27162}, 27168, 27170, {f: 4, c: 27172}, 27177, {f: 4, c: 27179}, - 27184, {f: 3, c: 27186}, {f: 2, c: 27190}, {f: 2, c: 27195}, - {f: 5, c: 27199}, {f: 2, c: 27205}, {f: 2, c: 27209}, {f: 4, c: 27212}, - {f: 7, c: 27217}, 27226, {f: 3, c: 27228}, 27232, {f: 2, c: 27235}, - {f: 11, c: 27238}, {f: 7, c: 27250}, {f: 2, c: 27258}, {f: 3, c: 27261}, - {f: 3, c: 27265}, {f: 4, c: 27269}, {f: 4, c: 27274}, 27279, - {f: 2, c: 27282}, {f: 2, c: 27285}, {f: 4, c: 27288}, {f: 3, c: 27293}, - 27297, {f: 5, c: 27300}, 27306, {f: 2, c: 27309}, {f: 3, c: 27312}, - {f: 4, c: 27316}, {f: 2, c: 27321}, {f: 7, c: 27324}, {f: 15, c: 27332}, - {f: 6, c: 27348}, 27356, {f: 7, c: 27360}, 27369, 27371, {f: 6, c: 27373}, - {f: 4, c: 27380}, {f: 2, c: 27385}, {f: 8, c: 27388}, {f: 5, c: 27397}, - {f: 4, c: 27403}, {f: 2, c: 27408}, {f: 3, c: 27411}, {f: 7, c: 27415}, - 27423, {f: 2, c: 27429}, {f: 10, c: 27432}, {f: 4, c: 27443}, 27448, - {f: 2, c: 27451}, {f: 4, c: 27455}, {f: 2, c: 27460}, 27464, - {f: 2, c: 27466}, {f: 3, c: 27469}, {f: 8, c: 27473}, {f: 5, c: 27482}, - 27488, {f: 2, c: 27496}, {f: 7, c: 27499}, {f: 4, c: 27507}, 27514, - {f: 4, c: 27517}, 27525, 27528, 27532, {f: 4, c: 27534}, {f: 2, c: 27540}, - 27543, 27545, {f: 2, c: 27548}, {f: 2, c: 27551}, {f: 2, c: 27554}, - {f: 5, c: 27557}, {f: 2, c: 27564}, {f: 2, c: 27568}, 27574, - {f: 2, c: 27576}, {f: 3, c: 27580}, 27584, {f: 2, c: 27587}, - {f: 4, c: 27591}, 27596, 27598, {f: 2, c: 27600}, 27608, 27610, - {f: 5, c: 27612}, {f: 8, c: 27618}, {f: 3, c: 27628}, {f: 3, c: 27632}, - 27636, {f: 3, c: 27638}, {f: 3, c: 27642}, 27646, {f: 5, c: 27648}, - {f: 3, c: 27657}, 27662, 27666, 27671, {f: 3, c: 27676}, 27680, 27685, - 27693, 27697, 27699, {f: 2, c: 27702}, {f: 4, c: 27705}, {f: 2, c: 27710}, - {f: 3, c: 27715}, 27720, {f: 5, c: 27723}, {f: 3, c: 27729}, 27734, - {f: 3, c: 27736}, {f: 2, c: 27746}, {f: 3, c: 27749}, {f: 5, c: 27755}, - 27761, 27763, 27765, {f: 2, c: 27767}, {f: 3, c: 27770}, {f: 2, c: 27775}, - 27780, 27783, {f: 2, c: 27786}, {f: 2, c: 27789}, {f: 2, c: 27793}, - {f: 4, c: 27797}, 27802, {f: 3, c: 27804}, 27808, 27810, 27816, 27820, - {f: 2, c: 27823}, {f: 4, c: 27828}, 27834, {f: 4, c: 27840}, - {f: 3, c: 27846}, 27851, {f: 3, c: 27853}, {f: 2, c: 27857}, - {f: 3, c: 27864}, {f: 2, c: 27868}, 27871, 27876, {f: 2, c: 27878}, 27881, - {f: 2, c: 27884}, 27890, 27892, 27897, {f: 2, c: 27903}, {f: 2, c: 27906}, - {f: 2, c: 27909}, {f: 3, c: 27912}, 27917, {f: 3, c: 27919}, - {f: 4, c: 27923}, 27928, {f: 2, c: 27932}, {f: 6, c: 27935}, 27942, - {f: 2, c: 27944}, {f: 2, c: 27948}, {f: 2, c: 27951}, 27956, - {f: 3, c: 27958}, 27962, {f: 2, c: 27967}, 27970, 27972, 27977, 27980, - 27984, {f: 4, c: 27989}, 27995, 27997, 27999, {f: 2, c: 28001}, - {f: 2, c: 28004}, {f: 2, c: 28007}, {f: 3, c: 28011}, {f: 4, c: 28016}, - {f: 2, c: 28021}, {f: 2, c: 28026}, {f: 5, c: 28029}, {f: 2, c: 28035}, - 28038, {f: 2, c: 28042}, 28045, {f: 2, c: 28047}, 28050, {f: 5, c: 28054}, - 28060, 28066, 28069, {f: 2, c: 28076}, {f: 2, c: 28080}, {f: 2, c: 28083}, - {f: 2, c: 28086}, {f: 6, c: 28089}, {f: 3, c: 28097}, {f: 3, c: 28104}, - {f: 4, c: 28109}, {f: 4, c: 28114}, 28119, {f: 3, c: 28122}, 28127, - {f: 2, c: 28130}, 28133, {f: 3, c: 28135}, 28141, {f: 2, c: 28143}, 28146, - 28148, 28152, {f: 8, c: 28157}, {f: 4, c: 28166}, 28171, 28175, - {f: 2, c: 28178}, 28181, {f: 2, c: 28184}, {f: 2, c: 28187}, - {f: 2, c: 28190}, 28194, {f: 2, c: 28199}, 28202, 28206, {f: 2, c: 28208}, - 28211, {f: 3, c: 28213}, 28217, {f: 3, c: 28219}, {f: 4, c: 28223}, - {f: 8, c: 28229}, {f: 4, c: 28239}, 28245, 28247, {f: 2, c: 28249}, - {f: 2, c: 28252}, {f: 11, c: 28256}, {f: 2, c: 28268}, {f: 14, c: 28272}, - {f: 3, c: 28288}, 28292, {f: 2, c: 28295}, {f: 5, c: 28298}, - {f: 5, c: 28305}, 28311, {f: 3, c: 28313}, 28318, {f: 2, c: 28320}, - {f: 2, c: 28323}, 28326, {f: 2, c: 28328}, {f: 4, c: 28331}, 28336, 28339, - 28341, {f: 2, c: 28344}, 28348, {f: 3, c: 28350}, 28355, 28358, - {f: 3, c: 28360}, 28365, 28368, 28370, 28374, {f: 2, c: 28376}, - {f: 3, c: 28379}, 28387, 28391, {f: 2, c: 28394}, {f: 2, c: 28397}, - {f: 2, c: 28400}, 28403, {f: 2, c: 28405}, {f: 5, c: 28410}, 28416, - {f: 3, c: 28419}, {f: 2, c: 28423}, {f: 5, c: 28426}, {f: 3, c: 28432}, - {f: 4, c: 28438}, {f: 5, c: 28443}, 28449, {f: 4, c: 28453}, 28462, 28464, - {f: 2, c: 28468}, 28471, {f: 5, c: 28473}, 28480, {f: 4, c: 28482}, - {f: 3, c: 28488}, 28492, {f: 3, c: 28494}, {f: 2, c: 28498}, - {f: 3, c: 28501}, {f: 2, c: 28506}, 28509, {f: 3, c: 28511}, 28515, 28517, - {f: 6, c: 28519}, 28529, 28531, {f: 2, c: 28533}, 28537, 28539, - {f: 2, c: 28541}, {f: 3, c: 28545}, 28549, {f: 2, c: 28554}, - {f: 8, c: 28559}, {f: 4, c: 28568}, {f: 3, c: 28573}, {f: 2, c: 28578}, - {f: 2, c: 28581}, 28584, {f: 4, c: 28586}, {f: 2, c: 28591}, 28594, - {f: 2, c: 28596}, {f: 2, c: 28599}, {f: 6, c: 28602}, {f: 5, c: 28612}, - {f: 7, c: 28618}, {f: 2, c: 28627}, {f: 2, c: 28630}, {f: 2, c: 28633}, - {f: 2, c: 28636}, {f: 2, c: 28642}, {f: 6, c: 28645}, {f: 2, c: 28652}, - {f: 8, c: 28658}, 28667, 28669, {f: 6, c: 28671}, {f: 2, c: 28679}, 28682, - {f: 3, c: 28684}, 28688, {f: 3, c: 28690}, {f: 2, c: 28694}, 28697, 28700, - 28702, {f: 2, c: 28705}, {f: 3, c: 28708}, {f: 7, c: 28713}, 28721, - {f: 2, c: 28723}, {f: 3, c: 28726}, {f: 4, c: 28730}, {f: 4, c: 28735}, - {f: 7, c: 28741}, {f: 2, c: 28749}, 28752, {f: 3, c: 28754}, - {f: 2, c: 28758}, {f: 4, c: 28761}, {f: 4, c: 28767}, {f: 2, c: 28773}, - {f: 3, c: 28776}, 28782, {f: 4, c: 28785}, 28791, {f: 3, c: 28793}, 28797, - {f: 4, c: 28801}, {f: 3, c: 28806}, {f: 3, c: 28811}, {f: 3, c: 28815}, - 28819, {f: 2, c: 28823}, {f: 2, c: 28826}, {f: 13, c: 28830}, 28848, 28850, - {f: 3, c: 28852}, 28858, {f: 2, c: 28862}, {f: 4, c: 28868}, 28873, - {f: 4, c: 28875}, {f: 8, c: 28880}, 28890, {f: 3, c: 28892}, - {f: 4, c: 28896}, 28901, 28906, 28910, {f: 4, c: 28912}, {f: 2, c: 28917}, - 28920, {f: 3, c: 28922}, {f: 11, c: 28926}, {f: 5, c: 28939}, - {f: 2, c: 28945}, 28948, 28951, {f: 6, c: 28955}, {f: 4, c: 28962}, - {f: 8, c: 28967}, {f: 4, c: 28978}, {f: 14, c: 28983}, {f: 3, c: 28998}, - 29003, 29005, {f: 3, c: 29007}, {f: 9, c: 29011}, 29021, {f: 3, c: 29023}, - 29027, 29029, {f: 2, c: 29034}, 29037, {f: 3, c: 29039}, {f: 4, c: 29044}, - 29049, {f: 2, c: 29051}, {f: 6, c: 29054}, {f: 5, c: 29061}, - {f: 4, c: 29067}, {f: 2, c: 29072}, 29075, {f: 2, c: 29077}, - {f: 5, c: 29082}, {f: 7, c: 29089}, {f: 3, c: 29097}, {f: 4, c: 29101}, - 29106, 29108, {f: 3, c: 29110}, {f: 4, c: 29114}, {f: 2, c: 29119}, 29122, - {f: 4, c: 29124}, {f: 5, c: 29129}, {f: 3, c: 29135}, 29139, - {f: 3, c: 29142}, {f: 2, c: 29146}, {f: 2, c: 29149}, {f: 4, c: 29153}, - {f: 5, c: 29160}, {f: 5, c: 29167}, {f: 4, c: 29173}, {f: 2, c: 29178}, - 29181, {f: 7, c: 29183}, {f: 6, c: 29191}, {f: 2, c: 29198}, - {f: 10, c: 29201}, 29212, {f: 10, c: 29214}, 29225, 29227, - {f: 3, c: 29229}, {f: 2, c: 29235}, 29244, {f: 7, c: 29248}, - {f: 3, c: 29257}, {f: 4, c: 29262}, {f: 3, c: 29267}, 29271, 29274, 29276, - 29278, 29280, {f: 3, c: 29283}, 29288, {f: 4, c: 29290}, {f: 2, c: 29296}, - {f: 2, c: 29299}, {f: 3, c: 29302}, {f: 2, c: 29307}, {f: 2, c: 29314}, - {f: 5, c: 29317}, 29324, 29326, {f: 2, c: 29328}, {f: 3, c: 29331}, - {f: 8, c: 29335}, {f: 2, c: 29344}, {f: 4, c: 29347}, {f: 4, c: 29352}, - 29358, {f: 3, c: 29361}, 29365, {f: 6, c: 29370}, {f: 3, c: 29381}, - {f: 4, c: 29385}, 29391, 29393, {f: 4, c: 29395}, 29400, {f: 4, c: 29402}, - 29407, {f: 6, c: 29410}, {f: 2, c: 29418}, {f: 2, c: 29429}, - {f: 3, c: 29438}, 29442, {f: 6, c: 29444}, {f: 3, c: 29451}, - {f: 4, c: 29455}, 29460, {f: 3, c: 29464}, {f: 2, c: 29471}, - {f: 2, c: 29475}, {f: 3, c: 29478}, 29485, {f: 2, c: 29487}, - {f: 2, c: 29490}, 29493, 29498, {f: 2, c: 29500}, 29504, {f: 2, c: 29506}, - {f: 7, c: 29510}, {f: 2, c: 29518}, 29521, {f: 4, c: 29523}, - {f: 8, c: 29528}, {f: 7, c: 29537}, 29545, 29550, 29553, {f: 2, c: 29555}, - 29558, 29561, 29565, 29567, {f: 3, c: 29569}, {f: 2, c: 29573}, 29576, - 29578, {f: 2, c: 29580}, {f: 2, c: 29583}, {f: 4, c: 29586}, - {f: 4, c: 29591}, {f: 3, c: 29596}, {f: 2, c: 29600}, {f: 6, c: 29603}, - 29610, {f: 2, c: 29612}, 29617, {f: 3, c: 29620}, {f: 2, c: 29624}, - {f: 4, c: 29628}, 29633, {f: 5, c: 29635}, {f: 2, c: 29643}, 29646, - {f: 7, c: 29650}, {f: 4, c: 29658}, 29663, {f: 4, c: 29665}, 29670, 29672, - {f: 3, c: 29674}, {f: 4, c: 29678}, {f: 11, c: 29683}, {f: 4, c: 29695}, - 29700, {f: 2, c: 29703}, {f: 4, c: 29707}, {f: 9, c: 29713}, - {f: 6, c: 29724}, {f: 2, c: 29731}, 29735, 29737, 29739, 29741, 29743, - {f: 2, c: 29745}, {f: 5, c: 29751}, {f: 2, c: 29757}, 29760, - {f: 9, c: 29762}, {f: 9, c: 29772}, 29782, 29784, 29789, {f: 3, c: 29792}, - {f: 5, c: 29796}, {f: 2, c: 29803}, {f: 2, c: 29806}, {f: 5, c: 29809}, - {f: 6, c: 29816}, 29823, 29826, {f: 3, c: 29828}, 29832, 29834, - {f: 2, c: 29836}, 29839, {f: 11, c: 29841}, 29853, {f: 4, c: 29855}, - {f: 2, c: 29860}, {f: 6, c: 29866}, {f: 9, c: 29873}, {f: 2, c: 29883}, - {f: 12, c: 29886}, {f: 4, c: 29899}, {f: 2, c: 29904}, 29907, - {f: 5, c: 29909}, 29915, 29917, 29919, 29921, 29925, {f: 7, c: 29927}, - {f: 4, c: 29936}, 29941, {f: 7, c: 29944}, {f: 4, c: 29952}, - {f: 7, c: 29957}, 29966, 29968, 29970, {f: 4, c: 29972}, 29979, - {f: 2, c: 29981}, {f: 3, c: 29984}, 29988, {f: 2, c: 29990}, 29994, 29998, - 30004, 30006, 30009, {f: 2, c: 30012}, 30015, {f: 4, c: 30017}, - {f: 2, c: 30022}, {f: 2, c: 30025}, 30029, {f: 4, c: 30032}, - {f: 4, c: 30037}, {f: 4, c: 30046}, {f: 2, c: 30051}, {f: 3, c: 30055}, - {f: 6, c: 30060}, 30067, 30069, 30071, {f: 5, c: 30074}, {f: 3, c: 30080}, - {f: 2, c: 30084}, {f: 3, c: 30088}, {f: 3, c: 30092}, 30096, 30099, 30101, - 30104, {f: 2, c: 30107}, 30110, 30114, {f: 5, c: 30118}, 30125, - {f: 2, c: 30134}, {f: 2, c: 30138}, {f: 3, c: 30143}, 30150, - {f: 2, c: 30155}, {f: 4, c: 30158}, 30163, 30167, 30170, {f: 2, c: 30172}, - {f: 3, c: 30175}, 30181, 30185, {f: 4, c: 30188}, {f: 2, c: 30194}, - {f: 4, c: 30197}, {f: 2, c: 30202}, {f: 2, c: 30205}, 30212, - {f: 4, c: 30214}, {f: 2, c: 30222}, {f: 4, c: 30225}, 30230, 30234, - {f: 2, c: 30236}, 30243, 30248, 30252, {f: 2, c: 30254}, {f: 2, c: 30257}, - {f: 2, c: 30262}, {f: 2, c: 30265}, 30269, 30273, {f: 2, c: 30276}, 30280, - {f: 2, c: 30282}, {f: 6, c: 30286}, 30293, 30295, {f: 3, c: 30297}, 30301, - {f: 2, c: 30304}, 30310, 30312, 30314, {f: 3, c: 30323}, [12136, 30326], - 30327, {f: 2, c: 30329}, {f: 3, c: 30335}, 30339, 30341, {f: 2, c: 30345}, - {f: 2, c: 30348}, {f: 2, c: 30351}, 30354, {f: 2, c: 30356}, - {f: 2, c: 30359}, {f: 9, c: 30363}, {f: 9, c: 30373}, {f: 2, c: 30383}, - 30387, {f: 3, c: 30389}, 30393, {f: 4, c: 30395}, {f: 2, c: 30400}, - {f: 2, c: 30403}, 30407, 30409, {f: 2, c: 30411}, 30419, 30421, - {f: 2, c: 30425}, {f: 2, c: 30428}, 30432, 30434, 30438, {f: 6, c: 30440}, - 30448, 30451, {f: 3, c: 30453}, {f: 2, c: 30458}, 30461, {f: 2, c: 30463}, - {f: 2, c: 30466}, {f: 2, c: 30469}, 30474, 30476, {f: 11, c: 30478}, - {f: 4, c: 30491}, 30497, {f: 3, c: 30499}, 30503, {f: 3, c: 30506}, 30510, - {f: 5, c: 30512}, 30521, 30523, {f: 3, c: 30525}, 30530, {f: 3, c: 30532}, - {f: 7, c: 30536}, {f: 8, c: 30546}, {f: 2, c: 30556}, {f: 2, c: 30559}, - 30564, 30567, {f: 2, c: 30569}, {f: 12, c: 30573}, {f: 3, c: 30586}, - {f: 3, c: 30593}, {f: 6, c: 30598}, {f: 2, c: 30607}, {f: 5, c: 30611}, - {f: 5, c: 30617}, 30625, {f: 2, c: 30627}, 30630, 30632, 30635, - {f: 2, c: 30638}, {f: 2, c: 30641}, 30644, {f: 5, c: 30646}, 30654, - {f: 7, c: 30656}, {f: 5, c: 30664}, {f: 9, c: 30670}, {f: 2, c: 30680}, - {f: 5, c: 30685}, 30692, 30694, 30696, 30698, {f: 3, c: 30704}, - {f: 2, c: 30708}, 30711, {f: 4, c: 30713}, {f: 6, c: 30723}, - {f: 2, c: 30730}, {f: 3, c: 30734}, 30739, 30741, 30745, 30747, 30750, - {f: 3, c: 30752}, 30756, 30760, {f: 2, c: 30762}, {f: 2, c: 30766}, - {f: 3, c: 30769}, {f: 2, c: 30773}, 30781, 30783, {f: 2, c: 30785}, 30788, - 30790, {f: 4, c: 30792}, 30797, 30799, 30801, {f: 2, c: 30803}, - {f: 5, c: 30808}, {f: 6, c: 30814}, {f: 3, c: 30821}, 30825, - {f: 7, c: 30832}, {f: 4, c: 30840}, {f: 10, c: 30845}, 30856, - {f: 2, c: 30858}, {f: 2, c: 30863}, 30866, {f: 3, c: 30868}, 30873, - {f: 2, c: 30877}, 30880, 30882, 30884, 30886, 30888, {f: 3, c: 30890}, - {f: 2, c: 30894}, {f: 3, c: 30901}, 30907, 30909, {f: 2, c: 30911}, - {f: 3, c: 30914}, {f: 3, c: 30918}, {f: 4, c: 30924}, {f: 3, c: 30929}, - {f: 3, c: 30934}, {f: 8, c: 30939}, {f: 3, c: 30948}, {f: 3, c: 30953}, - {f: 2, c: 30957}, {f: 2, c: 30960}, 30963, {f: 2, c: 30965}, - {f: 2, c: 30968}, {f: 2, c: 30971}, {f: 3, c: 30974}, {f: 3, c: 30978}, - {f: 8, c: 30982}, {f: 4, c: 30991}, {f: 5, c: 30996}, {f: 4, c: 31002}, - {f: 5, c: 31007}, 31013, {f: 3, c: 31015}, {f: 4, c: 31021}, - {f: 2, c: 31026}, {f: 5, c: 31029}, 31037, 31039, {f: 4, c: 31042}, 31047, - {f: 9, c: 31050}, {f: 2, c: 31060}, {f: 2, c: 31064}, 31073, - {f: 2, c: 31075}, 31078, {f: 4, c: 31081}, 31086, {f: 7, c: 31088}, 31097, - {f: 5, c: 31099}, {f: 2, c: 31106}, {f: 4, c: 31110}, {f: 2, c: 31115}, - {f: 10, c: 31120}, {f: 11, c: 31131}, {f: 2, c: 31144}, {f: 3, c: 31147}, - 31151, 31154, {f: 4, c: 31156}, [12145, 31160], 31164, 31167, 31170, - {f: 2, c: 31172}, {f: 2, c: 31175}, 31178, 31180, {f: 3, c: 31182}, - {f: 2, c: 31187}, {f: 2, c: 31190}, {f: 6, c: 31193}, {f: 3, c: 31200}, - 31205, 31208, 31210, 31212, 31214, {f: 7, c: 31217}, {f: 2, c: 31225}, - 31228, {f: 2, c: 31230}, 31233, {f: 2, c: 31236}, {f: 4, c: 31239}, 31244, - {f: 5, c: 31247}, {f: 2, c: 31253}, {f: 2, c: 31256}, {f: 3, c: 31259}, - 31263, {f: 2, c: 31265}, {f: 10, c: 31268}, {f: 2, c: 31279}, 31282, - {f: 3, c: 31284}, 31288, 31290, 31294, {f: 5, c: 31297}, {f: 5, c: 31303}, - {f: 2, c: 31311}, {f: 5, c: 31314}, {f: 9, c: 31320}, {f: 6, c: 31331}, - 31338, {f: 4, c: 31340}, {f: 3, c: 31345}, 31349, {f: 4, c: 31355}, 31362, - 31365, 31367, {f: 4, c: 31369}, {f: 3, c: 31374}, {f: 2, c: 31379}, - {f: 3, c: 31385}, 31390, {f: 4, c: 31393}, 31399, 31403, {f: 4, c: 31407}, - {f: 2, c: 31412}, {f: 3, c: 31415}, {f: 4, c: 31419}, {f: 4, c: 31424}, - 31430, 31433, {f: 10, c: 31436}, {f: 2, c: 31447}, {f: 4, c: 31450}, - {f: 2, c: 31457}, 31460, {f: 3, c: 31463}, {f: 2, c: 31467}, 31470, - {f: 6, c: 31472}, {f: 2, c: 31479}, {f: 2, c: 31483}, 31486, - {f: 3, c: 31488}, 31493, 31495, 31497, {f: 3, c: 31500}, 31504, - {f: 2, c: 31506}, {f: 3, c: 31510}, 31514, {f: 2, c: 31516}, 31519, - {f: 3, c: 31521}, 31527, 31529, 31533, {f: 2, c: 31535}, 31538, - {f: 4, c: 31540}, 31545, 31547, 31549, {f: 6, c: 31551}, 31560, 31562, - {f: 2, c: 31565}, 31571, 31573, 31575, 31577, 31580, {f: 2, c: 31582}, - 31585, {f: 4, c: 31587}, {f: 6, c: 31592}, {f: 2, c: 31599}, - {f: 2, c: 31603}, 31606, 31608, 31610, {f: 2, c: 31612}, 31615, - {f: 4, c: 31617}, {f: 5, c: 31622}, 31628, {f: 2, c: 31630}, - {f: 3, c: 31633}, 31638, {f: 4, c: 31640}, {f: 3, c: 31646}, - {f: 3, c: 31651}, {f: 3, c: 31662}, {f: 2, c: 31666}, {f: 3, c: 31669}, - {f: 7, c: 31673}, {f: 2, c: 31682}, 31685, 31688, 31690, {f: 4, c: 31693}, - 31698, {f: 5, c: 31700}, {f: 2, c: 31707}, {f: 3, c: 31710}, - {f: 2, c: 31714}, {f: 2, c: 31719}, {f: 3, c: 31723}, {f: 2, c: 31727}, - 31730, {f: 3, c: 31732}, {f: 4, c: 31736}, 31741, 31743, {f: 6, c: 31745}, - {f: 3, c: 31752}, 31758, {f: 6, c: 31760}, {f: 7, c: 31767}, 31776, 31778, - {f: 2, c: 31780}, {f: 2, c: 31784}, {f: 12, c: 31788}, {f: 4, c: 31801}, - 31810, {f: 8, c: 31812}, {f: 14, c: 31822}, {f: 2, c: 31837}, - {f: 3, c: 31841}, {f: 4, c: 31845}, 31851, 31853, {f: 3, c: 31855}, - {f: 6, c: 31861}, {f: 11, c: 31870}, {f: 7, c: 31882}, {f: 2, c: 31891}, - 31894, {f: 3, c: 31897}, {f: 2, c: 31904}, 31907, {f: 4, c: 31910}, - {f: 3, c: 31915}, {f: 2, c: 31919}, {f: 5, c: 31924}, {f: 2, c: 31930}, - {f: 2, c: 31935}, {f: 3, c: 31938}, 31942, 31945, 31947, {f: 7, c: 31950}, - 31960, {f: 2, c: 31962}, {f: 6, c: 31969}, {f: 6, c: 31977}, 31985, 31987, - 31989, 31991, 31994, {f: 2, c: 31996}, 31999, 32001, 32003, 32012, - {f: 2, c: 32014}, {f: 2, c: 32017}, 32022, 32024, {f: 3, c: 32029}, - {f: 4, c: 32035}, {f: 3, c: 32040}, {f: 3, c: 32044}, {f: 5, c: 32052}, - 32059, {f: 2, c: 32061}, 32065, 32067, 32069, {f: 7, c: 32071}, 32079, - {f: 12, c: 32081}, {f: 2, c: 32095}, {f: 3, c: 32099}, 32103, - {f: 5, c: 32105}, {f: 2, c: 32111}, {f: 2, c: 32116}, 32120, - {f: 7, c: 32122}, 32130, {f: 2, c: 32132}, 32135, {f: 5, c: 32138}, - {f: 3, c: 32144}, {f: 8, c: 32148}, 32157, {f: 3, c: 32159}, - {f: 2, c: 32164}, {f: 4, c: 32167}, 32175, {f: 3, c: 32181}, 32188, - {f: 4, c: 32192}, {f: 2, c: 32197}, {f: 2, c: 32200}, {f: 5, c: 32204}, - 32211, {f: 2, c: 32213}, {f: 3, c: 32218}, 32223, 32226, {f: 2, c: 32228}, - 32231, {f: 2, c: 32234}, {f: 2, c: 32237}, 32240, 32243, 32245, - {f: 2, c: 32247}, 32250, {f: 12, c: 32252}, {f: 4, c: 32268}, - {f: 9, c: 32274}, 32284, {f: 3, c: 32288}, {f: 3, c: 32292}, - {f: 3, c: 32296}, 32300, {f: 2, c: 32303}, 32307, 32312, 32314, 32316, - {f: 2, c: 32319}, {f: 3, c: 32322}, {f: 10, c: 32328}, 32339, - {f: 4, c: 32342}, {f: 3, c: 32347}, {f: 3, c: 32351}, {f: 6, c: 32355}, - 32364, {f: 2, c: 32369}, {f: 5, c: 32372}, {f: 2, c: 32378}, - {f: 3, c: 32383}, {f: 5, c: 32387}, 32393, 32395, 32398, {f: 3, c: 32400}, - 32405, 32407, {f: 2, c: 32409}, {f: 2, c: 32413}, 32430, 32436, - {f: 2, c: 32443}, 32470, 32484, 32492, 32505, 32522, 32528, 32542, 32567, - 32569, {f: 7, c: 32571}, 32579, {f: 6, c: 32582}, 32589, 32591, - {f: 2, c: 32594}, 32598, 32601, {f: 4, c: 32603}, 32608, {f: 5, c: 32611}, - {f: 3, c: 32619}, 32623, 32627, {f: 2, c: 32629}, 32632, {f: 4, c: 32634}, - {f: 2, c: 32639}, {f: 3, c: 32642}, 32647, 32649, 32651, 32653, - {f: 5, c: 32655}, {f: 5, c: 32661}, {f: 2, c: 32667}, 32672, - {f: 2, c: 32674}, 32678, 32680, {f: 5, c: 32682}, 32689, {f: 5, c: 32691}, - {f: 2, c: 32698}, 32702, 32704, {f: 3, c: 32706}, {f: 4, c: 32710}, 32715, - 32717, {f: 3, c: 32719}, 32723, {f: 2, c: 32726}, {f: 6, c: 32729}, - {f: 3, c: 32738}, {f: 2, c: 32743}, {f: 4, c: 32746}, 32751, 32754, - {f: 5, c: 32756}, 32762, {f: 3, c: 32765}, 32770, {f: 4, c: 32775}, - {f: 2, c: 32782}, 32785, 32787, {f: 2, c: 32794}, {f: 3, c: 32797}, 32801, - {f: 2, c: 32803}, 32811, 32813, {f: 2, c: 32815}, 32818, 32820, - {f: 2, c: 32825}, 32828, 32830, {f: 2, c: 32832}, {f: 2, c: 32836}, - {f: 3, c: 32839}, {f: 4, c: 32846}, 32851, 32853, 32855, 32857, - {f: 3, c: 32859}, {f: 10, c: 32863}, {f: 4, c: 32875}, 32884, 32888, - {f: 3, c: 32890}, {f: 2, c: 32897}, 32904, 32906, {f: 6, c: 32909}, - {f: 2, c: 32916}, 32919, 32921, 32926, 32931, {f: 3, c: 32934}, 32940, - 32944, 32947, {f: 2, c: 32949}, {f: 2, c: 32952}, 32955, 32965, - {f: 5, c: 32967}, {f: 7, c: 32975}, 32984, {f: 2, c: 32991}, - {f: 2, c: 32994}, 32998, 33006, 33013, 33015, 33017, 33019, - {f: 4, c: 33022}, {f: 2, c: 33027}, {f: 2, c: 33031}, {f: 2, c: 33035}, - 33045, 33047, 33049, {f: 2, c: 33052}, {f: 13, c: 33055}, {f: 2, c: 33069}, - 33072, {f: 3, c: 33075}, 33079, {f: 4, c: 33082}, {f: 7, c: 33087}, 33095, - 33097, 33101, 33103, 33106, {f: 2, c: 33111}, {f: 5, c: 33115}, - {f: 3, c: 33122}, 33128, 33130, 33132, 33135, {f: 2, c: 33138}, - {f: 3, c: 33141}, 33153, {f: 5, c: 33155}, 33161, {f: 4, c: 33163}, 33168, - {f: 6, c: 33170}, 33177, {f: 2, c: 33182}, {f: 2, c: 33185}, - {f: 2, c: 33188}, 33191, {f: 8, c: 33195}, {f: 6, c: 33204}, 33212, - {f: 2, c: 33220}, {f: 2, c: 33223}, 33227, 33230, {f: 8, c: 33232}, 33241, - {f: 4, c: 33243}, {f: 2, c: 33249}, {f: 3, c: 33252}, 33257, 33259, - {f: 5, c: 33262}, {f: 5, c: 33269}, 33277, 33279, 33283, 33291, - {f: 2, c: 33294}, 33297, 33299, {f: 6, c: 33301}, 33309, 33312, - {f: 4, c: 33316}, 33321, 33326, 33330, 33338, {f: 2, c: 33340}, - {f: 5, c: 33343}, {f: 2, c: 33349}, 33352, 33354, {f: 3, c: 33356}, - {f: 8, c: 33360}, {f: 4, c: 33371}, {f: 4, c: 33376}, 33381, 33383, - {f: 2, c: 33385}, {f: 2, c: 33388}, {f: 2, c: 33397}, [12171, 33400], - {f: 2, c: 33403}, {f: 2, c: 33408}, 33411, {f: 3, c: 33413}, 33417, 33420, - 33424, {f: 4, c: 33427}, {f: 2, c: 33434}, 33438, 33440, {f: 2, c: 33442}, - 33447, 33458, {f: 2, c: 33461}, 33466, 33468, {f: 2, c: 33471}, - {f: 2, c: 33474}, {f: 2, c: 33477}, 33481, 33488, 33494, {f: 2, c: 33497}, - 33501, 33506, {f: 3, c: 33512}, {f: 3, c: 33516}, 33520, {f: 2, c: 33522}, - {f: 2, c: 33525}, 33528, 33530, {f: 5, c: 33532}, {f: 2, c: 33546}, 33549, - 33552, {f: 2, c: 33554}, 33558, {f: 2, c: 33560}, {f: 10, c: 33565}, - {f: 2, c: 33577}, 33582, 33584, 33586, 33591, 33595, {f: 3, c: 33597}, - {f: 2, c: 33601}, {f: 2, c: 33604}, 33608, {f: 5, c: 33610}, 33619, - {f: 5, c: 33621}, 33629, 33634, {f: 7, c: 33648}, {f: 2, c: 33657}, - {f: 7, c: 33662}, {f: 2, c: 33671}, {f: 3, c: 33675}, {f: 3, c: 33679}, - {f: 2, c: 33684}, 33687, {f: 2, c: 33689}, 33693, 33695, 33697, - {f: 4, c: 33699}, {f: 4, c: 33708}, 33717, 33723, {f: 2, c: 33726}, - {f: 3, c: 33730}, 33734, {f: 2, c: 33736}, 33739, {f: 2, c: 33741}, - {f: 4, c: 33744}, 33749, 33751, {f: 3, c: 33753}, 33758, {f: 3, c: 33762}, - {f: 3, c: 33766}, {f: 4, c: 33771}, {f: 5, c: 33779}, {f: 3, c: 33786}, - {f: 3, c: 33790}, 33794, 33797, {f: 2, c: 33800}, 33808, {f: 6, c: 33810}, - {f: 3, c: 33817}, {f: 6, c: 33822}, {f: 3, c: 33833}, {f: 4, c: 33837}, - {f: 3, c: 33842}, {f: 2, c: 33846}, {f: 3, c: 33849}, {f: 8, c: 33854}, - {f: 2, c: 33863}, {f: 7, c: 33866}, {f: 4, c: 33875}, 33880, - {f: 4, c: 33885}, 33890, 33893, {f: 2, c: 33895}, 33898, 33902, 33904, - 33906, 33908, 33913, {f: 7, c: 33915}, {f: 4, c: 33923}, 33930, 33933, - {f: 4, c: 33935}, {f: 2, c: 33941}, 33944, {f: 2, c: 33946}, - {f: 4, c: 33949}, {f: 13, c: 33954}, {f: 2, c: 33968}, 33971, - {f: 3, c: 33973}, 33979, 33982, {f: 2, c: 33986}, {f: 4, c: 33989}, 33996, - {f: 2, c: 33998}, 34002, {f: 2, c: 34004}, {f: 6, c: 34007}, 34014, - {f: 2, c: 34017}, 34020, {f: 5, c: 34023}, 34029, {f: 11, c: 34033}, 34046, - {f: 12, c: 34048}, {f: 4, c: 34061}, 34066, {f: 2, c: 34069}, - {f: 2, c: 34072}, {f: 3, c: 34075}, 34080, 34082, {f: 2, c: 34084}, - {f: 4, c: 34087}, {f: 9, c: 34094}, {f: 3, c: 34110}, 34114, - {f: 2, c: 34116}, 34119, {f: 3, c: 34123}, {f: 3, c: 34127}, 34132, 34135, - {f: 4, c: 34138}, {f: 3, c: 34143}, 34147, {f: 3, c: 34149}, - {f: 2, c: 34155}, {f: 4, c: 34158}, 34163, {f: 2, c: 34165}, 34168, - {f: 2, c: 34172}, {f: 5, c: 34175}, 34182, 34185, 34187, {f: 2, c: 34189}, - 34192, {f: 2, c: 34194}, {f: 6, c: 34197}, {f: 2, c: 34205}, - {f: 4, c: 34208}, 34213, 34215, {f: 3, c: 34219}, {f: 6, c: 34225}, 34232, - {f: 6, c: 34235}, {f: 7, c: 34242}, {f: 3, c: 34250}, {f: 2, c: 34257}, - 34260, {f: 6, c: 34262}, {f: 6, c: 34270}, {f: 3, c: 34278}, - {f: 9, c: 34283}, 34293, {f: 2, c: 34295}, {f: 3, c: 34300}, - {f: 4, c: 34304}, {f: 3, c: 34312}, {f: 5, c: 34316}, {f: 4, c: 34322}, - {f: 3, c: 34327}, {f: 3, c: 34331}, {f: 3, c: 34335}, {f: 4, c: 34339}, - 34344, {f: 3, c: 34346}, {f: 10, c: 34350}, 34361, 34363, {f: 2, c: 34365}, - {f: 13, c: 34368}, {f: 2, c: 34386}, {f: 4, c: 34390}, 34395, 34397, - {f: 2, c: 34400}, {f: 4, c: 34403}, {f: 3, c: 34408}, 34413, - {f: 2, c: 34415}, {f: 7, c: 34418}, {f: 7, c: 34435}, {f: 5, c: 34446}, - 34452, {f: 6, c: 34454}, {f: 5, c: 34462}, {f: 2, c: 34469}, 34475, - {f: 2, c: 34477}, {f: 2, c: 34482}, {f: 3, c: 34487}, {f: 5, c: 34491}, - {f: 3, c: 34497}, 34501, 34504, {f: 2, c: 34508}, {f: 2, c: 34514}, - {f: 3, c: 34517}, 34522, {f: 2, c: 34524}, {f: 4, c: 34528}, - {f: 4, c: 34533}, {f: 3, c: 34538}, 34543, {f: 3, c: 34549}, - {f: 3, c: 34555}, 34559, 34561, {f: 2, c: 34564}, {f: 2, c: 34571}, - {f: 4, c: 34574}, 34580, 34582, 34585, 34587, 34589, {f: 2, c: 34591}, - 34596, {f: 3, c: 34598}, {f: 4, c: 34602}, {f: 2, c: 34607}, - {f: 2, c: 34610}, {f: 2, c: 34613}, {f: 3, c: 34616}, {f: 2, c: 34620}, - {f: 7, c: 34624}, {f: 2, c: 34634}, 34637, {f: 4, c: 34639}, 34644, 34646, - 34648, {f: 6, c: 34650}, {f: 2, c: 34657}, {f: 7, c: 34663}, 34671, - {f: 3, c: 34673}, 34677, 34679, {f: 2, c: 34681}, {f: 3, c: 34687}, - {f: 2, c: 34694}, {f: 2, c: 34697}, 34700, {f: 5, c: 34702}, - {f: 3, c: 34708}, {f: 6, c: 34712}, {f: 2, c: 34720}, {f: 5, c: 34723}, - {f: 2, c: 34729}, 34734, {f: 3, c: 34736}, 34740, {f: 4, c: 34742}, 34748, - {f: 2, c: 34750}, {f: 3, c: 34753}, 34757, 34759, 34761, {f: 2, c: 34764}, - {f: 2, c: 34767}, {f: 7, c: 34772}, {f: 4, c: 34780}, {f: 2, c: 34785}, - 34788, {f: 4, c: 34790}, 34795, 34797, {f: 2, c: 34800}, {f: 3, c: 34803}, - {f: 2, c: 34807}, 34810, {f: 2, c: 34812}, {f: 4, c: 34815}, 34820, - {f: 3, c: 34823}, {f: 5, c: 34827}, 34834, 34836, {f: 4, c: 34839}, - {f: 3, c: 34844}, 34848, {f: 13, c: 34852}, {f: 3, c: 34867}, - {f: 2, c: 34871}, 34874, {f: 3, c: 34877}, {f: 3, c: 34881}, - {f: 3, c: 34887}, 34891, {f: 5, c: 34894}, {f: 2, c: 34901}, 34904, 34906, - 34908, {f: 3, c: 34910}, {f: 2, c: 34918}, 34922, 34925, 34927, 34929, - {f: 4, c: 34931}, 34936, {f: 3, c: 34938}, 34944, 34947, {f: 2, c: 34950}, - {f: 2, c: 34953}, 34956, {f: 4, c: 34958}, {f: 3, c: 34963}, - {f: 5, c: 34967}, {f: 5, c: 34973}, 34979, {f: 6, c: 34981}, 34988, - {f: 3, c: 34990}, {f: 5, c: 34994}, {f: 4, c: 35000}, {f: 4, c: 35005}, - {f: 2, c: 35011}, {f: 2, c: 35015}, {f: 3, c: 35019}, {f: 2, c: 35024}, - 35027, {f: 2, c: 35030}, {f: 2, c: 35034}, 35038, {f: 2, c: 35040}, - {f: 2, c: 35046}, {f: 7, c: 35049}, 35058, {f: 3, c: 35061}, - {f: 2, c: 35066}, {f: 3, c: 35071}, {f: 4, c: 35075}, {f: 2, c: 35080}, - {f: 5, c: 35083}, 35089, {f: 5, c: 35092}, {f: 5, c: 35100}, - {f: 3, c: 35106}, {f: 4, c: 35110}, {f: 4, c: 35116}, 35121, 35125, 35127, - {f: 2, c: 35129}, {f: 5, c: 35132}, {f: 2, c: 35138}, {f: 2, c: 35141}, - {f: 14, c: 35144}, {f: 6, c: 35159}, {f: 3, c: 35169}, 35173, - {f: 3, c: 35175}, 35179, {f: 2, c: 35181}, {f: 2, c: 35184}, - {f: 8, c: 35187}, {f: 2, c: 35196}, [12177, 35198], 35200, 35202, - {f: 2, c: 35204}, {f: 4, c: 35207}, {f: 3, c: 35212}, {f: 3, c: 35216}, - {f: 2, c: 35220}, 35223, {f: 8, c: 35225}, {f: 4, c: 35234}, - {f: 3, c: 35239}, 35243, {f: 2, c: 35245}, {f: 2, c: 35248}, - {f: 4, c: 35251}, {f: 2, c: 35256}, {f: 2, c: 35259}, 35262, 35267, 35277, - {f: 3, c: 35283}, {f: 3, c: 35287}, 35291, 35293, {f: 4, c: 35295}, 35300, - {f: 4, c: 35303}, {f: 3, c: 35308}, {f: 3, c: 35312}, 35317, 35319, - {f: 7, c: 35321}, {f: 3, c: 35332}, 35337, 35339, 35341, 35343, - {f: 2, c: 35345}, 35348, 35351, {f: 2, c: 35353}, 35356, 35358, - {f: 3, c: 35360}, 35364, {f: 4, c: 35366}, {f: 2, c: 35371}, - {f: 3, c: 35374}, {f: 2, c: 35378}, 35381, {f: 3, c: 35383}, - {f: 3, c: 35387}, {f: 2, c: 35391}, {f: 4, c: 35394}, 35399, - {f: 5, c: 35401}, 35407, 35409, 35411, {f: 2, c: 35414}, {f: 2, c: 35417}, - {f: 2, c: 35420}, {f: 2, c: 35423}, {f: 2, c: 35428}, {f: 2, c: 35431}, - 35434, 35439, 35444, {f: 3, c: 35446}, {f: 2, c: 35450}, {f: 2, c: 35453}, - {f: 4, c: 35456}, 35464, {f: 2, c: 35467}, {f: 3, c: 35470}, 35476, - {f: 2, c: 35478}, 35481, {f: 3, c: 35483}, 35487, 35490, 35495, - {f: 3, c: 35497}, {f: 3, c: 35501}, 35505, {f: 3, c: 35507}, - {f: 2, c: 35511}, {f: 2, c: 35514}, {f: 2, c: 35517}, {f: 2, c: 35520}, - 35523, {f: 2, c: 35525}, 35528, 35530, 35532, 35534, 35536, - {f: 3, c: 35539}, {f: 3, c: 35544}, 35549, {f: 3, c: 35551}, 35555, 35557, - {f: 3, c: 35560}, 35564, {f: 2, c: 35567}, 35570, {f: 2, c: 35572}, 35577, - 35579, 35581, 35583, 35587, 35590, {f: 2, c: 35592}, {f: 3, c: 35595}, - 35599, {f: 3, c: 35601}, 35605, 35608, 35612, {f: 3, c: 35614}, - {f: 4, c: 35618}, 35623, {f: 2, c: 35625}, {f: 5, c: 35630}, - {f: 5, c: 35636}, {f: 4, c: 35642}, {f: 10, c: 35647}, {f: 4, c: 35658}, - {f: 6, c: 35664}, 35671, 35675, {f: 9, c: 35677}, {f: 4, c: 35687}, - {f: 2, c: 35693}, {f: 3, c: 35697}, {f: 2, c: 35701}, {f: 5, c: 35704}, - {f: 2, c: 35710}, {f: 9, c: 35713}, {f: 3, c: 35723}, {f: 3, c: 35727}, - 35732, {f: 5, c: 35735}, 35741, 35743, 35756, 35761, 35771, 35783, 35792, - 35818, 35849, 35870, {f: 9, c: 35896}, {f: 4, c: 35906}, {f: 2, c: 35914}, - {f: 3, c: 35917}, {f: 4, c: 35921}, {f: 4, c: 35926}, {f: 6, c: 35931}, - {f: 7, c: 35939}, {f: 7, c: 35948}, {f: 4, c: 35956}, {f: 7, c: 35963}, - {f: 2, c: 35971}, {f: 3, c: 35974}, 35979, {f: 7, c: 35981}, - {f: 3, c: 35989}, {f: 4, c: 35993}, 35999, {f: 4, c: 36003}, - {f: 2, c: 36013}, 36017, 36021, 36025, 36030, 36038, 36041, - {f: 6, c: 36043}, 36052, {f: 4, c: 36054}, 36059, 36061, 36063, 36069, - {f: 2, c: 36072}, {f: 6, c: 36078}, {f: 5, c: 36085}, {f: 5, c: 36095}, - {f: 2, c: 36102}, 36105, 36108, 36110, {f: 5, c: 36113}, {f: 4, c: 36119}, - 36128, {f: 2, c: 36177}, 36183, 36191, 36197, {f: 3, c: 36200}, 36204, - {f: 2, c: 36206}, {f: 2, c: 36209}, {f: 9, c: 36216}, {f: 2, c: 36226}, - {f: 4, c: 36230}, {f: 5, c: 36236}, {f: 2, c: 36242}, {f: 3, c: 36246}, - {f: 5, c: 36250}, {f: 3, c: 36256}, {f: 4, c: 36260}, {f: 8, c: 36265}, - {f: 2, c: 36278}, 36281, 36283, 36285, {f: 3, c: 36288}, 36293, - {f: 4, c: 36295}, 36301, 36304, {f: 4, c: 36306}, {f: 2, c: 36312}, 36316, - {f: 3, c: 36320}, {f: 3, c: 36325}, 36329, {f: 2, c: 36333}, - {f: 3, c: 36336}, 36340, 36342, 36348, {f: 7, c: 36350}, {f: 3, c: 36358}, - 36363, {f: 2, c: 36365}, {f: 3, c: 36369}, {f: 8, c: 36373}, - {f: 2, c: 36384}, {f: 5, c: 36388}, 36395, 36397, 36400, {f: 2, c: 36402}, - {f: 3, c: 36406}, {f: 2, c: 36411}, {f: 2, c: 36414}, 36419, - {f: 2, c: 36421}, {f: 4, c: 36429}, {f: 2, c: 36435}, {f: 3, c: 36438}, - {f: 9, c: 36442}, {f: 2, c: 36452}, {f: 2, c: 36455}, {f: 2, c: 36458}, - 36462, 36465, 36467, 36469, {f: 3, c: 36471}, 36475, {f: 2, c: 36477}, - 36480, {f: 3, c: 36482}, 36486, 36488, 36492, 36494, {f: 5, c: 36501}, - 36507, 36509, {f: 2, c: 36511}, {f: 3, c: 36514}, {f: 3, c: 36519}, - {f: 2, c: 36525}, {f: 2, c: 36528}, {f: 7, c: 36531}, {f: 5, c: 36539}, - {f: 9, c: 36545}, {f: 3, c: 36559}, 36563, {f: 6, c: 36565}, - {f: 3, c: 36572}, {f: 4, c: 36576}, {f: 6, c: 36581}, {f: 6, c: 36588}, - {f: 5, c: 36595}, 36605, {f: 4, c: 36607}, 36612, 36614, 36616, - {f: 7, c: 36619}, 36627, {f: 5, c: 36630}, {f: 5, c: 36640}, - {f: 2, c: 36647}, {f: 4, c: 36651}, {f: 3, c: 36656}, {f: 4, c: 36660}, - {f: 2, c: 36665}, {f: 2, c: 36668}, {f: 2, c: 36672}, 36675, - {f: 2, c: 36679}, {f: 3, c: 36682}, {f: 5, c: 36687}, {f: 10, c: 36693}, - 36704, 36707, 36709, 36714, 36736, 36748, 36754, 36765, {f: 3, c: 36768}, - {f: 2, c: 36772}, 36775, 36778, 36780, {f: 2, c: 36787}, [12193, 36789], - {f: 2, c: 36791}, {f: 3, c: 36794}, {f: 2, c: 36799}, 36803, 36806, - {f: 5, c: 36809}, 36815, 36818, {f: 2, c: 36822}, 36826, {f: 2, c: 36832}, - 36835, 36839, 36844, 36847, {f: 2, c: 36849}, {f: 2, c: 36853}, - {f: 3, c: 36858}, {f: 2, c: 36862}, {f: 2, c: 36871}, 36876, 36878, 36883, - 36888, 36892, {f: 2, c: 36900}, {f: 6, c: 36903}, {f: 2, c: 36912}, - {f: 2, c: 36915}, 36919, {f: 2, c: 36921}, 36925, {f: 2, c: 36927}, 36931, - {f: 2, c: 36933}, {f: 3, c: 36936}, 36940, 36950, {f: 2, c: 36953}, 36957, - 36959, 36961, 36964, {f: 2, c: 36966}, {f: 3, c: 36970}, {f: 3, c: 36975}, - 36979, 36982, 36985, 36987, 36990, {f: 2, c: 36997}, 37001, - {f: 3, c: 37004}, 37010, 37012, 37014, 37016, 37018, 37020, - {f: 3, c: 37022}, {f: 2, c: 37028}, {f: 3, c: 37031}, 37035, 37037, 37042, - 37047, {f: 2, c: 37052}, {f: 2, c: 37055}, {f: 2, c: 37058}, 37062, - {f: 2, c: 37064}, {f: 3, c: 37067}, 37074, {f: 3, c: 37076}, - {f: 3, c: 37080}, 37086, 37088, {f: 3, c: 37091}, {f: 2, c: 37097}, 37100, - 37102, {f: 4, c: 37104}, {f: 2, c: 37110}, {f: 4, c: 37113}, - {f: 3, c: 37119}, 37123, 37125, {f: 2, c: 37127}, {f: 8, c: 37130}, 37139, - 37141, {f: 2, c: 37143}, {f: 4, c: 37146}, {f: 3, c: 37151}, - {f: 3, c: 37156}, {f: 5, c: 37160}, 37166, 37171, 37173, {f: 2, c: 37175}, - {f: 8, c: 37179}, {f: 2, c: 37188}, 37191, 37201, {f: 4, c: 37203}, - {f: 2, c: 37208}, {f: 2, c: 37211}, {f: 2, c: 37215}, {f: 3, c: 37222}, - 37227, 37229, 37235, {f: 3, c: 37242}, {f: 5, c: 37248}, 37254, 37256, - 37258, {f: 2, c: 37262}, {f: 3, c: 37267}, {f: 3, c: 37271}, - {f: 5, c: 37277}, {f: 6, c: 37284}, {f: 4, c: 37296}, {f: 4, c: 37302}, - {f: 5, c: 37307}, 37314, 37316, [12196, 37318], 37320, 37328, 37334, - {f: 2, c: 37338}, {f: 5, c: 37342}, {f: 2, c: 37349}, 37352, - {f: 11, c: 37354}, 37366, 37368, {f: 5, c: 37371}, {f: 2, c: 37378}, - {f: 3, c: 37381}, {f: 3, c: 37386}, 37391, {f: 2, c: 37394}, - {f: 8, c: 37398}, {f: 4, c: 37407}, 37412, {f: 6, c: 37416}, 37423, - {f: 2, c: 37425}, {f: 2, c: 37429}, {f: 2, c: 37435}, {f: 4, c: 37441}, - {f: 2, c: 37446}, {f: 3, c: 37450}, {f: 3, c: 37454}, {f: 3, c: 37458}, - 37462, {f: 2, c: 37464}, {f: 2, c: 37468}, {f: 3, c: 37471}, - {f: 3, c: 37475}, {f: 5, c: 37479}, {f: 6, c: 37486}, {f: 3, c: 37493}, - 37497, {f: 3, c: 37500}, {f: 2, c: 37505}, 37508, {f: 8, c: 37510}, - {f: 2, c: 37519}, 37522, {f: 2, c: 37524}, 37527, 37529, 37531, - {f: 3, c: 37533}, {f: 2, c: 37537}, 37540, 37543, 37549, {f: 2, c: 37551}, - {f: 5, c: 37554}, 37560, 37562, {f: 4, c: 37565}, 37570, 37572, 37574, - {f: 3, c: 37577}, {f: 2, c: 37581}, {f: 2, c: 37584}, {f: 10, c: 37587}, - 37598, {f: 3, c: 37600}, 37607, 37609, {f: 2, c: 37611}, {f: 4, c: 37618}, - 37623, {f: 3, c: 37625}, {f: 4, c: 37629}, {f: 4, c: 37634}, - {f: 7, c: 37641}, 37649, {f: 2, c: 37651}, {f: 2, c: 37654}, - {f: 3, c: 37660}, 37665, {f: 3, c: 37667}, 37671, {f: 2, c: 37673}, - {f: 2, c: 37676}, {f: 2, c: 37680}, {f: 2, c: 37684}, 37687, - {f: 5, c: 37689}, 37695, 37698, {f: 2, c: 37700}, {f: 3, c: 37704}, 37708, - {f: 6, c: 37710}, {f: 3, c: 37717}, {f: 2, c: 37721}, {f: 8, c: 37724}, - {f: 3, c: 37734}, 37739, {f: 3, c: 37741}, {f: 4, c: 37745}, - {f: 3, c: 37751}, {f: 3, c: 37755}, {f: 3, c: 37759}, 37763, - {f: 2, c: 37765}, {f: 2, c: 37768}, {f: 4, c: 37771}, {f: 6, c: 37776}, - 37783, {f: 9, c: 37785}, {f: 2, c: 37796}, 37800, 37803, 37805, 37807, - {f: 2, c: 37809}, 37812, {f: 2, c: 37814}, {f: 6, c: 37817}, - {f: 3, c: 37824}, {f: 3, c: 37828}, 37833, 37835, {f: 3, c: 37838}, - {f: 4, c: 37842}, {f: 3, c: 37849}, 37856, 37859, {f: 3, c: 37861}, - {f: 12, c: 37865}, 37878, 37880, {f: 9, c: 37882}, {f: 7, c: 37892}, - {f: 4, c: 37900}, 37905, {f: 3, c: 37909}, {f: 3, c: 37914}, - {f: 2, c: 37918}, {f: 5, c: 37921}, {f: 5, c: 37929}, {f: 3, c: 37935}, - 37940, {f: 2, c: 37942}, 37945, {f: 3, c: 37947}, {f: 4, c: 37952}, - {f: 5, c: 37957}, 37963, {f: 5, c: 37965}, 37971, {f: 11, c: 37973}, - {f: 2, c: 37985}, 37988, {f: 5, c: 37990}, 37996, {f: 2, c: 37998}, 38001, - {f: 4, c: 38003}, 38008, {f: 2, c: 38010}, {f: 5, c: 38016}, 38033, 38038, - 38040, 38087, 38095, {f: 2, c: 38099}, 38106, 38118, 38139, 38172, 38176, - 38183, 38195, 38205, 38211, 38216, 38219, 38229, 38234, 38240, 38254, - {f: 2, c: 38260}, {f: 7, c: 38264}, 38273, {f: 2, c: 38276}, - {f: 2, c: 38279}, 38282, 38285, 38288, 38290, {f: 3, c: 38293}, - {f: 8, c: 38297}, 38306, {f: 2, c: 38310}, 38314, {f: 4, c: 38318}, - {f: 3, c: 38323}, {f: 2, c: 38327}, 38330, {f: 3, c: 38336}, - {f: 2, c: 38340}, 38343, 38345, {f: 3, c: 38349}, {f: 3, c: 38353}, - {f: 5, c: 38359}, 38365, {f: 2, c: 38367}, {f: 2, c: 38371}, - {f: 2, c: 38374}, 38380, 38399, 38407, 38419, 38424, 38427, 38430, 38432, - {f: 7, c: 38435}, {f: 3, c: 38443}, {f: 2, c: 38447}, {f: 4, c: 38455}, - 38462, 38465, 38467, 38474, {f: 2, c: 38478}, {f: 3, c: 38481}, - {f: 2, c: 38486}, {f: 2, c: 38489}, 38492, 38494, 38496, {f: 2, c: 38501}, - 38507, {f: 3, c: 38509}, 38513, {f: 4, c: 38521}, {f: 7, c: 38526}, 38535, - 38537, 38540, {f: 3, c: 38545}, 38550, 38554, {f: 10, c: 38557}, 38569, - {f: 5, c: 38571}, 38578, 38581, 38583, 38586, 38591, {f: 2, c: 38594}, - 38600, {f: 2, c: 38602}, {f: 2, c: 38608}, {f: 2, c: 38611}, - {f: 2, c: 38615}, 38618, {f: 3, c: 38621}, 38625, {f: 4, c: 38628}, - {f: 4, c: 38635}, {f: 2, c: 38640}, {f: 2, c: 38644}, 38648, 38650, - {f: 2, c: 38652}, 38655, {f: 2, c: 38658}, 38661, {f: 3, c: 38666}, - {f: 3, c: 38672}, {f: 2, c: 38676}, {f: 5, c: 38679}, 38685, - {f: 8, c: 38687}, {f: 2, c: 38696}, {f: 2, c: 38699}, {f: 2, c: 38702}, - 38705, {f: 5, c: 38707}, {f: 3, c: 38714}, {f: 3, c: 38719}, 38723, - {f: 3, c: 38725}, {f: 8, c: 38729}, [12205, 38737], {f: 2, c: 38740}, - {f: 2, c: 38743}, {f: 2, c: 38748}, 38751, {f: 2, c: 38755}, - {f: 2, c: 38758}, {f: 9, c: 38762}, 38773, {f: 5, c: 38775}, - {f: 8, c: 38781}, {f: 5, c: 38790}, 38796, 38798, 38800, 38803, - {f: 3, c: 38805}, {f: 7, c: 38809}, {f: 2, c: 38817}, {f: 2, c: 38820}, - {f: 4, c: 38823}, 38828, 38830, {f: 2, c: 38832}, 38835, {f: 8, c: 38837}, - {f: 5, c: 38846}, {f: 2, c: 38852}, {f: 2, c: 38855}, 38858, - {f: 6, c: 38861}, {f: 5, c: 38868}, {f: 2, c: 38874}, 38877, - {f: 7, c: 38879}, 38888, {f: 5, c: 38894}, 38900, {f: 8, c: 38903}, 38912, - 38916, 38921, 38923, 38925, {f: 3, c: 38932}, {f: 3, c: 38937}, - {f: 4, c: 38941}, {f: 2, c: 38946}, 38949, {f: 6, c: 38951}, - {f: 2, c: 38958}, {f: 6, c: 38961}, {f: 2, c: 38969}, 38972, - {f: 8, c: 38974}, {f: 5, c: 38983}, {f: 4, c: 38991}, {f: 3, c: 38997}, - 39002, {f: 2, c: 39004}, {f: 3, c: 39007}, {f: 2, c: 39011}, 39014, - {f: 3, c: 39016}, {f: 2, c: 39021}, 39026, 39051, 39054, 39058, 39061, - 39065, 39075, {f: 5, c: 39081}, 39088, 39090, {f: 2, c: 39092}, - {f: 5, c: 39095}, {f: 7, c: 39101}, 39109, 39111, {f: 5, c: 39113}, - {f: 2, c: 39119}, 39124, {f: 2, c: 39126}, {f: 2, c: 39132}, 39137, - {f: 4, c: 39139}, 39148, 39150, {f: 2, c: 39152}, 39155, {f: 7, c: 39157}, - {f: 4, c: 39167}, 39172, {f: 3, c: 39174}, 39179, {f: 2, c: 39182}, - {f: 4, c: 39188}, {f: 2, c: 39193}, {f: 2, c: 39196}, {f: 2, c: 39199}, - {f: 6, c: 39202}, {f: 5, c: 39209}, {f: 4, c: 39215}, {f: 3, c: 39220}, - {f: 4, c: 39224}, 39229, {f: 3, c: 39232}, 39236, {f: 2, c: 39238}, - {f: 4, c: 39245}, 39251, 39254, {f: 4, c: 39256}, 39261, {f: 3, c: 39263}, - 39268, 39270, 39283, {f: 2, c: 39288}, 39291, 39294, {f: 2, c: 39298}, - 39305, 39308, 39310, {f: 11, c: 39322}, {f: 2, c: 39334}, {f: 3, c: 39337}, - {f: 2, c: 39343}, 39346, {f: 12, c: 39349}, {f: 14, c: 39362}, 39379, - {f: 2, c: 39382}, 39386, 39388, 39390, 39392, {f: 10, c: 39395}, - {f: 3, c: 39406}, {f: 13, c: 39410}, 39424, {f: 3, c: 39426}, - {f: 7, c: 39430}, {f: 6, c: 39440}, {f: 2, c: 39447}, {f: 17, c: 39450}, - 39468, 39471, {f: 5, c: 39473}, {f: 5, c: 39481}, 39487, {f: 4, c: 39494}, - {f: 2, c: 39499}, 39502, {f: 5, c: 39504}, 39510, {f: 2, c: 39512}, - {f: 3, c: 39516}, {f: 2, c: 39520}, 39523, {f: 4, c: 39526}, 39531, 39538, - 39555, 39561, {f: 2, c: 39565}, {f: 2, c: 39572}, 39577, 39590, - {f: 6, c: 39593}, {f: 4, c: 39602}, 39609, 39611, {f: 3, c: 39613}, - {f: 2, c: 39619}, {f: 5, c: 39622}, {f: 2, c: 39629}, 39632, 39639, - {f: 6, c: 39641}, 39648, {f: 4, c: 39650}, {f: 4, c: 39655}, 39660, - {f: 9, c: 39664}, 39674, {f: 7, c: 39676}, {f: 2, c: 39684}, 39687, - {f: 4, c: 39689}, 39694, {f: 3, c: 39696}, {f: 6, c: 39700}, - {f: 4, c: 39707}, {f: 2, c: 39712}, 39716, 39718, 39720, {f: 4, c: 39722}, - 39728, {f: 8, c: 39731}, {f: 4, c: 39741}, 39750, {f: 3, c: 39754}, 39760, - {f: 2, c: 39762}, {f: 3, c: 39765}, 39769, {f: 20, c: 39771}, - {f: 4, c: 39792}, {f: 2, c: 39797}, {f: 9, c: 39800}, 39810, - {f: 10, c: 39812}, 39823, {f: 7, c: 39827}, {f: 2, c: 39835}, - {f: 11, c: 39839}, 39852, {f: 17, c: 39855}, {f: 5, c: 39874}, 39880, - {f: 9, c: 39883}, 39893, {f: 4, c: 39895}, 39900, {f: 3, c: 39902}, 39907, - {f: 2, c: 39909}, 39913, {f: 4, c: 39916}, {f: 3, c: 39921}, - {f: 8, c: 39925}, 39934, {f: 8, c: 39936}, {f: 3, c: 39946}, - {f: 2, c: 39950}, 39953, {f: 12, c: 39956}, {f: 2, c: 39969}, 39972, - {f: 2, c: 39974}, {f: 3, c: 39978}, {f: 3, c: 39982}, 39988, 39990, 39992, - 39994, {f: 2, c: 39996}, {f: 6, c: 39999}, {f: 2, c: 40006}, - {f: 8, c: 40010}, 40019, 40021, {f: 4, c: 40025}, 40030, {f: 7, c: 40032}, - {f: 5, c: 40040}, {f: 10, c: 40046}, 40057, 40059, {f: 2, c: 40061}, 40064, - {f: 2, c: 40067}, {f: 2, c: 40073}, 40076, 40079, 40083, {f: 4, c: 40086}, - 40093, 40106, 40108, 40111, 40121, {f: 5, c: 40126}, {f: 2, c: 40136}, - {f: 2, c: 40145}, {f: 2, c: 40154}, {f: 2, c: 40160}, {f: 2, c: 40163}, - {f: 3, c: 40166}, {f: 2, c: 40170}, {f: 6, c: 40173}, 40181, - {f: 15, c: 40183}, 40200, {f: 11, c: 40202}, {f: 5, c: 40214}, 40220, - 40222, {f: 3, c: 40224}, {f: 2, c: 40228}, 40231, {f: 6, c: 40233}, - {f: 10, c: 40241}, {f: 3, c: 40252}, {f: 2, c: 40256}, {f: 14, c: 40259}, - {f: 8, c: 40276}, {f: 2, c: 40286}, {f: 8, c: 40290}, 40299, - {f: 2, c: 40301}, {f: 2, c: 40304}, {f: 20, c: 40307}, 40328, - {f: 9, c: 40330}, {f: 4, c: 40340}, 40345, {f: 10, c: 40347}, - {f: 3, c: 40358}, {f: 5, c: 40362}, {f: 4, c: 40368}, {f: 6, c: 40373}, - {f: 3, c: 40381}, 40385, 40387, {f: 14, c: 40389}, {f: 3, c: 40404}, 40408, - {f: 10, c: 40411}, {f: 8, c: 40423}, {f: 2, c: 40432}, {f: 4, c: 40436}, - {f: 17, c: 40443}, {f: 8, c: 40461}, {f: 4, c: 40470}, 40476, 40484, 40487, - 40494, 40496, 40500, {f: 2, c: 40507}, 40512, 40525, 40528, - {f: 3, c: 40530}, 40534, 40537, 40541, {f: 4, c: 40543}, 40549, - {f: 2, c: 40558}, 40562, 40564, {f: 3, c: 40566}, 40571, {f: 2, c: 40576}, - {f: 4, c: 40579}, {f: 2, c: 40585}, {f: 6, c: 40588}, {f: 3, c: 40596}, - {f: 5, c: 40600}, 40606, {f: 5, c: 40608}, {f: 2, c: 40615}, - {f: 5, c: 40618}, {f: 4, c: 40624}, {f: 2, c: 40630}, {f: 2, c: 40633}, - 40636, {f: 4, c: 40639}, [12232, 40643], {f: 4, c: 40645}, - {f: 2, c: 40650}, 40656, {f: 2, c: 40658}, {f: 3, c: 40661}, - {f: 2, c: 40665}, 40673, {f: 2, c: 40675}, 40678, {f: 4, c: 40683}, - {f: 2, c: 40688}, 40691, {f: 2, c: 40693}, 40696, 40698, {f: 9, c: 40704}, - 40714, 40716, 40719, {f: 2, c: 40721}, 40724, 40726, 40728, - {f: 6, c: 40730}, 40737, {f: 9, c: 40739}, {f: 2, c: 40749}, - {f: 7, c: 40752}, 40760, 40762, 40764, {f: 5, c: 40767}, {f: 5, c: 40773}, - {f: 3, c: 40780}, 40787, {f: 4, c: 40789}, {f: 2, c: 40794}, - {f: 2, c: 40797}, 40802, {f: 2, c: 40804}, {f: 3, c: 40807}, 40811, - {f: 5, c: 40813}, {f: 4, c: 40819}, {f: 7, c: 40824}, {f: 2, c: 40833}, - {f: 2, c: 40846}, {f: 3, c: 40849}, {f: 3, c: 40854}, {f: 2, c: 40861}, - {f: 5, c: 40865}, 63788, {f: 3, c: 64013}, 64017, {f: 2, c: 64019}, 64024, - {f: 3, c: 64031}, {f: 2, c: 64035}, {f: 3, c: 64039}, 11905, - [59414, 131207], [59415, 131209], [59416, 131276], 11908, 13427, 13383, - 11912, 11915, 59422, 13726, 13850, 13838, 11916, 11927, 14702, 14616, - 59430, 14799, 14815, 14963, 14800, {f: 2, c: 59435}, 15182, 15470, 15584, - 11943, [59441, 136663], 59442, 11946, 16470, 16735, 11950, 17207, 11955, - {f: 2, c: 11958}, [59451, 141711], 17329, 17324, 11963, 17373, 17622, - 18017, 17996, [59459, 132361], 18211, 18217, 18300, 18317, 11978, 18759, - 18810, 18813, {f: 2, c: 18818}, {f: 2, c: 18821}, 18847, 18843, 18871, - 18870, [59476, 133533], [59477, 147966], 19619, {f: 3, c: 19615}, 19575, - 19618, {f: 7, c: 19731}, 19886, 59492, {s: 226}, 8364, 165, 0, 0, 12351, - {s: 17}, 12436, {s: 14}, 12535, 12537, 12536, 12538, 0, {f: 3, c: 12339}, - {f: 3, c: 12344}, {f: 3, c: 12586}, {f: 24, c: 12704}, 11904, - {f: 2, c: 11906}, {f: 3, c: 11909}, {f: 2, c: 11913}, {f: 10, c: 11917}, - {f: 2, c: 11928}, {f: 12, c: 11931}, {f: 2, c: 11944}, {f: 3, c: 11947}, - {f: 4, c: 11951}, {f: 2, c: 11956}, {f: 3, c: 11960}, {f: 14, c: 11964}, - {f: 41, c: 11979}, {f: 71, c: 13312}, {f: 43, c: 13384}, - {f: 298, c: 13428}, {f: 111, c: 13727}, {f: 11, c: 13839}, - {f: 765, c: 13851}, {f: 85, c: 14617}, {f: 96, c: 14703}, - {f: 14, c: 14801}, {f: 147, c: 14816}, {f: 218, c: 14964}, - {f: 287, c: 15183}, {f: 113, c: 15471}, {f: 885, c: 15585}, - {f: 264, c: 16471}, {f: 471, c: 16736}, {f: 116, c: 17208}, - {f: 4, c: 17325}, {f: 43, c: 17330}, {f: 248, c: 17374}, - {f: 373, c: 17623}, {f: 20, c: 17997}, {f: 193, c: 18018}, - {f: 5, c: 18212}, {f: 82, c: 18218}, {f: 16, c: 18301}, {f: 441, c: 18318}, - {f: 50, c: 18760}, {f: 2, c: 18811}, {f: 4, c: 18814}, 18820, - {f: 20, c: 18823}, {f: 3, c: 18844}, {f: 22, c: 18848}, {f: 703, c: 18872}, - {f: 39, c: 19576}, {f: 111, c: 19620}, {f: 148, c: 19738}, - {f: 7, c: 19887}] -}; - - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var ColorSpace = (function ColorSpaceClosure() { - // Constructor should define this.numComps, this.defaultColor, this.name - function ColorSpace() { - error('should not call ColorSpace constructor'); - } - - ColorSpace.prototype = { - // Input: array of size numComps representing color component values - // Output: array of rgb values, each value ranging from [0.1] - getRgb: function ColorSpace_getRgb(color) { - error('Should not call ColorSpace.getRgb: ' + color); - }, - // Input: Uint8Array of component values, each value scaled to [0,255] - // Output: Uint8Array of rgb values, each value scaled to [0,255] - getRgbBuffer: function ColorSpace_getRgbBuffer(input) { - error('Should not call ColorSpace.getRgbBuffer: ' + input); - } - }; - - ColorSpace.parse = function ColorSpace_parse(cs, xref, res) { - var IR = ColorSpace.parseToIR(cs, xref, res); - if (IR instanceof AlternateCS) - return IR; - - return ColorSpace.fromIR(IR); - }; - - ColorSpace.fromIR = function ColorSpace_fromIR(IR) { - var name = isArray(IR) ? IR[0] : IR; - - switch (name) { - case 'DeviceGrayCS': - return new DeviceGrayCS(); - case 'DeviceRgbCS': - return new DeviceRgbCS(); - case 'DeviceCmykCS': - return new DeviceCmykCS(); - case 'PatternCS': - var basePatternCS = IR[1]; - if (basePatternCS) - basePatternCS = ColorSpace.fromIR(basePatternCS); - return new PatternCS(basePatternCS); - case 'IndexedCS': - var baseIndexedCS = IR[1]; - var hiVal = IR[2]; - var lookup = IR[3]; - return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup); - case 'AlternateCS': - var numComps = IR[1]; - var alt = IR[2]; - var tintFnIR = IR[3]; - - return new AlternateCS(numComps, ColorSpace.fromIR(alt), - PDFFunction.fromIR(tintFnIR)); - case 'LabCS': - var whitePoint = IR[1].WhitePoint; - var blackPoint = IR[1].BlackPoint; - var range = IR[1].Range; - return new LabCS(whitePoint, blackPoint, range); - default: - error('Unkown name ' + name); - } - return null; - }; - - ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) { - if (isName(cs)) { - var colorSpaces = res.get('ColorSpace'); - if (isDict(colorSpaces)) { - var refcs = colorSpaces.get(cs.name); - if (refcs) - cs = refcs; - } - } - - cs = xref.fetchIfRef(cs); - var mode; - - if (isName(cs)) { - mode = cs.name; - this.mode = mode; - - switch (mode) { - case 'DeviceGray': - case 'G': - return 'DeviceGrayCS'; - case 'DeviceRGB': - case 'RGB': - return 'DeviceRgbCS'; - case 'DeviceCMYK': - case 'CMYK': - return 'DeviceCmykCS'; - case 'Pattern': - return ['PatternCS', null]; - default: - error('unrecognized colorspace ' + mode); - } - } else if (isArray(cs)) { - mode = cs[0].name; - this.mode = mode; - - switch (mode) { - case 'DeviceGray': - case 'G': - return 'DeviceGrayCS'; - case 'DeviceRGB': - case 'RGB': - return 'DeviceRgbCS'; - case 'DeviceCMYK': - case 'CMYK': - return 'DeviceCmykCS'; - case 'CalGray': - return 'DeviceGrayCS'; - case 'CalRGB': - return 'DeviceRgbCS'; - case 'ICCBased': - var stream = xref.fetchIfRef(cs[1]); - var dict = stream.dict; - var numComps = dict.get('N'); - if (numComps == 1) - return 'DeviceGrayCS'; - if (numComps == 3) - return 'DeviceRgbCS'; - if (numComps == 4) - return 'DeviceCmykCS'; - break; - case 'Pattern': - var basePatternCS = cs[1]; - if (basePatternCS) - basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res); - return ['PatternCS', basePatternCS]; - case 'Indexed': - case 'I': - var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res); - var hiVal = cs[2] + 1; - var lookup = xref.fetchIfRef(cs[3]); - return ['IndexedCS', baseIndexedCS, hiVal, lookup]; - case 'Separation': - case 'DeviceN': - var name = cs[1]; - var numComps = 1; - if (isName(name)) - numComps = 1; - else if (isArray(name)) - numComps = name.length; - var alt = ColorSpace.parseToIR(cs[2], xref, res); - var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3])); - return ['AlternateCS', numComps, alt, tintFnIR]; - case 'Lab': - var params = cs[1].getAll(); - return ['LabCS', params]; - default: - error('unimplemented color space object "' + mode + '"'); - } - } else { - error('unrecognized color space object: "' + cs + '"'); - } - return null; - }; - /** - * Checks if a decode map matches the default decode map for a color space. - * This handles the general decode maps where there are two values per - * component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color. - * This does not handle Lab, Indexed, or Pattern decode maps since they are - * slightly different. - * @param {Array} decode Decode map (usually from an image). - * @param {Number} n Number of components the color space has. - */ - ColorSpace.isDefaultDecode = function ColorSpace_isDefaultDecode(decode, n) { - if (!decode) - return true; - - if (n * 2 !== decode.length) { - warning('The decode map is not the correct length'); - return true; - } - for (var i = 0, ii = decode.length; i < ii; i += 2) { - if (decode[i] != 0 || decode[i + 1] != 1) - return false; - } - return true; - }; - - return ColorSpace; -})(); - -/** - * Alternate color space handles both Separation and DeviceN color spaces. A - * Separation color space is actually just a DeviceN with one color component. - * Both color spaces use a tinting function to convert colors to a base color - * space. - */ -var AlternateCS = (function AlternateCSClosure() { - function AlternateCS(numComps, base, tintFn) { - this.name = 'Alternate'; - this.numComps = numComps; - this.defaultColor = []; - for (var i = 0; i < numComps; ++i) - this.defaultColor.push(1); - this.base = base; - this.tintFn = tintFn; - } - - AlternateCS.prototype = { - getRgb: function AlternateCS_getRgb(color) { - var tinted = this.tintFn(color); - return this.base.getRgb(tinted); - }, - getRgbBuffer: function AlternateCS_getRgbBuffer(input, bits) { - var tintFn = this.tintFn; - var base = this.base; - var scale = 1 / ((1 << bits) - 1); - var length = input.length; - var pos = 0; - var baseNumComps = base.numComps; - var baseBuf = new Uint8Array(baseNumComps * length); - var numComps = this.numComps; - var scaled = []; - - for (var i = 0; i < length; i += numComps) { - for (var z = 0; z < numComps; ++z) - scaled[z] = input[i + z] * scale; - - var tinted = tintFn(scaled); - for (var j = 0; j < baseNumComps; ++j) - baseBuf[pos++] = 255 * tinted[j]; - } - return base.getRgbBuffer(baseBuf, 8); - }, - isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - } - }; - - return AlternateCS; -})(); - -var PatternCS = (function PatternCSClosure() { - function PatternCS(baseCS) { - this.name = 'Pattern'; - this.base = baseCS; - } - PatternCS.prototype = {}; - - return PatternCS; -})(); - -var IndexedCS = (function IndexedCSClosure() { - function IndexedCS(base, highVal, lookup) { - this.name = 'Indexed'; - this.numComps = 1; - this.defaultColor = [0]; - this.base = base; - this.highVal = highVal; - - var baseNumComps = base.numComps; - var length = baseNumComps * highVal; - var lookupArray = new Uint8Array(length); - - if (isStream(lookup)) { - var bytes = lookup.getBytes(length); - lookupArray.set(bytes); - } else if (isString(lookup)) { - for (var i = 0; i < length; ++i) - lookupArray[i] = lookup.charCodeAt(i); - } else { - error('Unrecognized lookup table: ' + lookup); - } - this.lookup = lookupArray; - } - - IndexedCS.prototype = { - getRgb: function IndexedCS_getRgb(color) { - var numComps = this.base.numComps; - var start = color[0] * numComps; - var c = []; - - for (var i = start, ii = start + numComps; i < ii; ++i) - c.push(this.lookup[i]); - - return this.base.getRgb(c); - }, - getRgbBuffer: function IndexedCS_getRgbBuffer(input) { - var base = this.base; - var numComps = base.numComps; - var lookup = this.lookup; - var length = input.length; - var baseBuf = new Uint8Array(length * numComps); - var baseBufPos = 0; - - for (var i = 0; i < length; ++i) { - var lookupPos = input[i] * numComps; - for (var j = 0; j < numComps; ++j) { - baseBuf[baseBufPos++] = lookup[lookupPos + j]; - } - } - - return base.getRgbBuffer(baseBuf, 8); - }, - isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) { - // indexed color maps shouldn't be changed - return true; - } - }; - return IndexedCS; -})(); - -var DeviceGrayCS = (function DeviceGrayCSClosure() { - function DeviceGrayCS() { - this.name = 'DeviceGray'; - this.numComps = 1; - this.defaultColor = [0]; - } - - DeviceGrayCS.prototype = { - getRgb: function DeviceGrayCS_getRgb(color) { - var c = color[0]; - return [c, c, c]; - }, - getRgbBuffer: function DeviceGrayCS_getRgbBuffer(input, bits) { - var scale = 255 / ((1 << bits) - 1); - var length = input.length; - var rgbBuf = new Uint8Array(length * 3); - for (var i = 0, j = 0; i < length; ++i) { - var c = (scale * input[i]) | 0; - rgbBuf[j++] = c; - rgbBuf[j++] = c; - rgbBuf[j++] = c; - } - return rgbBuf; - }, - isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - } - }; - return DeviceGrayCS; -})(); - -var DeviceRgbCS = (function DeviceRgbCSClosure() { - function DeviceRgbCS() { - this.name = 'DeviceRGB'; - this.numComps = 3; - this.defaultColor = [0, 0, 0]; - } - DeviceRgbCS.prototype = { - getRgb: function DeviceRgbCS_getRgb(color) { - return color; - }, - getRgbBuffer: function DeviceRgbCS_getRgbBuffer(input, bits) { - if (bits == 8) - return input; - var scale = 255 / ((1 << bits) - 1); - var i, length = input.length; - var rgbBuf = new Uint8Array(length); - for (i = 0; i < length; ++i) - rgbBuf[i] = (scale * input[i]) | 0; - return rgbBuf; - }, - isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - } - }; - return DeviceRgbCS; -})(); - -var DeviceCmykCS = (function DeviceCmykCSClosure() { - function DeviceCmykCS() { - this.name = 'DeviceCMYK'; - this.numComps = 4; - this.defaultColor = [0, 0, 0, 1]; - } - DeviceCmykCS.prototype = { - getRgb: function DeviceCmykCS_getRgb(color) { - var c = color[0], m = color[1], y = color[2], k = color[3]; - - // CMYK -> CMY: http://www.easyrgb.com/index.php?X=MATH&H=14#text14 - c = (c * (1 - k) + k); - m = (m * (1 - k) + k); - y = (y * (1 - k) + k); - - // CMY -> RGB: http://www.easyrgb.com/index.php?X=MATH&H=12#text12 - var r = (1 - c); - var g = (1 - m); - var b = (1 - y); - - return [r, g, b]; - }, - getRgbBuffer: function DeviceCmykCS_getRgbBuffer(colorBuf, bits) { - var scale = 1 / ((1 << bits) - 1); - var length = colorBuf.length / 4; - var rgbBuf = new Uint8Array(length * 3); - var rgbBufPos = 0; - var colorBufPos = 0; - - for (var i = 0; i < length; i++) { - var cmyk = []; - for (var j = 0; j < 4; ++j) - cmyk.push(scale * colorBuf[colorBufPos++]); - - var rgb = this.getRgb(cmyk); - for (var j = 0; j < 3; ++j) - rgbBuf[rgbBufPos++] = Math.round(rgb[j] * 255); - } - - return rgbBuf; - }, - isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - } - }; - - return DeviceCmykCS; -})(); - -// -// LabCS: Based on "PDF Reference, Sixth Ed", p.250 -// -var LabCS = (function LabCSClosure() { - function LabCS(whitePoint, blackPoint, range) { - this.name = 'Lab'; - this.numComps = 3; - this.defaultColor = [0, 0, 0]; - - if (!whitePoint) - error('WhitePoint missing - required for color space Lab'); - blackPoint = blackPoint || [0, 0, 0]; - range = range || [-100, 100, -100, 100]; - - // Translate args to spec variables - this.XW = whitePoint[0]; - this.YW = whitePoint[1]; - this.ZW = whitePoint[2]; - this.amin = range[0]; - this.amax = range[1]; - this.bmin = range[2]; - this.bmax = range[3]; - - // These are here just for completeness - the spec doesn't offer any - // formulas that use BlackPoint in Lab - this.XB = blackPoint[0]; - this.YB = blackPoint[1]; - this.ZB = blackPoint[2]; - - // Validate vars as per spec - if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) - error('Invalid WhitePoint components, no fallback available'); - - if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { - info('Invalid BlackPoint, falling back to default'); - this.XB = this.YB = this.ZB = 0; - } - - if (this.amin > this.amax || this.bmin > this.bmax) { - info('Invalid Range, falling back to defaults'); - this.amin = -100; - this.amax = 100; - this.bmin = -100; - this.bmax = 100; - } - }; - - // Function g(x) from spec - function g(x) { - if (x >= 6 / 29) - return x * x * x; - else - return (108 / 841) * (x - 4 / 29); - } - - LabCS.prototype = { - getRgb: function LabCS_getRgb(color) { - // Ls,as,bs <---> L*,a*,b* in the spec - var Ls = color[0], as = color[1], bs = color[2]; - - // Adjust limits of 'as' and 'bs' - as = as > this.amax ? this.amax : as; - as = as < this.amin ? this.amin : as; - bs = bs > this.bmax ? this.bmax : bs; - bs = bs < this.bmin ? this.bmin : bs; - - // Computes intermediate variables X,Y,Z as per spec - var M = (Ls + 16) / 116; - var L = M + (as / 500); - var N = M - (bs / 200); - var X = this.XW * g(L); - var Y = this.YW * g(M); - var Z = this.ZW * g(N); - - // XYZ to RGB 3x3 matrix, from: - // http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC18 - var XYZtoRGB = [3.240479, -1.537150, -0.498535, - -0.969256, 1.875992, 0.041556, - 0.055648, -0.204043, 1.057311]; - - return Util.apply3dTransform(XYZtoRGB, [X, Y, Z]); - }, - getRgbBuffer: function LabCS_getRgbBuffer(input, bits) { - if (bits == 8) - return input; - var scale = 255 / ((1 << bits) - 1); - var i, length = input.length / 3; - var rgbBuf = new Uint8Array(length); - - var j = 0; - for (i = 0; i < length; ++i) { - // Convert L*, a*, s* into RGB - var rgb = this.getRgb([input[i], input[i + 1], input[i + 2]]); - rgbBuf[j++] = rgb[0]; - rgbBuf[j++] = rgb[1]; - rgbBuf[j++] = rgb[2]; - } - - return rgbBuf; - }, - isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) { - // From Table 90 in Adobe's: - // "Document management - Portable document format", 1st ed, 2008 - if (decodeMap[0] === 0 && decodeMap[1] === 100 && - decodeMap[2] === this.amin && decodeMap[3] === this.amax && - decodeMap[4] === this.bmin && decodeMap[5] === this.bmax) - return true; - else - return false; - } - }; - return LabCS; -})(); - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var ARCFourCipher = (function ARCFourCipherClosure() { - function ARCFourCipher(key) { - this.a = 0; - this.b = 0; - var s = new Uint8Array(256); - var i, j = 0, tmp, keyLength = key.length; - for (i = 0; i < 256; ++i) - s[i] = i; - for (i = 0; i < 256; ++i) { - tmp = s[i]; - j = (j + tmp + key[i % keyLength]) & 0xFF; - s[i] = s[j]; - s[j] = tmp; - } - this.s = s; - } - - ARCFourCipher.prototype = { - encryptBlock: function ARCFourCipher_encryptBlock(data) { - var i, n = data.length, tmp, tmp2; - var a = this.a, b = this.b, s = this.s; - var output = new Uint8Array(n); - for (i = 0; i < n; ++i) { - a = (a + 1) & 0xFF; - tmp = s[a]; - b = (b + tmp) & 0xFF; - tmp2 = s[b]; - s[a] = tmp2; - s[b] = tmp; - output[i] = data[i] ^ s[(tmp + tmp2) & 0xFF]; - } - this.a = a; - this.b = b; - return output; - } - }; - ARCFourCipher.prototype.decryptBlock = ARCFourCipher.prototype.encryptBlock; - - return ARCFourCipher; -})(); - -var calculateMD5 = (function calculateMD5Closure() { - var r = new Uint8Array([ - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, - 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, - 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, - 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]); - - var k = new Int32Array([ - -680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, - -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, - 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, - 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, - 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, - 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, - -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, - -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, - -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, - -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, - -145523070, -1120210379, 718787259, -343485551]); - - function hash(data, offset, length) { - var h0 = 1732584193, h1 = -271733879, h2 = -1732584194, h3 = 271733878; - // pre-processing - var paddedLength = (length + 72) & ~63; // data + 9 extra bytes - var padded = new Uint8Array(paddedLength); - var i, j, n; - for (i = 0; i < length; ++i) - padded[i] = data[offset++]; - padded[i++] = 0x80; - n = paddedLength - 8; - while (i < n) - padded[i++] = 0; - padded[i++] = (length << 3) & 0xFF; - padded[i++] = (length >> 5) & 0xFF; - padded[i++] = (length >> 13) & 0xFF; - padded[i++] = (length >> 21) & 0xFF; - padded[i++] = (length >>> 29) & 0xFF; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - // chunking - // TODO ArrayBuffer ? - var w = new Int32Array(16); - for (i = 0; i < paddedLength;) { - for (j = 0; j < 16; ++j, i += 4) { - w[j] = (padded[i] | (padded[i + 1] << 8) | - (padded[i + 2] << 16) | (padded[i + 3] << 24)); - } - var a = h0, b = h1, c = h2, d = h3, f, g; - for (j = 0; j < 64; ++j) { - if (j < 16) { - f = (b & c) | ((~b) & d); - g = j; - } else if (j < 32) { - f = (d & b) | ((~d) & c); - g = (5 * j + 1) & 15; - } else if (j < 48) { - f = b ^ c ^ d; - g = (3 * j + 5) & 15; - } else { - f = c ^ (b | (~d)); - g = (7 * j) & 15; - } - var tmp = d, rotateArg = (a + f + k[j] + w[g]) | 0, rotate = r[j]; - d = c; - c = b; - b = (b + ((rotateArg << rotate) | (rotateArg >>> (32 - rotate)))) | 0; - a = tmp; - } - h0 = (h0 + a) | 0; - h1 = (h1 + b) | 0; - h2 = (h2 + c) | 0; - h3 = (h3 + d) | 0; - } - return new Uint8Array([ - h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >>> 24) & 0xFF, - h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >>> 24) & 0xFF, - h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >>> 24) & 0xFF, - h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >>> 24) & 0xFF - ]); - } - return hash; -})(); - -var NullCipher = (function NullCipherClosure() { - function NullCipher() { - } - - NullCipher.prototype = { - decryptBlock: function NullCipher_decryptBlock(data) { - return data; - } - }; - - return NullCipher; -})(); - -var AES128Cipher = (function AES128CipherClosure() { - var rcon = new Uint8Array([ - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, - 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, - 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, - 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, - 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, - 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, - 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, - 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, - 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, - 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, - 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, - 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, - 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, - 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, - 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, - 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, - 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, - 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, - 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, - 0x74, 0xe8, 0xcb, 0x8d]); - - var s = new Uint8Array([ - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, - 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, - 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, - 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, - 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, - 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, - 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, - 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, - 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, - 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, - 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, - 0xb0, 0x54, 0xbb, 0x16]); - - var inv_s = new Uint8Array([ - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, - 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, - 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, - 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, - 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, - 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, - 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, - 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, - 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, - 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, - 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, - 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, - 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, - 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0c, 0x7d]); - - var mix = new Uint32Array([ - 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, - 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, - 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, - 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, - 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, - 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, - 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, - 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, - 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, - 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, - 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, - 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, - 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, - 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, - 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, - 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, - 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, - 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, - 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, - 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, - 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, - 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, - 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, - 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, - 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, - 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, - 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, - 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, - 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, - 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, - 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, - 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, - 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, - 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, - 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, - 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, - 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, - 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, - 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, - 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, - 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, - 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, - 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]); - - function expandKey128(cipherKey) { - var b = 176, result = new Uint8Array(b); - result.set(cipherKey); - for (var j = 16, i = 1; j < b; ++i) { - // RotWord - var t1 = result[j - 3], t2 = result[j - 2], - t3 = result[j - 1], t4 = result[j - 4]; - // SubWord - t1 = s[t1]; t2 = s[t2]; t3 = s[t3]; t4 = s[t4]; - // Rcon - t1 = t1 ^ rcon[i]; - for (var n = 0; n < 4; ++n) { - result[j] = (t1 ^= result[j - 16]); j++; - result[j] = (t2 ^= result[j - 16]); j++; - result[j] = (t3 ^= result[j - 16]); j++; - result[j] = (t4 ^= result[j - 16]); j++; - } - } - return result; - } - - function decrypt128(input, key) { - var state = new Uint8Array(16); - state.set(input); - var i, j, k; - var t, u, v; - // AddRoundKey - for (j = 0, k = 160; j < 16; ++j, ++k) - state[j] ^= key[k]; - for (i = 9; i >= 1; --i) { - // InvShiftRows - t = state[13]; state[13] = state[9]; state[9] = state[5]; - state[5] = state[1]; state[1] = t; - t = state[14]; u = state[10]; state[14] = state[6]; - state[10] = state[2]; state[6] = t; state[2] = u; - t = state[15]; u = state[11]; v = state[7]; state[15] = state[3]; - state[11] = t; state[7] = u; state[3] = v; - // InvSubBytes - for (j = 0; j < 16; ++j) - state[j] = inv_s[state[j]]; - // AddRoundKey - for (j = 0, k = i * 16; j < 16; ++j, ++k) - state[j] ^= key[k]; - // InvMixColumns - for (j = 0; j < 16; j += 4) { - var s0 = mix[state[j]], s1 = mix[state[j + 1]], - s2 = mix[state[j + 2]], s3 = mix[state[j + 3]]; - t = (s0 ^ (s1 >>> 8) ^ (s1 << 24) ^ (s2 >>> 16) ^ (s2 << 16) ^ - (s3 >>> 24) ^ (s3 << 8)); - state[j] = (t >>> 24) & 0xFF; - state[j + 1] = (t >> 16) & 0xFF; - state[j + 2] = (t >> 8) & 0xFF; - state[j + 3] = t & 0xFF; - } - } - // InvShiftRows - t = state[13]; state[13] = state[9]; state[9] = state[5]; - state[5] = state[1]; state[1] = t; - t = state[14]; u = state[10]; state[14] = state[6]; - state[10] = state[2]; state[6] = t; state[2] = u; - t = state[15]; u = state[11]; v = state[7]; state[15] = state[3]; - state[11] = t; state[7] = u; state[3] = v; - for (j = 0; j < 16; ++j) { - // InvSubBytes - state[j] = inv_s[state[j]]; - // AddRoundKey - state[j] ^= key[j]; - } - return state; - } - - function AES128Cipher(key) { - this.key = expandKey128(key); - this.buffer = new Uint8Array(16); - this.bufferPosition = 0; - } - - function decryptBlock2(data) { - var i, j, ii, sourceLength = data.length, - buffer = this.buffer, bufferLength = this.bufferPosition, - result = [], iv = this.iv; - for (i = 0; i < sourceLength; ++i) { - buffer[bufferLength] = data[i]; - ++bufferLength; - if (bufferLength < 16) - continue; - // buffer is full, decrypting - var plain = decrypt128(buffer, this.key); - // xor-ing the IV vector to get plain text - for (j = 0; j < 16; ++j) - plain[j] ^= iv[j]; - iv = buffer; - result.push(plain); - buffer = new Uint8Array(16); - bufferLength = 0; - } - // saving incomplete buffer - this.buffer = buffer; - this.bufferLength = bufferLength; - this.iv = iv; - if (result.length == 0) - return new Uint8Array([]); - if (result.length == 1) - return result[0]; - // combining plain text blocks into one - var output = new Uint8Array(16 * result.length); - for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) - output.set(result[i], j); - return output; - } - - AES128Cipher.prototype = { - decryptBlock: function AES128Cipher_decryptBlock(data) { - var i, sourceLength = data.length; - var buffer = this.buffer, bufferLength = this.bufferPosition; - // waiting for IV values -- they are at the start of the stream - for (i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) - buffer[bufferLength] = data[i]; - if (bufferLength < 16) { - // need more data - this.bufferLength = bufferLength; - return new Uint8Array([]); - } - this.iv = buffer; - this.buffer = new Uint8Array(16); - this.bufferLength = 0; - // starting decryption - this.decryptBlock = decryptBlock2; - return this.decryptBlock(data.subarray(16)); - } - }; - - return AES128Cipher; -})(); - -var CipherTransform = (function CipherTransformClosure() { - function CipherTransform(stringCipherConstructor, streamCipherConstructor) { - this.stringCipherConstructor = stringCipherConstructor; - this.streamCipherConstructor = streamCipherConstructor; - } - CipherTransform.prototype = { - createStream: function CipherTransform_createStream(stream) { - var cipher = new this.streamCipherConstructor(); - return new DecryptStream(stream, - function cipherTransformDecryptStream(data) { - return cipher.decryptBlock(data); - } - ); - }, - decryptString: function CipherTransform_decryptString(s) { - var cipher = new this.stringCipherConstructor(); - var data = stringToBytes(s); - data = cipher.decryptBlock(data); - return bytesToString(data); - } - }; - return CipherTransform; -})(); - -var CipherTransformFactory = (function CipherTransformFactoryClosure() { - var defaultPasswordBytes = new Uint8Array([ - 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, - 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, - 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, - 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A]); - - function prepareKeyData(fileId, password, ownerPassword, userPassword, - flags, revision, keyLength, encryptMetadata) { - var hashData = new Uint8Array(100), i = 0, j, n; - if (password) { - n = Math.min(32, password.length); - for (; i < n; ++i) - hashData[i] = password[i]; - } - j = 0; - while (i < 32) { - hashData[i++] = defaultPasswordBytes[j++]; - } - // as now the padded password in the hashData[0..i] - for (j = 0, n = ownerPassword.length; j < n; ++j) - hashData[i++] = ownerPassword[j]; - hashData[i++] = flags & 0xFF; - hashData[i++] = (flags >> 8) & 0xFF; - hashData[i++] = (flags >> 16) & 0xFF; - hashData[i++] = (flags >>> 24) & 0xFF; - for (j = 0, n = fileId.length; j < n; ++j) - hashData[i++] = fileId[j]; - if (revision >= 4 && !encryptMetadata) { - hashData[i++] = 0xFF; - hashData[i++] = 0xFF; - hashData[i++] = 0xFF; - hashData[i++] = 0xFF; - } - var hash = calculateMD5(hashData, 0, i); - var keyLengthInBytes = keyLength >> 3; - if (revision >= 3) { - for (j = 0; j < 50; ++j) { - hash = calculateMD5(hash, 0, keyLengthInBytes); - } - } - var encryptionKey = hash.subarray(0, keyLengthInBytes); - var cipher, checkData; - - if (revision >= 3) { - for (i = 0; i < 32; ++i) - hashData[i] = defaultPasswordBytes[i]; - for (j = 0, n = fileId.length; j < n; ++j) - hashData[i++] = fileId[j]; - cipher = new ARCFourCipher(encryptionKey); - var checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i)); - n = encryptionKey.length; - var derivedKey = new Uint8Array(n), k; - for (j = 1; j <= 19; ++j) { - for (k = 0; k < n; ++k) - derivedKey[k] = encryptionKey[k] ^ j; - cipher = new ARCFourCipher(derivedKey); - checkData = cipher.encryptBlock(checkData); - } - for (j = 0, n = checkData.length; j < n; ++j) { - if (userPassword[j] != checkData[j]) - return null; - } - } else { - cipher = new ARCFourCipher(encryptionKey); - checkData = cipher.encryptBlock(defaultPasswordBytes); - for (j = 0, n = checkData.length; j < n; ++j) { - if (userPassword[j] != checkData[j]) - return null; - } - } - return encryptionKey; - } - function decodeUserPassword(password, ownerPassword, revision, keyLength) { - var hashData = new Uint8Array(32), i = 0, j, n; - n = Math.min(32, password.length); - for (; i < n; ++i) - hashData[i] = password[i]; - j = 0; - while (i < 32) { - hashData[i++] = defaultPasswordBytes[j++]; - } - var hash = calculateMD5(hashData, 0, i); - var keyLengthInBytes = keyLength >> 3; - if (revision >= 3) { - for (j = 0; j < 50; ++j) { - hash = calculateMD5(hash, 0, hash.length); - } - } - - var cipher, userPassword; - if (revision >= 3) { - userPassword = ownerPassword; - var derivedKey = new Uint8Array(keyLengthInBytes), k; - for (j = 19; j >= 0; j--) { - for (k = 0; k < keyLengthInBytes; ++k) - derivedKey[k] = hash[k] ^ j; - cipher = new ARCFourCipher(derivedKey); - userPassword = cipher.encryptBlock(userPassword); - } - } else { - cipher = new ARCFourCipher(hash.subarray(0, keyLengthInBytes)); - userPassword = cipher.encryptBlock(ownerPassword); - } - return userPassword; - } - - var identityName = new Name('Identity'); - - function CipherTransformFactory(dict, fileId, password) { - var filter = dict.get('Filter'); - if (!isName(filter) || filter.name != 'Standard') - error('unknown encryption method'); - this.dict = dict; - var algorithm = dict.get('V'); - if (!isInt(algorithm) || - (algorithm != 1 && algorithm != 2 && algorithm != 4)) - error('unsupported encryption algorithm'); - this.algorithm = algorithm; - var keyLength = dict.get('Length') || 40; - if (!isInt(keyLength) || - keyLength < 40 || (keyLength % 8) != 0) - error('invalid key length'); - // prepare keys - var ownerPassword = stringToBytes(dict.get('O')); - var userPassword = stringToBytes(dict.get('U')); - var flags = dict.get('P'); - var revision = dict.get('R'); - var encryptMetadata = algorithm == 4 && // meaningful when V is 4 - dict.get('EncryptMetadata') !== false; // makes true as default value - this.encryptMetadata = encryptMetadata; - - var fileIdBytes = stringToBytes(fileId); - var passwordBytes; - if (password) - passwordBytes = stringToBytes(password); - - var encryptionKey = prepareKeyData(fileIdBytes, passwordBytes, - ownerPassword, userPassword, flags, - revision, keyLength, encryptMetadata); - if (!encryptionKey && !password) { - throw new PasswordException('No password given', 'needpassword'); - } else if (!encryptionKey && password) { - // Attempting use the password as an owner password - var decodedPassword = decodeUserPassword(passwordBytes, ownerPassword, - revision, keyLength); - encryptionKey = prepareKeyData(fileIdBytes, decodedPassword, - ownerPassword, userPassword, flags, - revision, keyLength, encryptMetadata); - } - - if (!encryptionKey) - throw new PasswordException('Incorrect Password', 'incorrectpassword'); - - this.encryptionKey = encryptionKey; - - if (algorithm == 4) { - this.cf = dict.get('CF'); - this.stmf = dict.get('StmF') || identityName; - this.strf = dict.get('StrF') || identityName; - this.eff = dict.get('EFF') || this.strf; - } - } - - function buildObjectKey(num, gen, encryptionKey, isAes) { - var key = new Uint8Array(encryptionKey.length + 9), i, n; - for (i = 0, n = encryptionKey.length; i < n; ++i) - key[i] = encryptionKey[i]; - key[i++] = num & 0xFF; - key[i++] = (num >> 8) & 0xFF; - key[i++] = (num >> 16) & 0xFF; - key[i++] = gen & 0xFF; - key[i++] = (gen >> 8) & 0xFF; - if (isAes) { - key[i++] = 0x73; - key[i++] = 0x41; - key[i++] = 0x6C; - key[i++] = 0x54; - } - var hash = calculateMD5(key, 0, i); - return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); - } - - function buildCipherConstructor(cf, name, num, gen, key) { - var cryptFilter = cf.get(name.name); - var cfm; - if (cryptFilter != null) - cfm = cryptFilter.get('CFM'); - if (!cfm || cfm.name == 'None') { - return function cipherTransformFactoryBuildCipherConstructorNone() { - return new NullCipher(); - }; - } - if ('V2' == cfm.name) { - return function cipherTransformFactoryBuildCipherConstructorV2() { - return new ARCFourCipher( - buildObjectKey(num, gen, key, false)); - }; - } - if ('AESV2' == cfm.name) { - return function cipherTransformFactoryBuildCipherConstructorAESV2() { - return new AES128Cipher( - buildObjectKey(num, gen, key, true)); - }; - } - error('Unknown crypto method'); - } - - CipherTransformFactory.prototype = { - createCipherTransform: - function CipherTransformFactory_createCipherTransform(num, gen) { - if (this.algorithm == 4) { - return new CipherTransform( - buildCipherConstructor(this.cf, this.stmf, - num, gen, this.encryptionKey), - buildCipherConstructor(this.cf, this.strf, - num, gen, this.encryptionKey)); - } - // algorithms 1 and 2 - var key = buildObjectKey(num, gen, this.encryptionKey, false); - var cipherConstructor = function buildCipherCipherConstructor() { - return new ARCFourCipher(key); - }; - return new CipherTransform(cipherConstructor, cipherConstructor); - } - }; - - return CipherTransformFactory; -})(); - - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var PartialEvaluator = (function PartialEvaluatorClosure() { - function PartialEvaluator(xref, handler, uniquePrefix) { - this.state = new EvalState(); - this.stateStack = []; - - this.xref = xref; - this.handler = handler; - this.uniquePrefix = uniquePrefix; - this.objIdCounter = 0; - } - - var OP_MAP = { - // Graphics state - w: 'setLineWidth', - J: 'setLineCap', - j: 'setLineJoin', - M: 'setMiterLimit', - d: 'setDash', - ri: 'setRenderingIntent', - i: 'setFlatness', - gs: 'setGState', - q: 'save', - Q: 'restore', - cm: 'transform', - - // Path - m: 'moveTo', - l: 'lineTo', - c: 'curveTo', - v: 'curveTo2', - y: 'curveTo3', - h: 'closePath', - re: 'rectangle', - S: 'stroke', - s: 'closeStroke', - f: 'fill', - F: 'fill', - 'f*': 'eoFill', - B: 'fillStroke', - 'B*': 'eoFillStroke', - b: 'closeFillStroke', - 'b*': 'closeEOFillStroke', - n: 'endPath', - - // Clipping - W: 'clip', - 'W*': 'eoClip', - - // Text - BT: 'beginText', - ET: 'endText', - Tc: 'setCharSpacing', - Tw: 'setWordSpacing', - Tz: 'setHScale', - TL: 'setLeading', - Tf: 'setFont', - Tr: 'setTextRenderingMode', - Ts: 'setTextRise', - Td: 'moveText', - TD: 'setLeadingMoveText', - Tm: 'setTextMatrix', - 'T*': 'nextLine', - Tj: 'showText', - TJ: 'showSpacedText', - "'": 'nextLineShowText', - '"': 'nextLineSetSpacingShowText', - - // Type3 fonts - d0: 'setCharWidth', - d1: 'setCharWidthAndBounds', - - // Color - CS: 'setStrokeColorSpace', - cs: 'setFillColorSpace', - SC: 'setStrokeColor', - SCN: 'setStrokeColorN', - sc: 'setFillColor', - scn: 'setFillColorN', - G: 'setStrokeGray', - g: 'setFillGray', - RG: 'setStrokeRGBColor', - rg: 'setFillRGBColor', - K: 'setStrokeCMYKColor', - k: 'setFillCMYKColor', - - // Shading - sh: 'shadingFill', - - // Images - BI: 'beginInlineImage', - ID: 'beginImageData', - EI: 'endInlineImage', - - // XObjects - Do: 'paintXObject', - - // Marked content - MP: 'markPoint', - DP: 'markPointProps', - BMC: 'beginMarkedContent', - BDC: 'beginMarkedContentProps', - EMC: 'endMarkedContent', - - // Compatibility - BX: 'beginCompat', - EX: 'endCompat', - - // (reserved partial commands for the lexer) - BM: null, - BD: null, - 'true': null, - fa: null, - fal: null, - fals: null, - 'false': null, - nu: null, - nul: null, - 'null': null - }; - - PartialEvaluator.prototype = { - getOperatorList: function PartialEvaluator_getOperatorList(stream, - resources, - dependency, - queue) { - - var self = this; - var xref = this.xref; - var handler = this.handler; - var uniquePrefix = this.uniquePrefix || ''; - - function insertDependency(depList) { - fnArray.push('dependency'); - argsArray.push(depList); - for (var i = 0, ii = depList.length; i < ii; i++) { - var dep = depList[i]; - if (dependency.indexOf(dep) == -1) { - dependency.push(depList[i]); - } - } - } - - function handleSetFont(fontName, font) { - var loadedName = null; - - var fontRes = resources.get('Font'); - - assert(fontRes, 'fontRes not available'); - - font = xref.fetchIfRef(font) || fontRes.get(fontName); - assertWellFormed(isDict(font)); - - ++self.objIdCounter; - if (!font.loadedName) { - font.translated = self.translateFont(font, xref, resources, - dependency); - if (font.translated) { - // keep track of each font we translated so the caller can - // load them asynchronously before calling display on a page - loadedName = 'font_' + uniquePrefix + self.objIdCounter; - font.translated.properties.loadedName = loadedName; - font.loadedName = loadedName; - - var translated = font.translated; - // Convert the file to an ArrayBuffer which will be turned back into - // a Stream in the main thread. - if (translated.file) - translated.file = translated.file.getBytes(); - if (translated.properties.file) { - translated.properties.file = - translated.properties.file.getBytes(); - } - - handler.send('obj', [ - loadedName, - 'Font', - translated.name, - translated.file, - translated.properties - ]); - } - } - loadedName = loadedName || font.loadedName; - - // Ensure the font is ready before the font is set - // and later on used for drawing. - // OPTIMIZE: This should get insert to the operatorList only once per - // page. - insertDependency([loadedName]); - return loadedName; - } - - function buildPaintImageXObject(image, inline) { - var dict = image.dict; - var w = dict.get('Width', 'W'); - var h = dict.get('Height', 'H'); - - var imageMask = dict.get('ImageMask', 'IM') || false; - if (imageMask) { - // This depends on a tmpCanvas beeing filled with the - // current fillStyle, such that processing the pixel - // data can't be done here. Instead of creating a - // complete PDFImage, only read the information needed - // for later. - - var width = dict.get('Width', 'W'); - var height = dict.get('Height', 'H'); - var bitStrideLength = (width + 7) >> 3; - var imgArray = image.getBytes(bitStrideLength * height); - var decode = dict.get('Decode', 'D'); - var inverseDecode = !!decode && decode[0] > 0; - - fn = 'paintImageMaskXObject'; - args = [imgArray, inverseDecode, width, height]; - return; - } - - // If there is no imageMask, create the PDFImage and a lot - // of image processing can be done here. - var objId = 'img_' + uniquePrefix + (++self.objIdCounter); - insertDependency([objId]); - args = [objId, w, h]; - - var softMask = dict.get('SMask', 'IM') || false; - if (!softMask && image instanceof JpegStream && - image.isNativelySupported(xref, resources)) { - // These JPEGs don't need any more processing so we can just send it. - fn = 'paintJpegXObject'; - handler.send('obj', [objId, 'JpegStream', image.getIR()]); - return; - } - - fn = 'paintImageXObject'; - - PDFImage.buildImage(function(imageObj) { - var drawWidth = imageObj.drawWidth; - var drawHeight = imageObj.drawHeight; - var imgData = { - width: drawWidth, - height: drawHeight, - data: new Uint8Array(drawWidth * drawHeight * 4) - }; - var pixels = imgData.data; - imageObj.fillRgbaBuffer(pixels, drawWidth, drawHeight); - handler.send('obj', [objId, 'Image', imgData]); - }, handler, xref, resources, image, inline); - } - - if (!queue) - queue = {}; - - if (!queue.argsArray) { - queue.argsArray = []; - } - if (!queue.fnArray) { - queue.fnArray = []; - } - - var fnArray = queue.fnArray, argsArray = queue.argsArray; - var dependencyArray = dependency || []; - - resources = resources || new Dict(); - var xobjs = resources.get('XObject') || new Dict(); - var patterns = resources.get('Pattern') || new Dict(); - var parser = new Parser(new Lexer(stream, OP_MAP), false, xref); - var res = resources; - var args = [], obj; - var TILING_PATTERN = 1, SHADING_PATTERN = 2; - - while (true) { - obj = parser.getObj(); - if (isEOF(obj)) - break; - - if (isCmd(obj)) { - var cmd = obj.cmd; - var fn = OP_MAP[cmd]; - assertWellFormed(fn, 'Unknown command "' + cmd + '"'); - // TODO figure out how to type-check vararg functions - - if ((cmd == 'SCN' || cmd == 'scn') && !args[args.length - 1].code) { - // compile tiling patterns - var patternName = args[args.length - 1]; - // SCN/scn applies patterns along with normal colors - if (isName(patternName)) { - var pattern = patterns.get(patternName.name); - if (pattern) { - var dict = isStream(pattern) ? pattern.dict : pattern; - var typeNum = dict.get('PatternType'); - - if (typeNum == TILING_PATTERN) { - // Create an IR of the pattern code. - var depIdx = dependencyArray.length; - var operatorList = this.getOperatorList(pattern, - dict.get('Resources') || resources, dependencyArray); - - // Add the dependencies that are required to execute the - // operatorList. - insertDependency(dependencyArray.slice(depIdx)); - - args = TilingPattern.getIR(operatorList, dict, args); - } - else if (typeNum == SHADING_PATTERN) { - var shading = dict.get('Shading'); - var matrix = dict.get('Matrix'); - var pattern = Pattern.parseShading(shading, matrix, xref, - res); - args = pattern.getIR(); - } else { - error('Unkown PatternType ' + typeNum); - } - } - } - } else if (cmd == 'Do' && !args[0].code) { - // eagerly compile XForm objects - var name = args[0].name; - var xobj = xobjs.get(name); - if (xobj) { - assertWellFormed(isStream(xobj), 'XObject should be a stream'); - - var type = xobj.dict.get('Subtype'); - assertWellFormed( - isName(type), - 'XObject should have a Name subtype' - ); - - if ('Form' == type.name) { - var matrix = xobj.dict.get('Matrix'); - var bbox = xobj.dict.get('BBox'); - - fnArray.push('paintFormXObjectBegin'); - argsArray.push([matrix, bbox]); - - // This adds the operatorList of the xObj to the current queue. - var depIdx = dependencyArray.length; - - // Pass in the current `queue` object. That means the `fnArray` - // and the `argsArray` in this scope is reused and new commands - // are added to them. - this.getOperatorList(xobj, - xobj.dict.get('Resources') || resources, - dependencyArray, queue); - - // Add the dependencies that are required to execute the - // operatorList. - insertDependency(dependencyArray.slice(depIdx)); - - fn = 'paintFormXObjectEnd'; - args = []; - } else if ('Image' == type.name) { - buildPaintImageXObject(xobj, false); - } else { - error('Unhandled XObject subtype ' + type.name); - } - } - } else if (cmd == 'Tf') { // eagerly collect all fonts - args[0] = handleSetFont(args[0].name); - } else if (cmd == 'EI') { - buildPaintImageXObject(args[0], true); - } - - switch (fn) { - // Parse the ColorSpace data to a raw format. - case 'setFillColorSpace': - case 'setStrokeColorSpace': - args = [ColorSpace.parseToIR(args[0], xref, resources)]; - break; - case 'shadingFill': - var shadingRes = res.get('Shading'); - if (!shadingRes) - error('No shading resource found'); - - var shading = shadingRes.get(args[0].name); - if (!shading) - error('No shading object found'); - - var shadingFill = Pattern.parseShading(shading, null, xref, res); - var patternIR = shadingFill.getIR(); - args = [patternIR]; - fn = 'shadingFill'; - break; - case 'setGState': - var dictName = args[0]; - var extGState = resources.get('ExtGState'); - - if (!isDict(extGState) || !extGState.has(dictName.name)) - break; - - var gsState = extGState.get(dictName.name); - - // This array holds the converted/processed state data. - var gsStateObj = []; - - gsState.forEach( - function canvasGraphicsSetGStateForEach(key, value) { - switch (key) { - case 'Type': - break; - case 'LW': - case 'LC': - case 'LJ': - case 'ML': - case 'D': - case 'RI': - case 'FL': - case 'CA': - case 'ca': - gsStateObj.push([key, value]); - break; - case 'Font': - gsStateObj.push([ - 'Font', - handleSetFont(null, value[0]), - value[1] - ]); - break; - case 'BM': - // We support the default so don't trigger the TODO. - if (!isName(value) || value.name != 'Normal') - TODO('graphic state operator ' + key); - break; - case 'SMask': - // We support the default so don't trigger the TODO. - if (!isName(value) || value.name != 'None') - TODO('graphic state operator ' + key); - break; - // Only generate info log messages for the following since - // they are unlikey to have a big impact on the rendering. - case 'OP': - case 'op': - case 'OPM': - case 'BG': - case 'BG2': - case 'UCR': - case 'UCR2': - case 'TR': - case 'TR2': - case 'HT': - case 'SM': - case 'SA': - case 'AIS': - case 'TK': - // TODO implement these operators. - info('graphic state operator ' + key); - break; - default: - info('Unknown graphic state operator ' + key); - break; - } - } - ); - args = [gsStateObj]; - break; - } // switch - - fnArray.push(fn); - argsArray.push(args); - args = []; - } else if (obj != null) { - assertWellFormed(args.length <= 33, 'Too many arguments'); - args.push(obj instanceof Dict ? obj.getAll() : obj); - } - } - - return queue; - }, - - getTextContent: function partialEvaluatorGetIRQueue(stream, resources) { - - var self = this; - var xref = this.xref; - - function handleSetFont(fontName, fontRef) { - var fontRes = resources.get('Font'); - - // TODO: TOASK: Is it possible to get here? If so, what does - // args[0].name should be like??? - assert(fontRes, 'fontRes not available'); - - fontRes = xref.fetchIfRef(fontRes); - fontRef = fontRef || fontRes.get(fontName); - var font = xref.fetchIfRef(fontRef), tra; - assertWellFormed(isDict(font)); - if (!font.translated) { - font.translated = self.translateFont(font, xref, resources); - } - return font; - } - - resources = xref.fetchIfRef(resources) || new Dict(); - - var parser = new Parser(new Lexer(stream), false); - var res = resources; - var args = [], obj; - - var text = ''; - var chunk = ''; - var font = null; - while (!isEOF(obj = parser.getObj())) { - if (isCmd(obj)) { - var cmd = obj.cmd; - switch (cmd) { - case 'Tf': - font = handleSetFont(args[0].name); - break; - case 'TJ': - var items = args[0]; - for (var j = 0, jj = items.length; j < jj; j++) { - if (typeof items[j] === 'string') { - chunk += items[j]; - } else if (items[j] < 0) { - // making all negative offsets a space - better to have - // a space in incorrect place than not have them at all - chunk += ' '; - } - } - break; - case 'Tj': - chunk += args[0]; - break; - case "'": - chunk += args[0] + ' '; - break; - case '"': - chunk += args[2] + ' '; - break; - } // switch - if (chunk !== '') { - text += fontCharsToUnicode(chunk, font.translated.properties); - chunk = ''; - } - - args = []; - } else if (obj != null) { - assertWellFormed(args.length <= 33, 'Too many arguments'); - args.push(obj); - } - } - - return text; - }, - - extractDataStructures: function - partialEvaluatorExtractDataStructures(dict, baseDict, - xref, properties) { - // 9.10.2 - var toUnicode = dict.get('ToUnicode') || - baseDict.get('ToUnicode'); - if (toUnicode) - properties.toUnicode = this.readToUnicode(toUnicode, xref, properties); - - if (properties.composite) { - // CIDSystemInfo helps to match CID to glyphs - var cidSystemInfo = dict.get('CIDSystemInfo'); - if (isDict(cidSystemInfo)) { - properties.cidSystemInfo = { - registry: cidSystemInfo.get('Registry'), - ordering: cidSystemInfo.get('Ordering'), - supplement: cidSystemInfo.get('Supplement') - }; - } - - var cidToGidMap = dict.get('CIDToGIDMap'); - if (isStream(cidToGidMap)) - properties.cidToGidMap = this.readCidToGidMap(cidToGidMap); - } - - var flags = properties.flags; - var differences = []; - var baseEncoding = !!(flags & FontFlags.Symbolic) ? - Encodings.symbolsEncoding : Encodings.StandardEncoding; - var hasEncoding = dict.has('Encoding'); - if (hasEncoding) { - var encoding = dict.get('Encoding'); - if (isDict(encoding)) { - var baseName = encoding.get('BaseEncoding'); - if (baseName) - baseEncoding = Encodings[baseName.name]; - else - hasEncoding = false; // base encoding was not provided - - // Load the differences between the base and original - if (encoding.has('Differences')) { - var diffEncoding = encoding.get('Differences'); - var index = 0; - for (var j = 0, jj = diffEncoding.length; j < jj; j++) { - var data = diffEncoding[j]; - if (isNum(data)) - index = data; - else - differences[index++] = data.name; - } - } - } else if (isName(encoding)) { - baseEncoding = Encodings[encoding.name]; - } else { - error('Encoding is not a Name nor a Dict'); - } - } - - properties.differences = differences; - properties.baseEncoding = baseEncoding; - properties.hasEncoding = hasEncoding; - }, - - readToUnicode: function PartialEvaluator_readToUnicode(toUnicode, xref, - properties) { - var cmapObj = toUnicode; - var charToUnicode = []; - if (isName(cmapObj)) { - var isIdentityMap = cmapObj.name.substr(0, 9) == 'Identity-'; - if (!isIdentityMap) - error('ToUnicode file cmap translation not implemented'); - } else if (isStream(cmapObj)) { - var tokens = []; - var token = ''; - var beginArrayToken = {}; - - var cmap = cmapObj.getBytes(cmapObj.length); - for (var i = 0, ii = cmap.length; i < ii; i++) { - var octet = cmap[i]; - if (octet == 0x20 || octet == 0x0D || octet == 0x0A || - octet == 0x3C || octet == 0x5B || octet == 0x5D) { - switch (token) { - case 'usecmap': - error('usecmap is not implemented'); - break; - - case 'beginbfchar': - case 'beginbfrange': - case 'begincidchar': - case 'begincidrange': - token = ''; - tokens = []; - break; - - case 'endcidrange': - case 'endbfrange': - for (var j = 0, jj = tokens.length; j < jj; j += 3) { - var startRange = tokens[j]; - var endRange = tokens[j + 1]; - var code = tokens[j + 2]; - if (code == 0xFFFF) { - // CMap is broken, assuming code == startRange - code = startRange; - } - if (isArray(code)) { - var codeindex = 0; - while (startRange <= endRange) { - charToUnicode[startRange] = code[codeindex++]; - ++startRange; - } - } else { - while (startRange <= endRange) { - charToUnicode[startRange] = code++; - ++startRange; - } - } - } - break; - - case 'endcidchar': - case 'endbfchar': - for (var j = 0, jj = tokens.length; j < jj; j += 2) { - var index = tokens[j]; - var code = tokens[j + 1]; - charToUnicode[index] = code; - } - break; - - case '': - break; - - default: - if (token[0] >= '0' && token[0] <= '9') - token = parseInt(token, 10); // a number - tokens.push(token); - token = ''; - } - switch (octet) { - case 0x5B: - // begin list parsing - tokens.push(beginArrayToken); - break; - case 0x5D: - // collect array items - var items = [], item; - while (tokens.length && - (item = tokens.pop()) != beginArrayToken) - items.unshift(item); - tokens.push(items); - break; - } - } else if (octet == 0x3E) { - if (token.length) { - // Heuristic: guessing chars size by checking numbers sizes - // in the CMap entries. - if (token.length == 2 && properties.composite) - properties.wideChars = false; - - if (token.length <= 4) { - // parsing hex number - tokens.push(parseInt(token, 16)); - token = ''; - } else { - // parsing hex UTF-16BE numbers - var str = []; - for (var k = 0, kk = token.length; k < kk; k += 4) { - var b = parseInt(token.substr(k, 4), 16); - if (b <= 0x10) { - k += 4; - b = (b << 16) | parseInt(token.substr(k, 4), 16); - b -= 0x10000; - str.push(0xD800 | (b >> 10)); - str.push(0xDC00 | (b & 0x3FF)); - break; - } - str.push(b); - } - tokens.push(String.fromCharCode.apply(String, str)); - token = ''; - } - } - } else { - token += String.fromCharCode(octet); - } - } - } - return charToUnicode; - }, - readCidToGidMap: function PartialEvaluator_readCidToGidMap(cidToGidStream) { - // Extract the encoding from the CIDToGIDMap - var glyphsData = cidToGidStream.getBytes(); - - // Set encoding 0 to later verify the font has an encoding - var result = []; - for (var j = 0, jj = glyphsData.length; j < jj; j++) { - var glyphID = (glyphsData[j++] << 8) | glyphsData[j]; - if (glyphID == 0) - continue; - - var code = j >> 1; - result[code] = glyphID; - } - return result; - }, - - extractWidths: function PartialEvaluator_extractWidths(dict, - xref, - descriptor, - properties) { - var glyphsWidths = []; - var defaultWidth = 0; - if (properties.composite) { - defaultWidth = dict.get('DW') || 1000; - - var widths = dict.get('W'); - if (widths) { - var start = 0, end = 0; - for (var i = 0, ii = widths.length; i < ii; i++) { - var code = widths[i]; - if (isArray(code)) { - for (var j = 0, jj = code.length; j < jj; j++) - glyphsWidths[start++] = code[j]; - start = 0; - } else if (start) { - var width = widths[++i]; - for (var j = start; j <= code; j++) - glyphsWidths[j] = width; - start = 0; - } else { - start = code; - } - } - } - } else { - var firstChar = properties.firstChar; - var widths = dict.get('Widths'); - if (widths) { - var j = firstChar; - for (var i = 0, ii = widths.length; i < ii; i++) - glyphsWidths[j++] = widths[i]; - defaultWidth = parseFloat(descriptor.get('MissingWidth')) || 0; - } else { - // Trying get the BaseFont metrics (see comment above). - var baseFontName = dict.get('BaseFont'); - if (isName(baseFontName)) { - var metrics = this.getBaseFontMetrics(baseFontName.name); - - glyphsWidths = metrics.widths; - defaultWidth = metrics.defaultWidth; - } - } - } - - properties.defaultWidth = defaultWidth; - properties.widths = glyphsWidths; - }, - - getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) { - var defaultWidth = 0, widths = []; - var glyphWidths = Metrics[stdFontMap[name] || name]; - if (isNum(glyphWidths)) { - defaultWidth = glyphWidths; - } else { - widths = glyphWidths; - } - - return { - defaultWidth: defaultWidth, - widths: widths - }; - }, - - translateFont: function PartialEvaluator_translateFont(dict, - xref, - resources, - dependency) { - var baseDict = dict; - var type = dict.get('Subtype'); - assertWellFormed(isName(type), 'invalid font Subtype'); - - var composite = false; - if (type.name == 'Type0') { - // If font is a composite - // - get the descendant font - // - set the type according to the descendant font - // - get the FontDescriptor from the descendant font - var df = dict.get('DescendantFonts'); - if (!df) - return null; - - dict = isArray(df) ? xref.fetchIfRef(df[0]) : df; - - type = dict.get('Subtype'); - assertWellFormed(isName(type), 'invalid font Subtype'); - composite = true; - } - var maxCharIndex = composite ? 0xFFFF : 0xFF; - - var descriptor = dict.get('FontDescriptor'); - if (!descriptor) { - if (type.name == 'Type3') { - // FontDescriptor is only required for Type3 fonts when the document - // is a tagged pdf. Create a barbebones one to get by. - descriptor = new Dict(); - descriptor.set('FontName', new Name(type.name)); - } else { - // Before PDF 1.5 if the font was one of the base 14 fonts, having a - // FontDescriptor was not required. - // This case is here for compatibility. - var baseFontName = dict.get('BaseFont'); - if (!isName(baseFontName)) - return null; - - // Using base font name as a font name. - baseFontName = baseFontName.name.replace(/[,_]/g, '-'); - var metrics = this.getBaseFontMetrics(baseFontName); - - // Simulating descriptor flags attribute - var fontNameWoStyle = baseFontName.split('-')[0]; - var flags = (serifFonts[fontNameWoStyle] || - (fontNameWoStyle.search(/serif/gi) != -1) ? FontFlags.Serif : 0) | - (symbolsFonts[fontNameWoStyle] ? FontFlags.Symbolic : - FontFlags.Nonsymbolic); - - var properties = { - type: type.name, - widths: metrics.widths, - defaultWidth: metrics.defaultWidth, - flags: flags, - firstChar: 0, - lastChar: maxCharIndex - }; - this.extractDataStructures(dict, dict, xref, properties); - - return { - name: baseFontName, - dict: baseDict, - properties: properties - }; - } - } - - // According to the spec if 'FontDescriptor' is declared, 'FirstChar', - // 'LastChar' and 'Widths' should exist too, but some PDF encoders seem - // to ignore this rule when a variant of a standart font is used. - // TODO Fill the width array depending on which of the base font this is - // a variant. - var firstChar = dict.get('FirstChar') || 0; - var lastChar = dict.get('LastChar') || maxCharIndex; - var fontName = descriptor.get('FontName'); - // Some bad pdf's have a string as the font name. - if (isString(fontName)) - fontName = new Name(fontName); - assertWellFormed(isName(fontName), 'invalid font name'); - - var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3'); - if (fontFile) { - if (fontFile.dict) { - var subtype = fontFile.dict.get('Subtype'); - if (subtype) - subtype = subtype.name; - - var length1 = fontFile.dict.get('Length1'); - - var length2 = fontFile.dict.get('Length2'); - } - } - - var properties = { - type: type.name, - subtype: subtype, - file: fontFile, - length1: length1, - length2: length2, - composite: composite, - wideChars: composite, - fixedPitch: false, - fontMatrix: dict.get('FontMatrix') || IDENTITY_MATRIX, - firstChar: firstChar || 0, - lastChar: lastChar || maxCharIndex, - bbox: descriptor.get('FontBBox'), - ascent: descriptor.get('Ascent'), - descent: descriptor.get('Descent'), - xHeight: descriptor.get('XHeight'), - capHeight: descriptor.get('CapHeight'), - flags: descriptor.get('Flags'), - italicAngle: descriptor.get('ItalicAngle'), - coded: false - }; - this.extractWidths(dict, xref, descriptor, properties); - this.extractDataStructures(dict, baseDict, xref, properties); - - if (type.name === 'Type3') { - properties.coded = true; - var charProcs = dict.get('CharProcs').getAll(); - var fontResources = dict.get('Resources') || resources; - properties.charProcOperatorList = {}; - for (var key in charProcs) { - var glyphStream = charProcs[key]; - properties.charProcOperatorList[key] = - this.getOperatorList(glyphStream, fontResources, dependency); - } - } - - return { - name: fontName.name, - dict: baseDict, - file: fontFile, - properties: properties - }; - } - }; - - return PartialEvaluator; -})(); - -var EvalState = (function EvalStateClosure() { - function EvalState() { - // Are soft masks and alpha values shapes or opacities? - this.alphaIsShape = false; - this.fontSize = 0; - this.textMatrix = IDENTITY_MATRIX; - this.leading = 0; - // Start of text line (in text coordinates) - this.lineX = 0; - this.lineY = 0; - // Character and word spacing - this.charSpacing = 0; - this.wordSpacing = 0; - this.textHScale = 1; - // Color spaces - this.fillColorSpace = null; - this.strokeColorSpace = null; - } - EvalState.prototype = { - }; - return EvalState; -})(); - - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -/** - * Maximum time to wait for a font to be loaded by font-face rules. - */ -var kMaxWaitForFontFace = 1000; - -// Unicode Private Use Area -var kCmapGlyphOffset = 0xE000; -var kSizeOfGlyphArea = 0x1900; -var kSymbolicFontGlyphOffset = 0xF000; - -// PDF Glyph Space Units are one Thousandth of a TextSpace Unit -// except for Type 3 fonts -var kPDFGlyphSpaceUnits = 1000; - -// Until hinting is fully supported this constant can be used -var kHintingEnabled = false; - -var FontFlags = { - FixedPitch: 1, - Serif: 2, - Symbolic: 4, - Script: 8, - Nonsymbolic: 32, - Italic: 64, - AllCap: 65536, - SmallCap: 131072, - ForceBold: 262144 -}; - -var Encodings = { - ExpertEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclamsmall', 'Hungarumlautsmall', '', 'dollaroldstyle', - 'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', - 'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma', - 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', - 'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', - 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'colon', - 'semicolon', 'commasuperior', 'threequartersemdash', 'periodsuperior', - 'questionsmall', '', 'asuperior', 'bsuperior', 'centsuperior', 'dsuperior', - 'esuperior', '', '', 'isuperior', '', '', 'lsuperior', 'msuperior', - 'nsuperior', 'osuperior', '', '', 'rsuperior', 'ssuperior', 'tsuperior', - '', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', '', - 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', - 'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', - 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', - 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', - 'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', - 'onefitted', 'rupiah', 'Tildesmall', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', 'exclamdownsmall', 'centoldstyle', 'Lslashsmall', - '', '', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', 'Brevesmall', - 'Caronsmall', '', 'Dotaccentsmall', '', '', 'Macronsmall', '', '', - 'figuredash', 'hypheninferior', '', '', 'Ogoneksmall', 'Ringsmall', - 'Cedillasmall', '', '', '', 'onequarter', 'onehalf', 'threequarters', - 'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', '', '', 'zerosuperior', - 'onesuperior', 'twosuperior', 'threesuperior', 'foursuperior', - 'fivesuperior', 'sixsuperior', 'sevensuperior', 'eightsuperior', - 'ninesuperior', 'zeroinferior', 'oneinferior', 'twoinferior', - 'threeinferior', 'fourinferior', 'fiveinferior', 'sixinferior', - 'seveninferior', 'eightinferior', 'nineinferior', 'centinferior', - 'dollarinferior', 'periodinferior', 'commainferior', 'Agravesmall', - 'Aacutesmall', 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', - 'Aringsmall', 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall', - 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall', - 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', - 'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall', - 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall', - 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', - 'Ydieresissmall'], - MacExpertEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclamsmall', 'Hungarumlautsmall', 'centoldstyle', - 'dollaroldstyle', 'dollarsuperior', 'ampersandsmall', 'Acutesmall', - 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', - 'onedotenleader', 'comma', 'hyphen', 'period', 'fraction', 'zerooldstyle', - 'oneoldstyle', 'twooldstyle', 'threeoldstyle', 'fouroldstyle', - 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', - 'nineoldstyle', 'colon', 'semicolon', '', 'threequartersemdash', '', - 'questionsmall', '', '', '', '', 'Ethsmall', '', '', 'onequarter', - 'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', '', '', '', '', '', '', 'ff', - 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', '', 'parenrightinferior', - 'Circumflexsmall', 'hypheninferior', 'Gravesmall', 'Asmall', 'Bsmall', - 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', 'Hsmall', 'Ismall', - 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', 'Osmall', 'Psmall', - 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall', - 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah', - 'Tildesmall', '', '', 'asuperior', 'centsuperior', '', '', '', '', - 'Aacutesmall', 'Agravesmall', 'Acircumflexsmall', 'Adieresissmall', - 'Atildesmall', 'Aringsmall', 'Ccedillasmall', 'Eacutesmall', 'Egravesmall', - 'Ecircumflexsmall', 'Edieresissmall', 'Iacutesmall', 'Igravesmall', - 'Icircumflexsmall', 'Idieresissmall', 'Ntildesmall', 'Oacutesmall', - 'Ogravesmall', 'Ocircumflexsmall', 'Odieresissmall', 'Otildesmall', - 'Uacutesmall', 'Ugravesmall', 'Ucircumflexsmall', 'Udieresissmall', '', - 'eightsuperior', 'fourinferior', 'threeinferior', 'sixinferior', - 'eightinferior', 'seveninferior', 'Scaronsmall', '', 'centinferior', - 'twoinferior', '', 'Dieresissmall', '', 'Caronsmall', 'osuperior', - 'fiveinferior', '', 'commainferior', 'periodinferior', 'Yacutesmall', '', - 'dollarinferior', '', 'Thornsmall', '', 'nineinferior', 'zeroinferior', - 'Zcaronsmall', 'AEsmall', 'Oslashsmall', 'questiondownsmall', - 'oneinferior', 'Lslashsmall', '', '', '', '', '', '', 'Cedillasmall', '', - '', '', '', '', 'OEsmall', 'figuredash', 'hyphensuperior', '', '', '', '', - 'exclamdownsmall', '', 'Ydieresissmall', '', 'onesuperior', 'twosuperior', - 'threesuperior', 'foursuperior', 'fivesuperior', 'sixsuperior', - 'sevensuperior', 'ninesuperior', 'zerosuperior', '', 'esuperior', - 'rsuperior', 'tsuperior', '', '', 'isuperior', 'ssuperior', 'dsuperior', - '', '', '', '', '', 'lsuperior', 'Ogoneksmall', 'Brevesmall', - 'Macronsmall', 'bsuperior', 'nsuperior', 'msuperior', 'commasuperior', - 'periodsuperior', 'Dotaccentsmall', 'Ringsmall'], - MacRomanEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', - 'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus', - 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', - 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', - 'less', 'equal', 'greater', 'question', 'at', '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', 'bracketleft', 'backslash', 'bracketright', - 'asciicircum', 'underscore', 'grave', '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', 'braceleft', 'bar', 'braceright', 'asciitilde', '', - 'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', 'Odieresis', - 'Udieresis', 'aacute', 'agrave', 'acircumflex', 'adieresis', 'atilde', - 'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis', - 'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute', - 'ograve', 'ocircumflex', 'odieresis', 'otilde', 'uacute', 'ugrave', - 'ucircumflex', 'udieresis', 'dagger', 'degree', 'cent', 'sterling', - 'section', 'bullet', 'paragraph', 'germandbls', 'registered', 'copyright', - 'trademark', 'acute', 'dieresis', 'notequal', 'AE', 'Oslash', 'infinity', - 'plusminus', 'lessequal', 'greaterequal', 'yen', 'mu', 'partialdiff', - 'summation', 'product', 'pi', 'integral', 'ordfeminine', 'ordmasculine', - 'Omega', 'ae', 'oslash', 'questiondown', 'exclamdown', 'logicalnot', - 'radical', 'florin', 'approxequal', 'Delta', 'guillemotleft', - 'guillemotright', 'ellipsis', '', 'Agrave', 'Atilde', 'Otilde', 'OE', - 'oe', 'endash', 'emdash', 'quotedblleft', 'quotedblright', 'quoteleft', - 'quoteright', 'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction', - 'currency', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl', - 'periodcentered', 'quotesinglbase', 'quotedblbase', 'perthousand', - 'Acircumflex', 'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute', - 'Icircumflex', 'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple', - 'Ograve', 'Uacute', 'Ucircumflex', 'Ugrave', 'dotlessi', 'circumflex', - 'tilde', 'macron', 'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut', - 'ogonek', 'caron'], - StandardEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', - 'ampersand', 'quoteright', 'parenleft', 'parenright', 'asterisk', 'plus', - 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', - 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', - 'less', 'equal', 'greater', 'question', 'at', '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', 'bracketleft', 'backslash', 'bracketright', - 'asciicircum', 'underscore', 'quoteleft', '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', 'braceleft', 'bar', 'braceright', 'asciitilde', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'exclamdown', - 'cent', 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', - 'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft', - 'guilsinglright', 'fi', 'fl', '', 'endash', 'dagger', 'daggerdbl', - 'periodcentered', '', 'paragraph', 'bullet', 'quotesinglbase', - 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', - 'perthousand', '', 'questiondown', '', 'grave', 'acute', 'circumflex', - 'tilde', 'macron', 'breve', 'dotaccent', 'dieresis', '', 'ring', 'cedilla', - '', 'hungarumlaut', 'ogonek', 'caron', 'emdash', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', 'AE', '', 'ordfeminine', '', '', - '', '', 'Lslash', 'Oslash', 'OE', 'ordmasculine', '', '', '', '', '', 'ae', - '', '', '', 'dotlessi', '', '', 'lslash', 'oslash', 'oe', 'germandbls'], - WinAnsiEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', - 'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus', - 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', - 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', - 'less', 'equal', 'greater', 'question', 'at', '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', 'bracketleft', 'backslash', 'bracketright', - 'asciicircum', 'underscore', 'grave', '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', 'braceleft', 'bar', 'braceright', 'asciitilde', - 'bullet', 'Euro', 'bullet', 'quotesinglbase', 'florin', 'quotedblbase', - 'ellipsis', 'dagger', 'daggerdbl', 'circumflex', 'perthousand', 'Scaron', - 'guilsinglleft', 'OE', 'bullet', 'Zcaron', 'bullet', 'bullet', 'quoteleft', - 'quoteright', 'quotedblleft', 'quotedblright', 'bullet', 'endash', - 'emdash', 'tilde', 'trademark', 'scaron', 'guilsinglright', 'oe', 'bullet', - 'zcaron', 'Ydieresis', '', 'exclamdown', 'cent', 'sterling', - 'currency', 'yen', 'brokenbar', 'section', 'dieresis', 'copyright', - 'ordfeminine', 'guillemotleft', 'logicalnot', 'hyphen', 'registered', - 'macron', 'degree', 'plusminus', 'twosuperior', 'threesuperior', 'acute', - 'mu', 'paragraph', 'periodcentered', 'cedilla', 'onesuperior', - 'ordmasculine', 'guillemotright', 'onequarter', 'onehalf', 'threequarters', - 'questiondown', 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', 'Adieresis', - 'Aring', 'AE', 'Ccedilla', 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', - 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Eth', 'Ntilde', 'Ograve', - 'Oacute', 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', 'Oslash', - 'Ugrave', 'Uacute', 'Ucircumflex', 'Udieresis', 'Yacute', 'Thorn', - 'germandbls', 'agrave', 'aacute', 'acircumflex', 'atilde', 'adieresis', - 'aring', 'ae', 'ccedilla', 'egrave', 'eacute', 'ecircumflex', 'edieresis', - 'igrave', 'iacute', 'icircumflex', 'idieresis', 'eth', 'ntilde', 'ograve', - 'oacute', 'ocircumflex', 'otilde', 'odieresis', 'divide', 'oslash', - 'ugrave', 'uacute', 'ucircumflex', 'udieresis', 'yacute', 'thorn', - 'ydieresis'], - symbolsEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclam', 'universal', 'numbersign', 'existential', 'percent', - 'ampersand', 'suchthat', 'parenleft', 'parenright', 'asteriskmath', 'plus', - 'comma', 'minus', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four', - 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', - 'equal', 'greater', 'question', 'congruent', 'Alpha', 'Beta', 'Chi', - 'Delta', 'Epsilon', 'Phi', 'Gamma', 'Eta', 'Iota', 'theta1', 'Kappa', - 'Lambda', 'Mu', 'Nu', 'Omicron', 'Pi', 'Theta', 'Rho', 'Sigma', 'Tau', - 'Upsilon', 'sigma1', 'Omega', 'Xi', 'Psi', 'Zeta', 'bracketleft', - 'therefore', 'bracketright', 'perpendicular', 'underscore', 'radicalex', - 'alpha', 'beta', 'chi', 'delta', 'epsilon', 'phi', 'gamma', 'eta', 'iota', - 'phi1', 'kappa', 'lambda', 'mu', 'nu', 'omicron', 'pi', 'theta', 'rho', - 'sigma', 'tau', 'upsilon', 'omega1', 'omega', 'xi', 'psi', 'zeta', - 'braceleft', 'bar', 'braceright', 'similar', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', 'Euro', 'Upsilon1', 'minute', 'lessequal', - 'fraction', 'infinity', 'florin', 'club', 'diamond', 'heart', 'spade', - 'arrowboth', 'arrowleft', 'arrowup', 'arrowright', 'arrowdown', 'degree', - 'plusminus', 'second', 'greaterequal', 'multiply', 'proportional', - 'partialdiff', 'bullet', 'divide', 'notequal', 'equivalence', - 'approxequal', 'ellipsis', 'arrowvertex', 'arrowhorizex', 'carriagereturn', - 'aleph', 'Ifraktur', 'Rfraktur', 'weierstrass', 'circlemultiply', - 'circleplus', 'emptyset', 'intersection', 'union', 'propersuperset', - 'reflexsuperset', 'notsubset', 'propersubset', 'reflexsubset', 'element', - 'notelement', 'angle', 'gradient', 'registerserif', 'copyrightserif', - 'trademarkserif', 'product', 'radical', 'dotmath', 'logicalnot', - 'logicaland', 'logicalor', 'arrowdblboth', 'arrowdblleft', 'arrowdblup', - 'arrowdblright', 'arrowdbldown', 'lozenge', 'angleleft', 'registersans', - 'copyrightsans', 'trademarksans', 'summation', 'parenlefttp', - 'parenleftex', 'parenleftbt', 'bracketlefttp', 'bracketleftex', - 'bracketleftbt', 'bracelefttp', 'braceleftmid', 'braceleftbt', 'braceex', - '', 'angleright', 'integral', 'integraltp', 'integralex', 'integralbt', - 'parenrighttp', 'parenrightex', 'parenrightbt', 'bracketrighttp', - 'bracketrightex', 'bracketrightbt', 'bracerighttp', 'bracerightmid', - 'bracerightbt'], - zapfDingbatsEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'a1', 'a2', 'a202', 'a3', 'a4', 'a5', 'a119', 'a118', 'a117', - 'a11', 'a12', 'a13', 'a14', 'a15', 'a16', 'a105', 'a17', 'a18', 'a19', - 'a20', 'a21', 'a22', 'a23', 'a24', 'a25', 'a26', 'a27', 'a28', 'a6', 'a7', - 'a8', 'a9', 'a10', 'a29', 'a30', 'a31', 'a32', 'a33', 'a34', 'a35', 'a36', - 'a37', 'a38', 'a39', 'a40', 'a41', 'a42', 'a43', 'a44', 'a45', 'a46', - 'a47', 'a48', 'a49', 'a50', 'a51', 'a52', 'a53', 'a54', 'a55', 'a56', - 'a57', 'a58', 'a59', 'a60', 'a61', 'a62', 'a63', 'a64', 'a65', 'a66', - 'a67', 'a68', 'a69', 'a70', 'a71', 'a72', 'a73', 'a74', 'a203', 'a75', - 'a204', 'a76', 'a77', 'a78', 'a79', 'a81', 'a82', 'a83', 'a84', 'a97', - 'a98', 'a99', 'a100', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', 'a101', 'a102', 'a103', 'a104', 'a106', 'a107', 'a108', 'a112', - 'a111', 'a110', 'a109', 'a120', 'a121', 'a122', 'a123', 'a124', 'a125', - 'a126', 'a127', 'a128', 'a129', 'a130', 'a131', 'a132', 'a133', 'a134', - 'a135', 'a136', 'a137', 'a138', 'a139', 'a140', 'a141', 'a142', 'a143', - 'a144', 'a145', 'a146', 'a147', 'a148', 'a149', 'a150', 'a151', 'a152', - 'a153', 'a154', 'a155', 'a156', 'a157', 'a158', 'a159', 'a160', 'a161', - 'a163', 'a164', 'a196', 'a165', 'a192', 'a166', 'a167', 'a168', 'a169', - 'a170', 'a171', 'a172', 'a173', 'a162', 'a174', 'a175', 'a176', 'a177', - 'a178', 'a179', 'a193', 'a180', 'a199', 'a181', 'a200', 'a182', '', 'a201', - 'a183', 'a184', 'a197', 'a185', 'a194', 'a198', 'a186', 'a195', 'a187', - 'a188', 'a189', 'a190', 'a191'] -}; - -/** - * Hold a map of decoded fonts and of the standard fourteen Type1 - * fonts and their acronyms. - */ -var stdFontMap = { - 'ArialNarrow': 'Helvetica', - 'ArialNarrow-Bold': 'Helvetica-Bold', - 'ArialNarrow-BoldItalic': 'Helvetica-BoldOblique', - 'ArialNarrow-Italic': 'Helvetica-Oblique', - 'ArialBlack': 'Helvetica', - 'ArialBlack-Bold': 'Helvetica-Bold', - 'ArialBlack-BoldItalic': 'Helvetica-BoldOblique', - 'ArialBlack-Italic': 'Helvetica-Oblique', - 'Arial': 'Helvetica', - 'Arial-Bold': 'Helvetica-Bold', - 'Arial-BoldItalic': 'Helvetica-BoldOblique', - 'Arial-Italic': 'Helvetica-Oblique', - 'Arial-BoldItalicMT': 'Helvetica-BoldOblique', - 'Arial-BoldMT': 'Helvetica-Bold', - 'Arial-ItalicMT': 'Helvetica-Oblique', - 'ArialMT': 'Helvetica', - 'Courier-Bold': 'Courier-Bold', - 'Courier-BoldItalic': 'Courier-BoldOblique', - 'Courier-Italic': 'Courier-Oblique', - 'CourierNew': 'Courier', - 'CourierNew-Bold': 'Courier-Bold', - 'CourierNew-BoldItalic': 'Courier-BoldOblique', - 'CourierNew-Italic': 'Courier-Oblique', - 'CourierNewPS-BoldItalicMT': 'Courier-BoldOblique', - 'CourierNewPS-BoldMT': 'Courier-Bold', - 'CourierNewPS-ItalicMT': 'Courier-Oblique', - 'CourierNewPSMT': 'Courier', - 'Helvetica-Bold': 'Helvetica-Bold', - 'Helvetica-BoldItalic': 'Helvetica-BoldOblique', - 'Helvetica-Italic': 'Helvetica-Oblique', - 'Symbol-Bold': 'Symbol', - 'Symbol-BoldItalic': 'Symbol', - 'Symbol-Italic': 'Symbol', - 'TimesNewRoman': 'Times-Roman', - 'TimesNewRoman-Bold': 'Times-Bold', - 'TimesNewRoman-BoldItalic': 'Times-BoldItalic', - 'TimesNewRoman-Italic': 'Times-Italic', - 'TimesNewRomanPS': 'Times-Roman', - 'TimesNewRomanPS-Bold': 'Times-Bold', - 'TimesNewRomanPS-BoldItalic': 'Times-BoldItalic', - 'TimesNewRomanPS-BoldItalicMT': 'Times-BoldItalic', - 'TimesNewRomanPS-BoldMT': 'Times-Bold', - 'TimesNewRomanPS-Italic': 'Times-Italic', - 'TimesNewRomanPS-ItalicMT': 'Times-Italic', - 'TimesNewRomanPSMT': 'Times-Roman', - 'TimesNewRomanPSMT-Bold': 'Times-Bold', - 'TimesNewRomanPSMT-BoldItalic': 'Times-BoldItalic', - 'TimesNewRomanPSMT-Italic': 'Times-Italic' -}; - -/** - * Holds the map of the non-standard fonts that might be included as a standard - * fonts without glyph data. - */ -var nonStdFontMap = { - 'ComicSansMS': 'Comic Sans MS', - 'ComicSansMS-Bold': 'Comic Sans MS-Bold', - 'ComicSansMS-BoldItalic': 'Comic Sans MS-BoldItalic', - 'ComicSansMS-Italic': 'Comic Sans MS-Italic', - 'LucidaConsole': 'Courier', - 'LucidaConsole-Bold': 'Courier-Bold', - 'LucidaConsole-BoldItalic': 'Courier-BoldOblique', - 'LucidaConsole-Italic': 'Courier-Oblique' -}; - -var serifFonts = { - 'Adobe Jenson': true, 'Adobe Text': true, 'Albertus': true, - 'Aldus': true, 'Alexandria': true, 'Algerian': true, - 'American Typewriter': true, 'Antiqua': true, 'Apex': true, - 'Arno': true, 'Aster': true, 'Aurora': true, - 'Baskerville': true, 'Bell': true, 'Bembo': true, - 'Bembo Schoolbook': true, 'Benguiat': true, 'Berkeley Old Style': true, - 'Bernhard Modern': true, 'Berthold City': true, 'Bodoni': true, - 'Bauer Bodoni': true, 'Book Antiqua': true, 'Bookman': true, - 'Bordeaux Roman': true, 'Californian FB': true, 'Calisto': true, - 'Calvert': true, 'Capitals': true, 'Cambria': true, - 'Cartier': true, 'Caslon': true, 'Catull': true, - 'Centaur': true, 'Century Old Style': true, 'Century Schoolbook': true, - 'Chaparral': true, 'Charis SIL': true, 'Cheltenham': true, - 'Cholla Slab': true, 'Clarendon': true, 'Clearface': true, - 'Cochin': true, 'Colonna': true, 'Computer Modern': true, - 'Concrete Roman': true, 'Constantia': true, 'Cooper Black': true, - 'Corona': true, 'Ecotype': true, 'Egyptienne': true, - 'Elephant': true, 'Excelsior': true, 'Fairfield': true, - 'FF Scala': true, 'Folkard': true, 'Footlight': true, - 'FreeSerif': true, 'Friz Quadrata': true, 'Garamond': true, - 'Gentium': true, 'Georgia': true, 'Gloucester': true, - 'Goudy Old Style': true, 'Goudy Schoolbook': true, 'Goudy Pro Font': true, - 'Granjon': true, 'Guardian Egyptian': true, 'Heather': true, - 'Hercules': true, 'High Tower Text': true, 'Hiroshige': true, - 'Hoefler Text': true, 'Humana Serif': true, 'Imprint': true, - 'Ionic No. 5': true, 'Janson': true, 'Joanna': true, - 'Korinna': true, 'Lexicon': true, 'Liberation Serif': true, - 'Linux Libertine': true, 'Literaturnaya': true, 'Lucida': true, - 'Lucida Bright': true, 'Melior': true, 'Memphis': true, - 'Miller': true, 'Minion': true, 'Modern': true, - 'Mona Lisa': true, 'Mrs Eaves': true, 'MS Serif': true, - 'Museo Slab': true, 'New York': true, 'Nimbus Roman': true, - 'NPS Rawlinson Roadway': true, 'Palatino': true, 'Perpetua': true, - 'Plantin': true, 'Plantin Schoolbook': true, 'Playbill': true, - 'Poor Richard': true, 'Rawlinson Roadway': true, 'Renault': true, - 'Requiem': true, 'Rockwell': true, 'Roman': true, - 'Rotis Serif': true, 'Sabon': true, 'Scala': true, - 'Seagull': true, 'Sistina': true, 'Souvenir': true, - 'STIX': true, 'Stone Informal': true, 'Stone Serif': true, - 'Sylfaen': true, 'Times': true, 'Trajan': true, - 'Trinité': true, 'Trump Mediaeval': true, 'Utopia': true, - 'Vale Type': true, 'Bitstream Vera': true, 'Vera Serif': true, - 'Versailles': true, 'Wanted': true, 'Weiss': true, - 'Wide Latin': true, 'Windsor': true, 'XITS': true -}; - -var symbolsFonts = { - 'Dingbats': true, 'Symbol': true, 'ZapfDingbats': true -}; - -// Some characters, e.g. copyrightserif, mapped to the private use area and -// might not be displayed using standard fonts. Mapping/hacking well-known chars -// to the similar equivalents in the normal characters range. -function mapPrivateUseChars(code) { - switch (code) { - case 0xF8E9: // copyrightsans - case 0xF6D9: // copyrightserif - return 0x00A9; // copyright - default: - return code; - } -} - -var FontLoader = { - listeningForFontLoad: false, - - bind: function fontLoaderBind(fonts, callback) { - function checkFontsLoaded() { - for (var i = 0, ii = fonts.length; i < ii; i++) { - var fontObj = fonts[i]; - if (fontObj.loading) { - return false; - } - } - - document.documentElement.removeEventListener( - 'pdfjsFontLoad', checkFontsLoaded, false); - - callback(); - return true; - } - - var rules = [], names = [], fontsToLoad = []; - var fontCreateTimer = 0; - - for (var i = 0, ii = fonts.length; i < ii; i++) { - var font = fonts[i]; - - // Add the font to the DOM only once or skip if the font - // is already loaded. - if (font.attached || font.loading == false) { - continue; - } - font.attached = true; - - fontsToLoad.push(font); - - var str = ''; - var data = font.data; - if (data) { - var length = data.length; - for (var j = 0; j < length; j++) - str += String.fromCharCode(data[j]); - - var rule = font.bindDOM(str); - if (rule) { - rules.push(rule); - names.push(font.loadedName); - } - } - } - - this.listeningForFontLoad = false; - if (!isWorker && rules.length) { - FontLoader.prepareFontLoadEvent(rules, names, fontsToLoad); - } - - if (!checkFontsLoaded()) { - document.documentElement.addEventListener( - 'pdfjsFontLoad', checkFontsLoaded, false); - } - }, - // Set things up so that at least one pdfjsFontLoad event is - // dispatched when all the @font-face |rules| for |names| have been - // loaded in a subdocument. It's expected that the load of |rules| - // has already started in this (outer) document, so that they should - // be ordered before the load in the subdocument. - prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, names, - fonts) { - /** Hack begin */ - // There's no event when a font has finished downloading so the - // following code is a dirty hack to 'guess' when a font is - // ready. This code will be obsoleted by Mozilla bug 471915. - // - // The only reliable way to know if a font is loaded in Gecko - // (at the moment) is document.onload in a document with - // a @font-face rule defined in a "static" stylesheet. We use a - // subdocument in an @@ -18,14 +18,14 @@ - + \ No newline at end of file From df6ba6955d8fe9692ce9028f71cde962dcc89030 Mon Sep 17 00:00:00 2001 From: j-ed Date: Tue, 22 Jan 2013 14:13:24 +0100 Subject: [PATCH 234/315] Update lib/mail.php Added three additional mail_smtp.. parameters. - mail_smtpdebug - enable debug messages to analyse SMTP problems. - mail_smtptimeout - set SMTP timeout which is set to 10s by default and this is sometimes to short especially if a malware/ spam scanner is used. - mail_smtpsecure - force secure SMTP connections. --- lib/mail.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/mail.php b/lib/mail.php index 4683a1b4ee..ffc4d01b79 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -40,6 +40,9 @@ class OC_Mail { $SMTPAUTH = OC_Config::getValue( 'mail_smtpauth', false ); $SMTPUSERNAME = OC_Config::getValue( 'mail_smtpname', '' ); $SMTPPASSWORD = OC_Config::getValue( 'mail_smtppassword', '' ); + $SMTPDEBUG = OC_Config::getValue( 'mail_smtpdebug', false ); + $SMTPTIMEOUT = OC_Config::getValue( 'mail_smtptimeout', 10 ); + $SMTPSECURE = OC_Config::getValue( 'mail_smtpsecure', '' ); $mailo = new PHPMailer(true); @@ -57,12 +60,15 @@ class OC_Mail { $mailo->Host = $SMTPHOST; $mailo->Port = $SMTPPORT; $mailo->SMTPAuth = $SMTPAUTH; + $mailo->SMTPDebug = $SMTPDEBUG; + $mailo->SMTPSecure = $SMTPSECURE; $mailo->Username = $SMTPUSERNAME; $mailo->Password = $SMTPPASSWORD; + $mailo->Timeout = $SMTPTIMEOUT; - $mailo->From =$fromaddress; + $mailo->From = $fromaddress; $mailo->FromName = $fromname;; - $mailo->Sender =$fromaddress; + $mailo->Sender = $fromaddress; $a=explode(' ', $toaddress); try { foreach($a as $ad) { From 9c069530cbe60dff043cf5bf0aae28546cb419c7 Mon Sep 17 00:00:00 2001 From: j-ed Date: Tue, 22 Jan 2013 14:24:00 +0100 Subject: [PATCH 235/315] Update config/config.sample.php Added three additional mail_smtp.. parameters. - mail_smtpdebug - enable debug messages to analyse SMTP problems. - mail_smtptimeout - set SMTP timeout which is set to 10s by default and this is sometimes to short especially if a malware/ spam scanner is used. - mail_smtpsecure - force secure SMTP connections. --- config/config.sample.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/config.sample.php b/config/config.sample.php index dafb536fa6..0e3ce8bcaf 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -66,6 +66,9 @@ $CONFIG = array( /* URL of the appstore to use, server should understand OCS */ "appstoreurl" => "http://api.apps.owncloud.com/v1", +/* Enable SMTP class debugging */ +"mail_smtpdebug" => false; + /* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */ "mail_smtpmode" => "sendmail", @@ -75,6 +78,13 @@ $CONFIG = array( /* Port to use for sending mail, depends on mail_smtpmode if this is used */ "mail_smtpport" => 25, +/* SMTP server timeout in seconds for sending mail, depends on mail_smtpmode if this is used */ +"mail_smtptimeout" => 10; + +/* SMTP connection prefix or sending mail, depends on mail_smtpmode if this is used. + Can be '', ssl or tls */ +"mail_smtpsecure" => '', + /* authentication needed to send mail, depends on mail_smtpmode if this is used * (false = disable authentication) */ From 47592657d7fa24cca77f47fcddbf35bf0de0485c Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 22 Jan 2013 17:15:03 +0000 Subject: [PATCH 236/315] Added localisation for encryption settings --- .../templates/settings-personal.php | 52 ++++++++--- apps/files_encryption/templates/settings.php | 89 +++++++++++++++---- 2 files changed, 114 insertions(+), 27 deletions(-) diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index de05fa5a4b..1274bd3bb5 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -1,13 +1,45 @@
                -
                - -Choose encryption mode: - -

                - - /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
                - /> Server side encryption (allows you to access your files from the web interface and the desktop client)
                - /> None (no encryption at all)
                -

                +
                + t('Choose encryption mode:'); ?> +

                + + + + /> + t('Client side encryption (most secure but makes it impossible to access your data from the web interface)'); ?> +
                + + + /> + t('Server side encryption (allows you to access your files from the web interface and the desktop client)'); ?> +
                + + + /> + t('None (no encryption at all)'); ?> +
                +

                diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php index e2a9bcc3be..544ec793f3 100644 --- a/apps/files_encryption/templates/settings.php +++ b/apps/files_encryption/templates/settings.php @@ -1,24 +1,79 @@
                - Choose encryption mode: - -

                Important: Once you selected an encryption mode there is no way to change it back

                - -

                - /> Client side encryption (most secure but makes it impossible to access your data from the web interface)
                - /> Server side encryption (allows you to access your files from the web interface and the desktop client)
                - /> User specific (let the user decide)
                - /> None (no encryption at all)
                -

                -

                - t('Encryption'); ?> - t("Exclude the following file types from encryption"); ?> - + /> + + t("Client side encryption (most secure but makes it impossible to access your data from the web interface)"); ?> +
                + + + /> + + t('Server side encryption (allows you to access your files from the web interface and the desktop client)'); ?> +
                + + + /> + + t('User specific (let the user decide)'); ?> +
                + + + /> + + t('None (no encryption at all)'); ?> +
                + +

                +

                + t('Encryption'); ?> + + t("Exclude the following file types from encryption"); ?> + + -

                + +

                From ca454f0228a9d915ac56ac41f65ee865a7141ddc Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 22 Jan 2013 17:15:51 +0000 Subject: [PATCH 237/315] Removed depreciated file --- settings/trans.png | Bin 185 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 settings/trans.png diff --git a/settings/trans.png b/settings/trans.png deleted file mode 100644 index ef57510d530920a91a9e0d9212faf7159c6d4d87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k92}K#X;^)4C~IxyaaOClDyqr82*Fc zg1yTp14TFsJR*x37`TN&n2}-D90{Nxdx@v7EBhT5QEm(I#bpa!fI>bP0l+XkKD Date: Tue, 22 Jan 2013 18:34:59 +0100 Subject: [PATCH 238/315] rename 'publicListView' switch to 'disableSharing' because this is not only used for the public list view --- apps/files/js/publiclistview.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/files/js/publiclistview.php b/apps/files/js/publiclistview.php index 8652dabc42..f1c67aabb4 100644 --- a/apps/files/js/publiclistview.php +++ b/apps/files/js/publiclistview.php @@ -13,8 +13,8 @@ header("Content-type: text/javascript"); header("Cache-Control: no-cache, must-revalidate"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); -if ( array_key_exists('publicListView', $_) && $_['publicListView'] == true ) { - echo "var publicListView = true;"; +if ( array_key_exists('disableSharing', $_) && $_['disableSharing'] == true ) { + echo "var disableSharing = true;"; } else { - echo "var publicListView = false;"; + echo "var disableSharing = false;"; } From dfa5f2de4d6fc79114c533b79ee5f3eb412d30c5 Mon Sep 17 00:00:00 2001 From: j-ed Date: Tue, 22 Jan 2013 21:33:01 +0100 Subject: [PATCH 239/315] Update config/config.sample.php Fixed type in line 70. Thank you for pointing me to that typo. --- config/config.sample.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.sample.php b/config/config.sample.php index 0e3ce8bcaf..362cb0a085 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -67,7 +67,7 @@ $CONFIG = array( "appstoreurl" => "http://api.apps.owncloud.com/v1", /* Enable SMTP class debugging */ -"mail_smtpdebug" => false; +"mail_smtpdebug" => false, /* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */ "mail_smtpmode" => "sendmail", From dcda792fbcb3e5743e345553e2fc53fd19a742b9 Mon Sep 17 00:00:00 2001 From: j-ed Date: Tue, 22 Jan 2013 21:42:39 +0100 Subject: [PATCH 240/315] Update config/config.sample.php fixed an other typo. --- config/config.sample.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 362cb0a085..f26a53c155 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -79,11 +79,11 @@ $CONFIG = array( "mail_smtpport" => 25, /* SMTP server timeout in seconds for sending mail, depends on mail_smtpmode if this is used */ -"mail_smtptimeout" => 10; +"mail_smtptimeout" => 10, /* SMTP connection prefix or sending mail, depends on mail_smtpmode if this is used. Can be '', ssl or tls */ -"mail_smtpsecure" => '', +"mail_smtpsecure" => "", /* authentication needed to send mail, depends on mail_smtpmode if this is used * (false = disable authentication) From c986dbe5739347f3fd40fa17132169de9fd9494c Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Wed, 23 Jan 2013 00:06:18 +0100 Subject: [PATCH 241/315] [tx-robot] updated from transifex --- apps/files/l10n/ca.php | 1 + apps/files/l10n/el.php | 1 + apps/files/l10n/fa.php | 1 + apps/files/l10n/ja_JP.php | 1 + apps/files/l10n/pt_PT.php | 1 + apps/files/l10n/sv.php | 4 + apps/files/l10n/th_TH.php | 9 ++ apps/files/l10n/tr.php | 9 ++ apps/files/l10n/zh_CN.php | 1 + apps/files_encryption/l10n/ar.php | 3 +- apps/files_encryption/l10n/bg_BG.php | 5 +- apps/files_encryption/l10n/bn_BD.php | 5 +- apps/files_encryption/l10n/ca.php | 3 +- apps/files_encryption/l10n/cs_CZ.php | 3 +- apps/files_encryption/l10n/da.php | 3 +- apps/files_encryption/l10n/de.php | 3 +- apps/files_encryption/l10n/de_DE.php | 3 +- apps/files_encryption/l10n/el.php | 3 +- apps/files_encryption/l10n/eo.php | 3 +- apps/files_encryption/l10n/es.php | 3 +- apps/files_encryption/l10n/es_AR.php | 3 +- apps/files_encryption/l10n/et_EE.php | 3 +- apps/files_encryption/l10n/eu.php | 3 +- apps/files_encryption/l10n/fa.php | 4 +- apps/files_encryption/l10n/fi_FI.php | 3 +- apps/files_encryption/l10n/fr.php | 3 +- apps/files_encryption/l10n/gl.php | 7 +- apps/files_encryption/l10n/he.php | 5 +- apps/files_encryption/l10n/hu_HU.php | 5 +- apps/files_encryption/l10n/id.php | 3 +- apps/files_encryption/l10n/is.php | 5 +- apps/files_encryption/l10n/it.php | 3 +- apps/files_encryption/l10n/ja_JP.php | 3 +- apps/files_encryption/l10n/ko.php | 3 +- apps/files_encryption/l10n/ku_IQ.php | 3 +- apps/files_encryption/l10n/lt_LT.php | 3 +- apps/files_encryption/l10n/mk.php | 3 +- apps/files_encryption/l10n/nb_NO.php | 3 +- apps/files_encryption/l10n/nl.php | 3 +- apps/files_encryption/l10n/pl.php | 3 +- apps/files_encryption/l10n/pt_BR.php | 3 +- apps/files_encryption/l10n/pt_PT.php | 3 +- apps/files_encryption/l10n/ro.php | 3 +- apps/files_encryption/l10n/ru.php | 3 +- apps/files_encryption/l10n/ru_RU.php | 3 +- apps/files_encryption/l10n/si_LK.php | 3 +- apps/files_encryption/l10n/sk_SK.php | 3 +- apps/files_encryption/l10n/sl.php | 5 +- apps/files_encryption/l10n/sr.php | 3 +- apps/files_encryption/l10n/sv.php | 3 +- apps/files_encryption/l10n/ta_LK.php | 3 +- apps/files_encryption/l10n/th_TH.php | 3 +- apps/files_encryption/l10n/tr.php | 5 +- apps/files_encryption/l10n/uk.php | 3 +- apps/files_encryption/l10n/vi.php | 3 +- apps/files_encryption/l10n/zh_CN.GB2312.php | 3 +- apps/files_encryption/l10n/zh_CN.php | 3 +- apps/files_encryption/l10n/zh_TW.php | 3 +- apps/files_external/l10n/th_TH.php | 2 + apps/user_ldap/l10n/sv.php | 4 + apps/user_ldap/l10n/th_TH.php | 5 + apps/user_webdavauth/l10n/sv.php | 4 +- apps/user_webdavauth/l10n/th_TH.php | 4 +- apps/user_webdavauth/l10n/zh_CN.php | 4 +- core/l10n/fa.php | 1 + core/l10n/th_TH.php | 11 +- core/l10n/tr.php | 24 +++- l10n/ar/files_encryption.po | 68 ++++++++++-- l10n/bg_BG/files_encryption.po | 74 ++++++++++--- l10n/bn_BD/files_encryption.po | 74 ++++++++++--- l10n/ca/files.po | 9 +- l10n/ca/files_encryption.po | 70 ++++++++++-- l10n/cs_CZ/files_encryption.po | 68 ++++++++++-- l10n/da/files_encryption.po | 68 ++++++++++-- l10n/de/files_encryption.po | 68 ++++++++++-- l10n/de_DE/files_encryption.po | 68 ++++++++++-- l10n/el/files.po | 9 +- l10n/el/files_encryption.po | 70 ++++++++++-- l10n/eo/files_encryption.po | 70 ++++++++++-- l10n/es/files_encryption.po | 70 ++++++++++-- l10n/es_AR/files_encryption.po | 68 ++++++++++-- l10n/et_EE/files_encryption.po | 70 ++++++++++-- l10n/eu/files_encryption.po | 70 ++++++++++-- l10n/fa/core.po | 72 ++++++------ l10n/fa/files.po | 6 +- l10n/fa/files_encryption.po | 68 ++++++++++-- l10n/fi_FI/files_encryption.po | 70 ++++++++++-- l10n/fr/files_encryption.po | 70 ++++++++++-- l10n/gl/files_encryption.po | 68 ++++++++++-- l10n/gl/lib.po | 12 +- l10n/he/files_encryption.po | 74 ++++++++++--- l10n/hi/files_encryption.po | 70 ++++++++++-- l10n/hr/files_encryption.po | 70 ++++++++++-- l10n/hu_HU/files_encryption.po | 74 ++++++++++--- l10n/ia/files_encryption.po | 70 ++++++++++-- l10n/id/files_encryption.po | 68 ++++++++++-- l10n/is/files_encryption.po | 74 ++++++++++--- l10n/it/files_encryption.po | 70 ++++++++++-- l10n/ja_JP/files.po | 8 +- l10n/ja_JP/files_encryption.po | 70 ++++++++++-- l10n/ka_GE/files_encryption.po | 68 ++++++++++-- l10n/ko/files_encryption.po | 68 ++++++++++-- l10n/ku_IQ/files_encryption.po | 68 ++++++++++-- l10n/lb/files_encryption.po | 70 ++++++++++-- l10n/lt_LT/files_encryption.po | 70 ++++++++++-- l10n/lv/files_encryption.po | 70 ++++++++++-- l10n/mk/files_encryption.po | 68 ++++++++++-- l10n/ms_MY/files_encryption.po | 70 ++++++++++-- l10n/nb_NO/files_encryption.po | 70 ++++++++++-- l10n/nl/files_encryption.po | 70 ++++++++++-- l10n/nn_NO/files_encryption.po | 70 ++++++++++-- l10n/oc/files_encryption.po | 68 ++++++++++-- l10n/pl/files_encryption.po | 70 ++++++++++-- l10n/pl_PL/files_encryption.po | 70 ++++++++++-- l10n/pt_BR/files_encryption.po | 68 ++++++++++-- l10n/pt_PT/files.po | 9 +- l10n/pt_PT/files_encryption.po | 68 ++++++++++-- l10n/ro/files_encryption.po | 68 ++++++++++-- l10n/ru/files_encryption.po | 70 ++++++++++-- l10n/ru_RU/files_encryption.po | 68 ++++++++++-- l10n/si_LK/files_encryption.po | 68 ++++++++++-- l10n/sk_SK/files_encryption.po | 68 ++++++++++-- l10n/sl/files_encryption.po | 68 ++++++++++-- l10n/sr/files_encryption.po | 68 ++++++++++-- l10n/sr@latin/files_encryption.po | 70 ++++++++++-- l10n/sv/files.po | 14 +-- l10n/sv/files_encryption.po | 70 ++++++++++-- l10n/sv/lib.po | 12 +- l10n/sv/user_ldap.po | 16 +-- l10n/sv/user_webdavauth.po | 12 +- l10n/ta_LK/files_encryption.po | 68 ++++++++++-- l10n/templates/core.pot | 42 +++---- l10n/templates/files.pot | 2 +- l10n/templates/files_encryption.pot | 70 ++++++++++-- l10n/templates/files_external.pot | 2 +- l10n/templates/files_sharing.pot | 2 +- l10n/templates/files_versions.pot | 2 +- l10n/templates/lib.pot | 2 +- l10n/templates/settings.pot | 2 +- l10n/templates/user_ldap.pot | 2 +- l10n/templates/user_webdavauth.pot | 2 +- l10n/th_TH/core.po | 92 +++++++-------- l10n/th_TH/files.po | 26 ++--- l10n/th_TH/files_encryption.po | 70 ++++++++++-- l10n/th_TH/files_external.po | 18 +-- l10n/th_TH/lib.po | 12 +- l10n/th_TH/settings.po | 42 +++---- l10n/th_TH/user_ldap.po | 18 +-- l10n/th_TH/user_webdavauth.po | 14 +-- l10n/tr/core.po | 117 ++++++++++---------- l10n/tr/files.po | 25 +++-- l10n/tr/files_encryption.po | 74 ++++++++++--- l10n/tr/lib.po | 11 +- l10n/uk/files_encryption.po | 68 ++++++++++-- l10n/vi/files_encryption.po | 68 ++++++++++-- l10n/zh_CN.GB2312/files_encryption.po | 68 ++++++++++-- l10n/zh_CN/files.po | 9 +- l10n/zh_CN/files_encryption.po | 68 ++++++++++-- l10n/zh_CN/user_webdavauth.po | 11 +- l10n/zh_HK/files_encryption.po | 68 ++++++++++-- l10n/zh_TW/files_encryption.po | 70 ++++++++++-- lib/l10n/gl.php | 1 + lib/l10n/sv.php | 1 + lib/l10n/th_TH.php | 1 + lib/l10n/tr.php | 1 + settings/l10n/th_TH.php | 17 +++ 166 files changed, 4124 insertions(+), 1090 deletions(-) diff --git a/apps/files/l10n/ca.php b/apps/files/l10n/ca.php index be330fb82c..b35a9299de 100644 --- a/apps/files/l10n/ca.php +++ b/apps/files/l10n/ca.php @@ -29,6 +29,7 @@ "'.' is an invalid file name." => "'.' és un nom no vàlid per un fitxer.", "File name cannot be empty." => "El nom del fitxer no pot ser buit.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "El nóm no és vàlid, '\\', '/', '<', '>', ':', '\"', '|', '?' i '*' no estan permesos.", +"Your download is being prepared. This might take some time if the files are big." => "S'està preparant la baixada. Pot trigar una estona si els fitxers són grans.", "Unable to upload your file as it is a directory or has 0 bytes" => "No es pot pujar el fitxer perquè és una carpeta o té 0 bytes", "Upload Error" => "Error en la pujada", "Close" => "Tanca", diff --git a/apps/files/l10n/el.php b/apps/files/l10n/el.php index 274367b32a..cc93943d28 100644 --- a/apps/files/l10n/el.php +++ b/apps/files/l10n/el.php @@ -29,6 +29,7 @@ "'.' is an invalid file name." => "'.' είναι μη έγκυρο όνομα αρχείου.", "File name cannot be empty." => "Το όνομα αρχείου δεν πρέπει να είναι κενό.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Μη έγκυρο όνομα, '\\', '/', '<', '>', ':', '\"', '|', '?' και '*' δεν επιτρέπονται.", +"Your download is being prepared. This might take some time if the files are big." => "Η λήψη προετοιμάζεται. Αυτό μπορεί να πάρει ώρα εάν τα αρχεία έχουν μεγάλο μέγεθος.", "Unable to upload your file as it is a directory or has 0 bytes" => "Αδυναμία στην αποστολή του αρχείου σας αφού είναι φάκελος ή έχει 0 bytes", "Upload Error" => "Σφάλμα Αποστολής", "Close" => "Κλείσιμο", diff --git a/apps/files/l10n/fa.php b/apps/files/l10n/fa.php index 24059bdeab..ec8b5cdec4 100644 --- a/apps/files/l10n/fa.php +++ b/apps/files/l10n/fa.php @@ -8,6 +8,7 @@ "Missing a temporary folder" => "یک پوشه موقت گم شده است", "Failed to write to disk" => "نوشتن بر روی دیسک سخت ناموفق بود", "Files" => "فایل ها", +"Unshare" => "لغو اشتراک", "Delete" => "پاک کردن", "Rename" => "تغییرنام", "replace" => "جایگزین", diff --git a/apps/files/l10n/ja_JP.php b/apps/files/l10n/ja_JP.php index 750b4644d7..548263f54a 100644 --- a/apps/files/l10n/ja_JP.php +++ b/apps/files/l10n/ja_JP.php @@ -29,6 +29,7 @@ "'.' is an invalid file name." => "'.' は無効なファイル名です。", "File name cannot be empty." => "ファイル名を空にすることはできません。", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "無効な名前、'\\', '/', '<', '>', ':', '\"', '|', '?', '*' は使用できません。", +"Your download is being prepared. This might take some time if the files are big." => "ダウンロードの準備中です。ファイルサイズが大きい場合は少し時間がかかるかもしれません。", "Unable to upload your file as it is a directory or has 0 bytes" => "ディレクトリもしくは0バイトのファイルはアップロードできません", "Upload Error" => "アップロードエラー", "Close" => "閉じる", diff --git a/apps/files/l10n/pt_PT.php b/apps/files/l10n/pt_PT.php index d3f2251326..0ed13fa998 100644 --- a/apps/files/l10n/pt_PT.php +++ b/apps/files/l10n/pt_PT.php @@ -29,6 +29,7 @@ "'.' is an invalid file name." => "'.' não é um nome de ficheiro válido!", "File name cannot be empty." => "O nome do ficheiro não pode estar vazio.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome Inválido, os caracteres '\\', '/', '<', '>', ':', '\"', '|', '?' e '*' não são permitidos.", +"Your download is being prepared. This might take some time if the files are big." => "O seu download está a ser preparado. Este processo pode demorar algum tempo se os ficheiros forem grandes.", "Unable to upload your file as it is a directory or has 0 bytes" => "Não é possível fazer o envio do ficheiro devido a ser uma pasta ou ter 0 bytes", "Upload Error" => "Erro no envio", "Close" => "Fechar", diff --git a/apps/files/l10n/sv.php b/apps/files/l10n/sv.php index df75f15e7a..7597f6908e 100644 --- a/apps/files/l10n/sv.php +++ b/apps/files/l10n/sv.php @@ -1,5 +1,8 @@ "Ladda upp", +"Could not move %s - File with this name already exists" => "Kunde inte flytta %s - Det finns redan en fil med detta namn", +"Could not move %s" => "Kan inte flytta %s", +"Unable to rename file" => "Kan inte byta namn på filen", "No file was uploaded. Unknown error" => "Ingen fil uppladdad. Okänt fel", "There is no error, the file uploaded with success" => "Inga fel uppstod. Filen laddades upp utan problem", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Den uppladdade filen överskrider upload_max_filesize direktivet php.ini:", @@ -26,6 +29,7 @@ "'.' is an invalid file name." => "'.' är ett ogiltigt filnamn.", "File name cannot be empty." => "Filnamn kan inte vara tomt.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ogiltigt namn, '\\', '/', '<', '>', ':', '\"', '|', '?' och '*' är inte tillåtet.", +"Your download is being prepared. This might take some time if the files are big." => "Din nedladdning förbereds. Det kan ta tid om det är stora filer.", "Unable to upload your file as it is a directory or has 0 bytes" => "Kunde inte ladda upp dina filer eftersom det antingen är en mapp eller har 0 bytes.", "Upload Error" => "Uppladdningsfel", "Close" => "Stäng", diff --git a/apps/files/l10n/th_TH.php b/apps/files/l10n/th_TH.php index f2394f0449..43a905ea3b 100644 --- a/apps/files/l10n/th_TH.php +++ b/apps/files/l10n/th_TH.php @@ -1,5 +1,8 @@ "อัพโหลด", +"Could not move %s - File with this name already exists" => "ไม่สามารถย้าย %s ได้ - ไฟล์ที่ใช้ชื่อนี้มีอยู่แล้ว", +"Could not move %s" => "ไม่สามารถย้าย %s ได้", +"Unable to rename file" => "ไม่สามารถเปลี่ยนชื่อไฟล์ได้", "No file was uploaded. Unknown error" => "ยังไม่มีไฟล์ใดที่ถูกอัพโหลด เกิดข้อผิดพลาดที่ไม่ทราบสาเหตุ", "There is no error, the file uploaded with success" => "ไม่มีข้อผิดพลาดใดๆ ไฟล์ถูกอัพโหลดเรียบร้อยแล้ว", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "ขนาดไฟล์ที่อัพโหลดมีขนาดเกิน upload_max_filesize ที่ระบุไว้ใน php.ini", @@ -8,6 +11,8 @@ "No file was uploaded" => "ยังไม่มีไฟล์ที่ถูกอัพโหลด", "Missing a temporary folder" => "แฟ้มเอกสารชั่วคราวเกิดการสูญหาย", "Failed to write to disk" => "เขียนข้อมูลลงแผ่นดิสก์ล้มเหลว", +"Not enough space available" => "มีพื้นที่เหลือไม่เพียงพอ", +"Invalid directory." => "ไดเร็กทอรี่ไม่ถูกต้อง", "Files" => "ไฟล์", "Unshare" => "ยกเลิกการแชร์ข้อมูล", "Delete" => "ลบ", @@ -21,7 +26,10 @@ "replaced {new_name} with {old_name}" => "แทนที่ {new_name} ด้วย {old_name} แล้ว", "unshared {files}" => "ยกเลิกการแชร์แล้ว {files} ไฟล์", "deleted {files}" => "ลบไฟล์แล้ว {files} ไฟล์", +"'.' is an invalid file name." => "'.' เป็นชื่อไฟล์ที่ไม่ถูกต้อง", +"File name cannot be empty." => "ชื่อไฟล์ไม่สามารถเว้นว่างได้", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "ชื่อที่ใช้ไม่ถูกต้อง, '\\', '/', '<', '>', ':', '\"', '|', '?' และ '*' ไม่ได้รับอนุญาตให้ใช้งานได้", +"Your download is being prepared. This might take some time if the files are big." => "กำลังเตรียมดาวน์โหลดข้อมูล หากไฟล์มีขนาดใหญ่ อาจใช้เวลาสักครู่", "Unable to upload your file as it is a directory or has 0 bytes" => "ไม่สามารถอัพโหลดไฟล์ของคุณได้ เนื่องจากไฟล์ดังกล่าวเป็นไดเร็กทอรี่หรือมีขนาด 0 ไบต์", "Upload Error" => "เกิดข้อผิดพลาดในการอัพโหลด", "Close" => "ปิด", @@ -31,6 +39,7 @@ "Upload cancelled." => "การอัพโหลดถูกยกเลิก", "File upload is in progress. Leaving the page now will cancel the upload." => "การอัพโหลดไฟล์กำลังอยู่ในระหว่างดำเนินการ การออกจากหน้าเว็บนี้จะทำให้การอัพโหลดถูกยกเลิก", "URL cannot be empty." => "URL ไม่สามารถเว้นว่างได้", +"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "ชื่อโฟลเดอร์ไม่ถูกต้อง การใช้งาน 'แชร์' สงวนไว้สำหรับ Owncloud เท่านั้น", "{count} files scanned" => "สแกนไฟล์แล้ว {count} ไฟล์", "error while scanning" => "พบข้อผิดพลาดในระหว่างการสแกนไฟล์", "Name" => "ชื่อ", diff --git a/apps/files/l10n/tr.php b/apps/files/l10n/tr.php index c49c7e47dd..6b390570f3 100644 --- a/apps/files/l10n/tr.php +++ b/apps/files/l10n/tr.php @@ -1,5 +1,8 @@ "Yükle", +"Could not move %s - File with this name already exists" => "%s taşınamadı. Bu isimde dosya zaten var.", +"Could not move %s" => "%s taşınamadı", +"Unable to rename file" => "Dosya adı değiştirilemedi", "No file was uploaded. Unknown error" => "Dosya yüklenmedi. Bilinmeyen hata", "There is no error, the file uploaded with success" => "Bir hata yok, dosya başarıyla yüklendi", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "php.ini dosyasında upload_max_filesize ile belirtilen dosya yükleme sınırı aşıldı.", @@ -8,6 +11,8 @@ "No file was uploaded" => "Hiç dosya yüklenmedi", "Missing a temporary folder" => "Geçici bir klasör eksik", "Failed to write to disk" => "Diske yazılamadı", +"Not enough space available" => "Yeterli disk alanı yok", +"Invalid directory." => "Geçersiz dizin.", "Files" => "Dosyalar", "Unshare" => "Paylaşılmayan", "Delete" => "Sil", @@ -21,7 +26,10 @@ "replaced {new_name} with {old_name}" => "{new_name} ismi {old_name} ile değiştirildi", "unshared {files}" => "paylaşılmamış {files}", "deleted {files}" => "silinen {files}", +"'.' is an invalid file name." => "'.' geçersiz dosya adı.", +"File name cannot be empty." => "Dosya adı boş olamaz.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Geçersiz isim, '\\', '/', '<', '>', ':', '\"', '|', '?' ve '*' karakterlerine izin verilmemektedir.", +"Your download is being prepared. This might take some time if the files are big." => "İndirmeniz hazırlanıyor. Dosya büyük ise biraz zaman alabilir.", "Unable to upload your file as it is a directory or has 0 bytes" => "Dosyanızın boyutu 0 byte olduğundan veya bir dizin olduğundan yüklenemedi", "Upload Error" => "Yükleme hatası", "Close" => "Kapat", @@ -31,6 +39,7 @@ "Upload cancelled." => "Yükleme iptal edildi.", "File upload is in progress. Leaving the page now will cancel the upload." => "Dosya yükleme işlemi sürüyor. Şimdi sayfadan ayrılırsanız işleminiz iptal olur.", "URL cannot be empty." => "URL boş olamaz.", +"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Geçersiz dizin adı. Shared isminin kullanımı Owncloud tarafından rezerver edilmiştir.", "{count} files scanned" => "{count} dosya tarandı", "error while scanning" => "tararamada hata oluşdu", "Name" => "Ad", diff --git a/apps/files/l10n/zh_CN.php b/apps/files/l10n/zh_CN.php index 3e9a13b519..f8dedc118e 100644 --- a/apps/files/l10n/zh_CN.php +++ b/apps/files/l10n/zh_CN.php @@ -29,6 +29,7 @@ "'.' is an invalid file name." => "'.' 是一个无效的文件名。", "File name cannot be empty." => "文件名不能为空。", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "无效名称,'\\', '/', '<', '>', ':', '\"', '|', '?' 和 '*' 不被允许使用。", +"Your download is being prepared. This might take some time if the files are big." => "下载正在准备中。如果文件较大可能会花费一些时间。", "Unable to upload your file as it is a directory or has 0 bytes" => "无法上传文件,因为它是一个目录或者大小为 0 字节", "Upload Error" => "上传错误", "Close" => "关闭", diff --git a/apps/files_encryption/l10n/ar.php b/apps/files_encryption/l10n/ar.php index 756a9d7279..f08585e485 100644 --- a/apps/files_encryption/l10n/ar.php +++ b/apps/files_encryption/l10n/ar.php @@ -1,6 +1,5 @@ "التشفير", "Exclude the following file types from encryption" => "استبعد أنواع الملفات التالية من التشفير", -"None" => "لا شيء", -"Enable Encryption" => "تفعيل التشفير" +"None" => "لا شيء" ); diff --git a/apps/files_encryption/l10n/bg_BG.php b/apps/files_encryption/l10n/bg_BG.php index cb1613ef37..4ceee127af 100644 --- a/apps/files_encryption/l10n/bg_BG.php +++ b/apps/files_encryption/l10n/bg_BG.php @@ -1,6 +1,5 @@ "Криптиране", -"Enable Encryption" => "Включване на криптирането", -"None" => "Няма", -"Exclude the following file types from encryption" => "Изключване на следните файлови типове от криптирането" +"Exclude the following file types from encryption" => "Изключване на следните файлови типове от криптирането", +"None" => "Няма" ); diff --git a/apps/files_encryption/l10n/bn_BD.php b/apps/files_encryption/l10n/bn_BD.php index c8f041d762..29c486b8ca 100644 --- a/apps/files_encryption/l10n/bn_BD.php +++ b/apps/files_encryption/l10n/bn_BD.php @@ -1,6 +1,5 @@ "সংকেতায়ন", -"Enable Encryption" => "সংকেতায়ন সক্রিয় কর", -"None" => "কোনটিই নয়", -"Exclude the following file types from encryption" => "সংকেতায়ন থেকে নিম্নোক্ত ধরণসমূহ বাদ দাও" +"Exclude the following file types from encryption" => "সংকেতায়ন থেকে নিম্নোক্ত ধরণসমূহ বাদ দাও", +"None" => "কোনটিই নয়" ); diff --git a/apps/files_encryption/l10n/ca.php b/apps/files_encryption/l10n/ca.php index 8e087b3462..d97a8666df 100644 --- a/apps/files_encryption/l10n/ca.php +++ b/apps/files_encryption/l10n/ca.php @@ -1,6 +1,5 @@ "Encriptatge", "Exclude the following file types from encryption" => "Exclou els tipus de fitxers següents de l'encriptatge", -"None" => "Cap", -"Enable Encryption" => "Activa l'encriptatge" +"None" => "Cap" ); diff --git a/apps/files_encryption/l10n/cs_CZ.php b/apps/files_encryption/l10n/cs_CZ.php index 9be2be9809..90b1243f1f 100644 --- a/apps/files_encryption/l10n/cs_CZ.php +++ b/apps/files_encryption/l10n/cs_CZ.php @@ -1,6 +1,5 @@ "Šifrování", "Exclude the following file types from encryption" => "Při šifrování vynechat následující typy souborů", -"None" => "Žádné", -"Enable Encryption" => "Povolit šifrování" +"None" => "Žádné" ); diff --git a/apps/files_encryption/l10n/da.php b/apps/files_encryption/l10n/da.php index 144c9f9708..1b4664ce1c 100644 --- a/apps/files_encryption/l10n/da.php +++ b/apps/files_encryption/l10n/da.php @@ -1,6 +1,5 @@ "Kryptering", "Exclude the following file types from encryption" => "Ekskluder følgende filtyper fra kryptering", -"None" => "Ingen", -"Enable Encryption" => "Aktivér kryptering" +"None" => "Ingen" ); diff --git a/apps/files_encryption/l10n/de.php b/apps/files_encryption/l10n/de.php index d486a82322..34c596dc4b 100644 --- a/apps/files_encryption/l10n/de.php +++ b/apps/files_encryption/l10n/de.php @@ -1,6 +1,5 @@ "Verschlüsselung", "Exclude the following file types from encryption" => "Die folgenden Dateitypen von der Verschlüsselung ausnehmen", -"None" => "Keine", -"Enable Encryption" => "Verschlüsselung aktivieren" +"None" => "Keine" ); diff --git a/apps/files_encryption/l10n/de_DE.php b/apps/files_encryption/l10n/de_DE.php index d486a82322..34c596dc4b 100644 --- a/apps/files_encryption/l10n/de_DE.php +++ b/apps/files_encryption/l10n/de_DE.php @@ -1,6 +1,5 @@ "Verschlüsselung", "Exclude the following file types from encryption" => "Die folgenden Dateitypen von der Verschlüsselung ausnehmen", -"None" => "Keine", -"Enable Encryption" => "Verschlüsselung aktivieren" +"None" => "Keine" ); diff --git a/apps/files_encryption/l10n/el.php b/apps/files_encryption/l10n/el.php index 40a7c6a367..70e65a5237 100644 --- a/apps/files_encryption/l10n/el.php +++ b/apps/files_encryption/l10n/el.php @@ -1,6 +1,5 @@ "Κρυπτογράφηση", "Exclude the following file types from encryption" => "Εξαίρεση των παρακάτω τύπων αρχείων από την κρυπτογράφηση", -"None" => "Καμία", -"Enable Encryption" => "Ενεργοποίηση Κρυπτογράφησης" +"None" => "Καμία" ); diff --git a/apps/files_encryption/l10n/eo.php b/apps/files_encryption/l10n/eo.php index af3c9ae98e..c6f82dcb8a 100644 --- a/apps/files_encryption/l10n/eo.php +++ b/apps/files_encryption/l10n/eo.php @@ -1,6 +1,5 @@ "Ĉifrado", "Exclude the following file types from encryption" => "Malinkluzivigi la jenajn dosiertipojn el ĉifrado", -"None" => "Nenio", -"Enable Encryption" => "Kapabligi ĉifradon" +"None" => "Nenio" ); diff --git a/apps/files_encryption/l10n/es.php b/apps/files_encryption/l10n/es.php index b7e7601b35..1fea54ff35 100644 --- a/apps/files_encryption/l10n/es.php +++ b/apps/files_encryption/l10n/es.php @@ -1,6 +1,5 @@ "Cifrado", "Exclude the following file types from encryption" => "Excluir del cifrado los siguientes tipos de archivo", -"None" => "Ninguno", -"Enable Encryption" => "Habilitar cifrado" +"None" => "Ninguno" ); diff --git a/apps/files_encryption/l10n/es_AR.php b/apps/files_encryption/l10n/es_AR.php index a15c37e730..31898f50fd 100644 --- a/apps/files_encryption/l10n/es_AR.php +++ b/apps/files_encryption/l10n/es_AR.php @@ -1,6 +1,5 @@ "Encriptación", "Exclude the following file types from encryption" => "Exceptuar de la encriptación los siguientes tipos de archivo", -"None" => "Ninguno", -"Enable Encryption" => "Habilitar encriptación" +"None" => "Ninguno" ); diff --git a/apps/files_encryption/l10n/et_EE.php b/apps/files_encryption/l10n/et_EE.php index a7cd9395bf..0c0ef23114 100644 --- a/apps/files_encryption/l10n/et_EE.php +++ b/apps/files_encryption/l10n/et_EE.php @@ -1,6 +1,5 @@ "Krüpteerimine", "Exclude the following file types from encryption" => "Järgnevaid failitüüpe ära krüpteeri", -"None" => "Pole", -"Enable Encryption" => "Luba krüpteerimine" +"None" => "Pole" ); diff --git a/apps/files_encryption/l10n/eu.php b/apps/files_encryption/l10n/eu.php index 57b6a4927b..2bb1a46954 100644 --- a/apps/files_encryption/l10n/eu.php +++ b/apps/files_encryption/l10n/eu.php @@ -1,6 +1,5 @@ "Enkriptazioa", "Exclude the following file types from encryption" => "Ez enkriptatu hurrengo fitxategi motak", -"None" => "Bat ere ez", -"Enable Encryption" => "Gaitu enkriptazioa" +"None" => "Bat ere ez" ); diff --git a/apps/files_encryption/l10n/fa.php b/apps/files_encryption/l10n/fa.php index 0faa3f3aae..0cdee74f5a 100644 --- a/apps/files_encryption/l10n/fa.php +++ b/apps/files_encryption/l10n/fa.php @@ -1,5 +1,5 @@ "رمزگذاری", -"None" => "هیچ‌کدام", -"Enable Encryption" => "فعال کردن رمزگذاری" +"Exclude the following file types from encryption" => "نادیده گرفتن فایل های زیر برای رمز گذاری", +"None" => "هیچ‌کدام" ); diff --git a/apps/files_encryption/l10n/fi_FI.php b/apps/files_encryption/l10n/fi_FI.php index 5796499a26..433ae890ef 100644 --- a/apps/files_encryption/l10n/fi_FI.php +++ b/apps/files_encryption/l10n/fi_FI.php @@ -1,6 +1,5 @@ "Salaus", "Exclude the following file types from encryption" => "Jätä seuraavat tiedostotyypit salaamatta", -"None" => "Ei mitään", -"Enable Encryption" => "Käytä salausta" +"None" => "Ei mitään" ); diff --git a/apps/files_encryption/l10n/fr.php b/apps/files_encryption/l10n/fr.php index c9367d1a31..f78a90ad59 100644 --- a/apps/files_encryption/l10n/fr.php +++ b/apps/files_encryption/l10n/fr.php @@ -1,6 +1,5 @@ "Chiffrement", "Exclude the following file types from encryption" => "Ne pas chiffrer les fichiers dont les types sont les suivants", -"None" => "Aucun", -"Enable Encryption" => "Activer le chiffrement" +"None" => "Aucun" ); diff --git a/apps/files_encryption/l10n/gl.php b/apps/files_encryption/l10n/gl.php index 1434ff48aa..42fcfce1cc 100644 --- a/apps/files_encryption/l10n/gl.php +++ b/apps/files_encryption/l10n/gl.php @@ -1,6 +1,5 @@ "Encriptado", -"Exclude the following file types from encryption" => "Excluír os seguintes tipos de ficheiro da encriptación", -"None" => "Nada", -"Enable Encryption" => "Habilitar encriptación" +"Encryption" => "Cifrado", +"Exclude the following file types from encryption" => "Excluír os seguintes tipos de ficheiro do cifrado", +"None" => "Nada" ); diff --git a/apps/files_encryption/l10n/he.php b/apps/files_encryption/l10n/he.php index 0332d59520..9adb6d2b92 100644 --- a/apps/files_encryption/l10n/he.php +++ b/apps/files_encryption/l10n/he.php @@ -1,6 +1,5 @@ "הצפנה", -"Enable Encryption" => "הפעל הצפנה", -"None" => "כלום", -"Exclude the following file types from encryption" => "הוצא את סוגי הקבצים הבאים מהצפנה" +"Exclude the following file types from encryption" => "הוצא את סוגי הקבצים הבאים מהצפנה", +"None" => "כלום" ); diff --git a/apps/files_encryption/l10n/hu_HU.php b/apps/files_encryption/l10n/hu_HU.php index 4352d8b771..1ef1effd41 100644 --- a/apps/files_encryption/l10n/hu_HU.php +++ b/apps/files_encryption/l10n/hu_HU.php @@ -1,6 +1,5 @@ "Titkosítás", -"Exclude the following file types from encryption" => "A következő fájl típusok kizárása a titkosításból", -"None" => "Egyik sem", -"Enable Encryption" => "Titkosítás engedélyezése" +"Exclude the following file types from encryption" => "A következő fájltípusok kizárása a titkosításból", +"None" => "Egyik sem" ); diff --git a/apps/files_encryption/l10n/id.php b/apps/files_encryption/l10n/id.php index 824ae88304..20f33b8782 100644 --- a/apps/files_encryption/l10n/id.php +++ b/apps/files_encryption/l10n/id.php @@ -1,6 +1,5 @@ "enkripsi", "Exclude the following file types from encryption" => "pengecualian untuk tipe file berikut dari enkripsi", -"None" => "tidak ada", -"Enable Encryption" => "aktifkan enkripsi" +"None" => "tidak ada" ); diff --git a/apps/files_encryption/l10n/is.php b/apps/files_encryption/l10n/is.php index 3210ecb4f8..a2559cf2b7 100644 --- a/apps/files_encryption/l10n/is.php +++ b/apps/files_encryption/l10n/is.php @@ -1,6 +1,5 @@ "Dulkóðun", -"Enable Encryption" => "Virkja dulkóðun", -"None" => "Ekkert", -"Exclude the following file types from encryption" => "Undanskilja eftirfarandi skráartegundir frá dulkóðun" +"Exclude the following file types from encryption" => "Undanskilja eftirfarandi skráartegundir frá dulkóðun", +"None" => "Ekkert" ); diff --git a/apps/files_encryption/l10n/it.php b/apps/files_encryption/l10n/it.php index 5136b06179..d7e68a66e9 100644 --- a/apps/files_encryption/l10n/it.php +++ b/apps/files_encryption/l10n/it.php @@ -1,6 +1,5 @@ "Cifratura", "Exclude the following file types from encryption" => "Escludi i seguenti tipi di file dalla cifratura", -"None" => "Nessuna", -"Enable Encryption" => "Abilita cifratura" +"None" => "Nessuna" ); diff --git a/apps/files_encryption/l10n/ja_JP.php b/apps/files_encryption/l10n/ja_JP.php index 2c3e5410de..bd630c1d71 100644 --- a/apps/files_encryption/l10n/ja_JP.php +++ b/apps/files_encryption/l10n/ja_JP.php @@ -1,6 +1,5 @@ "暗号化", "Exclude the following file types from encryption" => "暗号化から除外するファイルタイプ", -"None" => "なし", -"Enable Encryption" => "暗号化を有効にする" +"None" => "なし" ); diff --git a/apps/files_encryption/l10n/ko.php b/apps/files_encryption/l10n/ko.php index 4702753435..68d60c1ae3 100644 --- a/apps/files_encryption/l10n/ko.php +++ b/apps/files_encryption/l10n/ko.php @@ -1,6 +1,5 @@ "암호화", "Exclude the following file types from encryption" => "다음 파일 형식은 암호화하지 않음", -"None" => "없음", -"Enable Encryption" => "암호화 사용" +"None" => "없음" ); diff --git a/apps/files_encryption/l10n/ku_IQ.php b/apps/files_encryption/l10n/ku_IQ.php index bd8977ac51..06bb9b9325 100644 --- a/apps/files_encryption/l10n/ku_IQ.php +++ b/apps/files_encryption/l10n/ku_IQ.php @@ -1,6 +1,5 @@ "نهێنیکردن", "Exclude the following file types from encryption" => "به‌ربه‌ست کردنی ئه‌م جۆره‌ په‌ڕگانه له‌ نهێنیکردن", -"None" => "هیچ", -"Enable Encryption" => "چالاکردنی نهێنیکردن" +"None" => "هیچ" ); diff --git a/apps/files_encryption/l10n/lt_LT.php b/apps/files_encryption/l10n/lt_LT.php index b939df164c..22cbe7a4ff 100644 --- a/apps/files_encryption/l10n/lt_LT.php +++ b/apps/files_encryption/l10n/lt_LT.php @@ -1,6 +1,5 @@ "Šifravimas", "Exclude the following file types from encryption" => "Nešifruoti pasirinkto tipo failų", -"None" => "Nieko", -"Enable Encryption" => "Įjungti šifravimą" +"None" => "Nieko" ); diff --git a/apps/files_encryption/l10n/mk.php b/apps/files_encryption/l10n/mk.php index dfcaed9f37..7ccf8ac2d5 100644 --- a/apps/files_encryption/l10n/mk.php +++ b/apps/files_encryption/l10n/mk.php @@ -1,6 +1,5 @@ "Енкрипција", "Exclude the following file types from encryption" => "Исклучи ги следните типови на датотеки од енкрипција", -"None" => "Ништо", -"Enable Encryption" => "Овозможи енкрипција" +"None" => "Ништо" ); diff --git a/apps/files_encryption/l10n/nb_NO.php b/apps/files_encryption/l10n/nb_NO.php index e65df7b6ce..2ec6670e92 100644 --- a/apps/files_encryption/l10n/nb_NO.php +++ b/apps/files_encryption/l10n/nb_NO.php @@ -1,6 +1,5 @@ "Kryptering", "Exclude the following file types from encryption" => "Ekskluder følgende filer fra kryptering", -"None" => "Ingen", -"Enable Encryption" => "Slå på kryptering" +"None" => "Ingen" ); diff --git a/apps/files_encryption/l10n/nl.php b/apps/files_encryption/l10n/nl.php index 1ea56006fc..7c09009cba 100644 --- a/apps/files_encryption/l10n/nl.php +++ b/apps/files_encryption/l10n/nl.php @@ -1,6 +1,5 @@ "Versleuteling", "Exclude the following file types from encryption" => "Versleutel de volgende bestand types niet", -"None" => "Geen", -"Enable Encryption" => "Zet versleuteling aan" +"None" => "Geen" ); diff --git a/apps/files_encryption/l10n/pl.php b/apps/files_encryption/l10n/pl.php index 5cfc707450..896086108e 100644 --- a/apps/files_encryption/l10n/pl.php +++ b/apps/files_encryption/l10n/pl.php @@ -1,6 +1,5 @@ "Szyfrowanie", "Exclude the following file types from encryption" => "Wyłącz następujące typy plików z szyfrowania", -"None" => "Brak", -"Enable Encryption" => "Włącz szyfrowanie" +"None" => "Brak" ); diff --git a/apps/files_encryption/l10n/pt_BR.php b/apps/files_encryption/l10n/pt_BR.php index 5c02f52217..086d073cf5 100644 --- a/apps/files_encryption/l10n/pt_BR.php +++ b/apps/files_encryption/l10n/pt_BR.php @@ -1,6 +1,5 @@ "Criptografia", "Exclude the following file types from encryption" => "Excluir os seguintes tipos de arquivo da criptografia", -"None" => "Nenhuma", -"Enable Encryption" => "Habilitar Criptografia" +"None" => "Nenhuma" ); diff --git a/apps/files_encryption/l10n/pt_PT.php b/apps/files_encryption/l10n/pt_PT.php index 570462b414..5634184a3b 100644 --- a/apps/files_encryption/l10n/pt_PT.php +++ b/apps/files_encryption/l10n/pt_PT.php @@ -1,6 +1,5 @@ "Encriptação", "Exclude the following file types from encryption" => "Excluir da encriptação os seguintes tipo de ficheiros", -"None" => "Nenhum", -"Enable Encryption" => "Activar Encriptação" +"None" => "Nenhum" ); diff --git a/apps/files_encryption/l10n/ro.php b/apps/files_encryption/l10n/ro.php index 97f3f262d7..fc0f24f483 100644 --- a/apps/files_encryption/l10n/ro.php +++ b/apps/files_encryption/l10n/ro.php @@ -1,6 +1,5 @@ "Încriptare", "Exclude the following file types from encryption" => "Exclude următoarele tipuri de fișiere de la încriptare", -"None" => "Niciuna", -"Enable Encryption" => "Activare încriptare" +"None" => "Niciuna" ); diff --git a/apps/files_encryption/l10n/ru.php b/apps/files_encryption/l10n/ru.php index 3a7e84b6d0..14115c1268 100644 --- a/apps/files_encryption/l10n/ru.php +++ b/apps/files_encryption/l10n/ru.php @@ -1,6 +1,5 @@ "Шифрование", "Exclude the following file types from encryption" => "Исключить шифрование следующих типов файлов", -"None" => "Ничего", -"Enable Encryption" => "Включить шифрование" +"None" => "Ничего" ); diff --git a/apps/files_encryption/l10n/ru_RU.php b/apps/files_encryption/l10n/ru_RU.php index 1328b0d035..4321fb8a8a 100644 --- a/apps/files_encryption/l10n/ru_RU.php +++ b/apps/files_encryption/l10n/ru_RU.php @@ -1,6 +1,5 @@ "Шифрование", "Exclude the following file types from encryption" => "Исключите следующие типы файлов из шифрования", -"None" => "Ни один", -"Enable Encryption" => "Включить шифрование" +"None" => "Ни один" ); diff --git a/apps/files_encryption/l10n/si_LK.php b/apps/files_encryption/l10n/si_LK.php index a29884afff..2d61bec45b 100644 --- a/apps/files_encryption/l10n/si_LK.php +++ b/apps/files_encryption/l10n/si_LK.php @@ -1,6 +1,5 @@ "ගුප්ත කේතනය", "Exclude the following file types from encryption" => "මෙම ගොනු වර්ග ගුප්ත කේතනය කිරීමෙන් බැහැරව තබන්න", -"None" => "කිසිවක් නැත", -"Enable Encryption" => "ගුප්ත කේතනය සක්‍රිය කරන්න" +"None" => "කිසිවක් නැත" ); diff --git a/apps/files_encryption/l10n/sk_SK.php b/apps/files_encryption/l10n/sk_SK.php index 598f1294f6..5aebb6e35b 100644 --- a/apps/files_encryption/l10n/sk_SK.php +++ b/apps/files_encryption/l10n/sk_SK.php @@ -1,6 +1,5 @@ "Šifrovanie", "Exclude the following file types from encryption" => "Vynechať nasledujúce súbory pri šifrovaní", -"None" => "Žiadne", -"Enable Encryption" => "Zapnúť šifrovanie" +"None" => "Žiadne" ); diff --git a/apps/files_encryption/l10n/sl.php b/apps/files_encryption/l10n/sl.php index 65807910e1..db963ef2f8 100644 --- a/apps/files_encryption/l10n/sl.php +++ b/apps/files_encryption/l10n/sl.php @@ -1,6 +1,5 @@ "Šifriranje", -"Exclude the following file types from encryption" => "Naslednje vrste datotek naj se ne šifrirajo", -"None" => "Brez", -"Enable Encryption" => "Omogoči šifriranje" +"Exclude the following file types from encryption" => "Navedene vrste datotek naj ne bodo šifrirane", +"None" => "Brez" ); diff --git a/apps/files_encryption/l10n/sr.php b/apps/files_encryption/l10n/sr.php index 4718780ee5..198bcc94ef 100644 --- a/apps/files_encryption/l10n/sr.php +++ b/apps/files_encryption/l10n/sr.php @@ -1,6 +1,5 @@ "Шифровање", "Exclude the following file types from encryption" => "Не шифруј следеће типове датотека", -"None" => "Ништа", -"Enable Encryption" => "Омогући шифровање" +"None" => "Ништа" ); diff --git a/apps/files_encryption/l10n/sv.php b/apps/files_encryption/l10n/sv.php index 0a477f8346..c154de1a76 100644 --- a/apps/files_encryption/l10n/sv.php +++ b/apps/files_encryption/l10n/sv.php @@ -1,6 +1,5 @@ "Kryptering", "Exclude the following file types from encryption" => "Exkludera följande filtyper från kryptering", -"None" => "Ingen", -"Enable Encryption" => "Aktivera kryptering" +"None" => "Ingen" ); diff --git a/apps/files_encryption/l10n/ta_LK.php b/apps/files_encryption/l10n/ta_LK.php index 1d1ef74007..aab628b551 100644 --- a/apps/files_encryption/l10n/ta_LK.php +++ b/apps/files_encryption/l10n/ta_LK.php @@ -1,6 +1,5 @@ "மறைக்குறியீடு", "Exclude the following file types from encryption" => "மறைக்குறியாக்கலில் பின்வரும் கோப்பு வகைகளை நீக்கவும்", -"None" => "ஒன்றுமில்லை", -"Enable Encryption" => "மறைக்குறியாக்கலை இயலுமைப்படுத்துக" +"None" => "ஒன்றுமில்லை" ); diff --git a/apps/files_encryption/l10n/th_TH.php b/apps/files_encryption/l10n/th_TH.php index c2685de6e3..65fcd80685 100644 --- a/apps/files_encryption/l10n/th_TH.php +++ b/apps/files_encryption/l10n/th_TH.php @@ -1,6 +1,5 @@ "การเข้ารหัส", "Exclude the following file types from encryption" => "ไม่ต้องรวมชนิดของไฟล์ดังต่อไปนี้จากการเข้ารหัส", -"None" => "ไม่ต้อง", -"Enable Encryption" => "เปิดใช้งานการเข้ารหัส" +"None" => "ไม่ต้อง" ); diff --git a/apps/files_encryption/l10n/tr.php b/apps/files_encryption/l10n/tr.php index 474ee42b84..07f78d148c 100644 --- a/apps/files_encryption/l10n/tr.php +++ b/apps/files_encryption/l10n/tr.php @@ -1,6 +1,5 @@ "Şifreleme", -"Enable Encryption" => "Şifrelemeyi Etkinleştir", -"None" => "Hiçbiri", -"Exclude the following file types from encryption" => "Aşağıdaki dosya tiplerini şifrelemeye dahil etme" +"Exclude the following file types from encryption" => "Aşağıdaki dosya tiplerini şifrelemeye dahil etme", +"None" => "Hiçbiri" ); diff --git a/apps/files_encryption/l10n/uk.php b/apps/files_encryption/l10n/uk.php index 3c15bb2843..e358921565 100644 --- a/apps/files_encryption/l10n/uk.php +++ b/apps/files_encryption/l10n/uk.php @@ -1,6 +1,5 @@ "Шифрування", "Exclude the following file types from encryption" => "Не шифрувати файли наступних типів", -"None" => "Жоден", -"Enable Encryption" => "Включити шифрування" +"None" => "Жоден" ); diff --git a/apps/files_encryption/l10n/vi.php b/apps/files_encryption/l10n/vi.php index cabf2da7dc..218285b675 100644 --- a/apps/files_encryption/l10n/vi.php +++ b/apps/files_encryption/l10n/vi.php @@ -1,6 +1,5 @@ "Mã hóa", "Exclude the following file types from encryption" => "Loại trừ các loại tập tin sau đây từ mã hóa", -"None" => "none", -"Enable Encryption" => "BẬT mã hóa" +"None" => "Không có gì hết" ); diff --git a/apps/files_encryption/l10n/zh_CN.GB2312.php b/apps/files_encryption/l10n/zh_CN.GB2312.php index 297444fcf5..31a3d3b49b 100644 --- a/apps/files_encryption/l10n/zh_CN.GB2312.php +++ b/apps/files_encryption/l10n/zh_CN.GB2312.php @@ -1,6 +1,5 @@ "加密", "Exclude the following file types from encryption" => "从加密中排除如下文件类型", -"None" => "无", -"Enable Encryption" => "启用加密" +"None" => "无" ); diff --git a/apps/files_encryption/l10n/zh_CN.php b/apps/files_encryption/l10n/zh_CN.php index 1e1247d15f..aa4817b590 100644 --- a/apps/files_encryption/l10n/zh_CN.php +++ b/apps/files_encryption/l10n/zh_CN.php @@ -1,6 +1,5 @@ "加密", "Exclude the following file types from encryption" => "从加密中排除列出的文件类型", -"None" => "None", -"Enable Encryption" => "开启加密" +"None" => "None" ); diff --git a/apps/files_encryption/l10n/zh_TW.php b/apps/files_encryption/l10n/zh_TW.php index 4c62130cf4..fecebbe250 100644 --- a/apps/files_encryption/l10n/zh_TW.php +++ b/apps/files_encryption/l10n/zh_TW.php @@ -1,6 +1,5 @@ "加密", "Exclude the following file types from encryption" => "下列的檔案類型不加密", -"None" => "無", -"Enable Encryption" => "啟用加密" +"None" => "無" ); diff --git a/apps/files_external/l10n/th_TH.php b/apps/files_external/l10n/th_TH.php index 70ab8d3348..870995c8e7 100644 --- a/apps/files_external/l10n/th_TH.php +++ b/apps/files_external/l10n/th_TH.php @@ -5,6 +5,8 @@ "Fill out all required fields" => "กรอกข้อมูลในช่องข้อมูลที่จำเป็นต้องกรอกทั้งหมด", "Please provide a valid Dropbox app key and secret." => "กรุณากรอกรหัส app key ของ Dropbox และรหัสลับ", "Error configuring Google Drive storage" => "เกิดข้อผิดพลาดในการกำหนดค่าการจัดเก็บข้อมูลในพื้นที่ของ Google Drive", +"Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "คำเตือน: \"smbclient\" ยังไม่ได้ถูกติดตั้ง. การชี้ CIFS/SMB เพื่อแชร์ข้อมูลไม่สามารถกระทำได้ กรุณาสอบถามข้อมูลเพิ่มเติมจากผู้ดูแลระบบเพื่อติดตั้ง.", +"Warning: The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "คำเตือน: การสนับสนุนการใช้งาน FTP ในภาษา PHP ยังไม่ได้ถูกเปิดใช้งานหรือถูกติดตั้ง. การชี้ FTP เพื่อแชร์ข้อมูลไม่สามารถดำเนินการได้ กรุณาสอบถามข้อมูลเพิ่มเติมจากผู้ดูแลระบบเพื่อติดตั้ง", "External Storage" => "พื้นทีจัดเก็บข้อมูลจากภายนอก", "Mount point" => "จุดชี้ตำแหน่ง", "Backend" => "ด้านหลังระบบ", diff --git a/apps/user_ldap/l10n/sv.php b/apps/user_ldap/l10n/sv.php index 1e36ff91ba..25abfdd7dd 100644 --- a/apps/user_ldap/l10n/sv.php +++ b/apps/user_ldap/l10n/sv.php @@ -1,8 +1,10 @@ Warning: Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behaviour. Please ask your system administrator to disable one of them." => "Varning: Apps user_ldap och user_webdavauth är inkompatibla. Oväntade problem kan uppstå. Be din systemadministratör att inaktivera en av dom.", +"Warning: The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "Varning: PHP LDAP - modulen är inte installerad, serversidan kommer inte att fungera. Kontakta din systemadministratör för installation.", "Host" => "Server", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Du behöver inte ange protokoll förutom om du använder SSL. Starta då med ldaps://", "Base DN" => "Start DN", +"One Base DN per line" => "Ett Start DN per rad", "You can specify Base DN for users and groups in the Advanced tab" => "Du kan ange start DN för användare och grupper under fliken Avancerat", "User DN" => "Användare DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN för användaren som skall användas, t.ex. uid=agent, dc=example, dc=com. För anonym åtkomst, lämna DN och lösenord tomt.", @@ -19,7 +21,9 @@ "without any placeholder, e.g. \"objectClass=posixGroup\"." => "utan platshållare, t.ex. \"objectClass=posixGroup\".", "Port" => "Port", "Base User Tree" => "Bas för användare i katalogtjänst", +"One User Base DN per line" => "En Användare start DN per rad", "Base Group Tree" => "Bas för grupper i katalogtjänst", +"One Group Base DN per line" => "En Grupp start DN per rad", "Group-Member association" => "Attribut för gruppmedlemmar", "Use TLS" => "Använd TLS", "Do not use it for SSL connections, it will fail." => "Använd inte för SSL-anslutningar, det kommer inte att fungera.", diff --git a/apps/user_ldap/l10n/th_TH.php b/apps/user_ldap/l10n/th_TH.php index acc7a4936b..e3a941c424 100644 --- a/apps/user_ldap/l10n/th_TH.php +++ b/apps/user_ldap/l10n/th_TH.php @@ -1,7 +1,10 @@ Warning: Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behaviour. Please ask your system administrator to disable one of them." => "คำเตือน: แอปฯ user_ldap และ user_webdavauth ไม่สามารถใช้งานร่วมกันได้. คุณอาจประสพปัญหาที่ไม่คาดคิดจากเหตุการณ์ดังกล่าว กรุณาติดต่อผู้ดูแลระบบของคุณเพื่อระงับการใช้งานแอปฯ ตัวใดตัวหนึ่งข้างต้น", +"Warning: The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "คำเตือน: โมดูล PHP LDAP ยังไม่ได้ถูกติดตั้ง, ระบบด้านหลังจะไม่สามารถทำงานได้ กรุณาติดต่อผู้ดูแลระบบของคุณเพื่อทำการติดตั้งโมดูลดังกล่าว", "Host" => "โฮสต์", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "คุณสามารถปล่อยช่องโปรโตคอลเว้นไว้ได้, ยกเว้นกรณีที่คุณต้องการใช้ SSL จากนั้นเริ่มต้นด้วย ldaps://", "Base DN" => "DN ฐาน", +"One Base DN per line" => "หนึ่ง Base DN ต่อบรรทัด", "You can specify Base DN for users and groups in the Advanced tab" => "คุณสามารถระบุ DN หลักสำหรับผู้ใช้งานและกลุ่มต่างๆในแท็บขั้นสูงได้", "User DN" => "DN ของผู้ใช้งาน", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN ของผู้ใช้งานที่เป็นลูกค้าอะไรก็ตามที่ผูกอยู่ด้วย เช่น uid=agent, dc=example, dc=com, สำหรับการเข้าถึงโดยบุคคลนิรนาม, ให้เว้นว่าง DN และ รหัสผ่านเอาไว้", @@ -18,7 +21,9 @@ "without any placeholder, e.g. \"objectClass=posixGroup\"." => "โดยไม่ต้องมีตัวยึดใดๆ, เช่น \"objectClass=posixGroup\",", "Port" => "พอร์ต", "Base User Tree" => "รายการผู้ใช้งานหลักแบบ Tree", +"One User Base DN per line" => "หนึ่ง User Base DN ต่อบรรทัด", "Base Group Tree" => "รายการกลุ่มหลักแบบ Tree", +"One Group Base DN per line" => "หนึ่ง Group Base DN ต่อบรรทัด", "Group-Member association" => "ความสัมพันธ์ของสมาชิกในกลุ่ม", "Use TLS" => "ใช้ TLS", "Do not use it for SSL connections, it will fail." => "กรุณาอย่าใช้การเชื่อมต่อแบบ SSL การเชื่อมต่อจะเกิดการล้มเหลว", diff --git a/apps/user_webdavauth/l10n/sv.php b/apps/user_webdavauth/l10n/sv.php index 245a510134..c79b35c27c 100644 --- a/apps/user_webdavauth/l10n/sv.php +++ b/apps/user_webdavauth/l10n/sv.php @@ -1,3 +1,5 @@ "URL: http://" +"WebDAV Authentication" => "WebDAV Autentisering", +"URL: http://" => "URL: http://", +"ownCloud will send the user credentials to this URL. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud kommer skicka användaruppgifterna till denna URL. Denna plugin kontrollerar svaret och tolkar HTTP-statuskoderna 401 och 403 som felaktiga uppgifter, och alla andra svar som giltiga uppgifter." ); diff --git a/apps/user_webdavauth/l10n/th_TH.php b/apps/user_webdavauth/l10n/th_TH.php index 9bd32954b0..2bd1f685e6 100644 --- a/apps/user_webdavauth/l10n/th_TH.php +++ b/apps/user_webdavauth/l10n/th_TH.php @@ -1,3 +1,5 @@ "WebDAV URL: http://" +"WebDAV Authentication" => "WebDAV Authentication", +"URL: http://" => "URL: http://", +"ownCloud will send the user credentials to this URL. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud จะส่งข้อมูลการเข้าใช้งานของผู้ใช้งานไปยังที่อยู่ URL ดังกล่าวนี้ ปลั๊กอินดังกล่าวจะทำการตรวจสอบข้อมูลที่โต้ตอบกลับมาและจะทำการแปลรหัส HTTP statuscodes 401 และ 403 ให้เป็นข้อมูลการเข้าใช้งานที่ไม่สามารถใช้งานได้ ส่วนข้อมูลอื่นๆที่เหลือทั้งหมดจะเป็นข้อมูลการเข้าใช้งานที่สามารถใช้งานได้" ); diff --git a/apps/user_webdavauth/l10n/zh_CN.php b/apps/user_webdavauth/l10n/zh_CN.php index 5b06409b42..72d2a0c11d 100644 --- a/apps/user_webdavauth/l10n/zh_CN.php +++ b/apps/user_webdavauth/l10n/zh_CN.php @@ -1,3 +1,5 @@ "URL:http://" +"WebDAV Authentication" => "WebDAV 认证", +"URL: http://" => "URL:http://", +"ownCloud will send the user credentials to this URL. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud 将会发送用户的身份到此 URL。这个插件检查返回值并且将 HTTP 状态编码 401 和 403 解释为非法身份,其他所有返回值为合法身份。" ); diff --git a/core/l10n/fa.php b/core/l10n/fa.php index a7c3c9ab2e..ad5bafeb1a 100644 --- a/core/l10n/fa.php +++ b/core/l10n/fa.php @@ -17,6 +17,7 @@ "Ok" => "قبول", "Error" => "خطا", "Password" => "گذرواژه", +"Unshare" => "لغو اشتراک", "create" => "ایجاد", "ownCloud password reset" => "پسورد ابرهای شما تغییرکرد", "Use the following link to reset your password: {link}" => "از لینک زیر جهت دوباره سازی پسورد استفاده کنید :\n{link}", diff --git a/core/l10n/th_TH.php b/core/l10n/th_TH.php index 183997e4c9..bcbd70d03e 100644 --- a/core/l10n/th_TH.php +++ b/core/l10n/th_TH.php @@ -1,4 +1,8 @@ "ผู้ใช้งาน %s ได้แชร์ไฟล์ให้กับคุณ", +"User %s shared a folder with you" => "ผู้ใช้งาน %s ได้แชร์โฟลเดอร์ให้กับคุณ", +"User %s shared the file \"%s\" with you. It is available for download here: %s" => "ผู้ใช้งาน %s ได้แชร์ไฟล์ \"%s\" ให้กับคุณ และคุณสามารถสามารถดาวน์โหลดไฟล์ดังกล่าวได้จากที่นี่: %s", +"User %s shared the folder \"%s\" with you. It is available for download here: %s" => "ผู้ใช้งาน %s ได้แชร์โฟลเดอร์ \"%s\" ให้กับคุณ และคุณสามารถดาวน์โหลดโฟลเดอร์ดังกล่าวได้จากที่นี่: %s", "Category type not provided." => "ยังไม่ได้ระบุชนิดของหมวดหมู่", "No category to add?" => "ไม่มีหมวดหมู่ที่ต้องการเพิ่ม?", "This category already exists: " => "หมวดหมู่นี้มีอยู่แล้ว: ", @@ -39,6 +43,8 @@ "Share with link" => "แชร์ด้วยลิงก์", "Password protect" => "ใส่รหัสผ่านไว้", "Password" => "รหัสผ่าน", +"Email link to person" => "ส่งลิงก์ให้ทางอีเมล", +"Send" => "ส่ง", "Set expiration date" => "กำหนดวันที่หมดอายุ", "Expiration date" => "วันที่หมดอายุ", "Share via email:" => "แชร์ผ่านทางอีเมล", @@ -55,6 +61,8 @@ "Password protected" => "ใส่รหัสผ่านไว้", "Error unsetting expiration date" => "เกิดข้อผิดพลาดในการยกเลิกการตั้งค่าวันที่หมดอายุ", "Error setting expiration date" => "เกิดข้อผิดพลาดในการตั้งค่าวันที่หมดอายุ", +"Sending ..." => "กำลังส่ง...", +"Email sent" => "ส่งอีเมล์แล้ว", "ownCloud password reset" => "รีเซ็ตรหัสผ่าน ownCloud", "Use the following link to reset your password: {link}" => "ใช้ลิงค์ต่อไปนี้เพื่อเปลี่ยนรหัสผ่านของคุณใหม่: {link}", "You will receive a link to reset your password via Email." => "คุณจะได้รับลิงค์เพื่อกำหนดรหัสผ่านใหม่ทางอีเมล์", @@ -118,5 +126,6 @@ "remember" => "จำรหัสผ่าน", "Log in" => "เข้าสู่ระบบ", "prev" => "ก่อนหน้า", -"next" => "ถัดไป" +"next" => "ถัดไป", +"Updating ownCloud to version %s, this may take a while." => "กำลังอัพเดท ownCloud ไปเป็นรุ่น %s, กรุณารอสักครู่" ); diff --git a/core/l10n/tr.php b/core/l10n/tr.php index 284a4d9713..58e28a9b3b 100644 --- a/core/l10n/tr.php +++ b/core/l10n/tr.php @@ -1,9 +1,16 @@ "%s kullanıcısı sizinle bir dosyayı paylaştı", +"User %s shared a folder with you" => "%s kullanıcısı sizinle bir dizini paylaştı", +"User %s shared the file \"%s\" with you. It is available for download here: %s" => "%s kullanıcısı \"%s\" dosyasını sizinle paylaştı. %s adresinden indirilebilir", +"User %s shared the folder \"%s\" with you. It is available for download here: %s" => "%s kullanıcısı \"%s\" dizinini sizinle paylaştı. %s adresinden indirilebilir", "Category type not provided." => "Kategori türü desteklenmemektedir.", "No category to add?" => "Eklenecek kategori yok?", "This category already exists: " => "Bu kategori zaten mevcut: ", "Object type not provided." => "Nesne türü desteklenmemektedir.", +"%s ID not provided." => "%s ID belirtilmedi.", +"Error adding %s to favorites." => "%s favorilere eklenirken hata oluştu", "No categories selected for deletion." => "Silmek için bir kategori seçilmedi", +"Error removing %s from favorites." => "%s favorilere çıkarılırken hata oluştu", "Settings" => "Ayarlar", "seconds ago" => "saniye önce", "1 minute ago" => "1 dakika önce", @@ -25,18 +32,25 @@ "Ok" => "Tamam", "The object type is not specified." => "Nesne türü belirtilmemiş.", "Error" => "Hata", +"The app name is not specified." => "uygulama adı belirtilmedi.", +"The required file {file} is not installed!" => "İhtiyaç duyulan {file} dosyası kurulu değil.", "Error while sharing" => "Paylaşım sırasında hata ", +"Error while unsharing" => "Paylaşım iptal ediliyorken hata", "Error while changing permissions" => "İzinleri değiştirirken hata oluştu", +"Shared with you and the group {group} by {owner}" => " {owner} tarafından sizinle ve {group} ile paylaştırılmış", +"Shared with you by {owner}" => "{owner} trafından sizinle paylaştırıldı", "Share with" => "ile Paylaş", "Share with link" => "Bağlantı ile paylaş", "Password protect" => "Şifre korunması", "Password" => "Parola", +"Email link to person" => "Kişiye e-posta linki", "Send" => "Gönder", "Set expiration date" => "Son kullanma tarihini ayarla", "Expiration date" => "Son kullanım tarihi", "Share via email:" => "Eposta ile paylaş", "No people found" => "Kişi bulunamadı", "Resharing is not allowed" => "Tekrar paylaşmaya izin verilmiyor", +"Shared in {item} with {user}" => " {item} içinde {user} ile paylaşılanlarlar", "Unshare" => "Paylaşılmayan", "can edit" => "düzenleyebilir", "access control" => "erişim kontrolü", @@ -45,6 +59,8 @@ "delete" => "sil", "share" => "paylaş", "Password protected" => "Paralo korumalı", +"Error unsetting expiration date" => "Geçerlilik tarihi tanımlama kaldırma hatası", +"Error setting expiration date" => "Geçerlilik tarihi tanımlama hatası", "Sending ..." => "Gönderiliyor...", "Email sent" => "Eposta gönderildi", "ownCloud password reset" => "ownCloud parola sıfırlama", @@ -68,6 +84,9 @@ "Edit categories" => "Kategorileri düzenle", "Add" => "Ekle", "Security Warning" => "Güvenlik Uyarisi", +"No secure random number generator is available, please enable the PHP OpenSSL extension." => "Güvenli rasgele sayı üreticisi bulunamadı. Lütfen PHP OpenSSL eklentisini etkinleştirin.", +"Without a secure random number generator an attacker may be able to predict password reset tokens and take over your account." => "Güvenli rasgele sayı üreticisi olmadan saldırganlar parola sıfırlama simgelerini tahmin edip hesabınızı ele geçirebilir.", +"Your data directory and your files are probably accessible from the internet. The .htaccess file that ownCloud provides is not working. We strongly suggest that you configure your webserver in a way that the data directory is no longer accessible or you move the data directory outside the webserver document root." => "data dizininiz ve dosyalarınız büyük ihtimalle internet üzerinden erişilebilir. Owncloud tarafından sağlanan .htaccess dosyası çalışmıyor. Web sunucunuzu yapılandırarak data dizinine erişimi kapatmanızı veya data dizinini web sunucu döküman dizini dışına almanızı şiddetle tavsiye ederiz.", "Create an admin account" => "Bir yönetici hesabı oluşturun", "Advanced" => "Gelişmiş", "Data folder" => "Veri klasörü", @@ -101,9 +120,12 @@ "web services under your control" => "kontrolünüzdeki web servisleri", "Log out" => "Çıkış yap", "Automatic logon rejected!" => "Otomatik oturum açma reddedildi!", +"If you did not change your password recently, your account may be compromised!" => "Yakın zamanda parolanızı değiştirmedi iseniz hesabınız riske girebilir.", +"Please change your password to secure your account again." => "Hesabınızı korumak için lütfen parolanızı değiştirin.", "Lost your password?" => "Parolanızı mı unuttunuz?", "remember" => "hatırla", "Log in" => "Giriş yap", "prev" => "önceki", -"next" => "sonraki" +"next" => "sonraki", +"Updating ownCloud to version %s, this may take a while." => "Owncloud %s versiyonuna güncelleniyor. Biraz zaman alabilir." ); diff --git a/l10n/ar/files_encryption.po b/l10n/ar/files_encryption.po index 1d2de3d76f..a3c4ed8931 100644 --- a/l10n/ar/files_encryption.po +++ b/l10n/ar/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-11-13 00:05+0100\n" -"PO-Revision-Date: 2012-11-12 13:20+0000\n" -"Last-Translator: TYMAH \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Arabic (http://www.transifex.com/projects/p/owncloud/language/ar/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "التشفير" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "استبعد أنواع الملفات التالية من التشفير" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "لا شيء" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "تفعيل التشفير" diff --git a/l10n/bg_BG/files_encryption.po b/l10n/bg_BG/files_encryption.po index c5aca629ed..8e5aeda084 100644 --- a/l10n/bg_BG/files_encryption.po +++ b/l10n/bg_BG/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-10 00:04+0100\n" -"PO-Revision-Date: 2013-01-09 20:51+0000\n" -"Last-Translator: Stefan Ilivanov \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Bulgarian (Bulgaria) (http://www.transifex.com/projects/p/owncloud/language/bg_BG/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: bg_BG\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Криптиране" -#: templates/settings.php:6 -msgid "Enable Encryption" -msgstr "Включване на криптирането" - -#: templates/settings.php:7 -msgid "None" -msgstr "Няма" - -#: templates/settings.php:12 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Изключване на следните файлови типове от криптирането" + +#: templates/settings.php:71 +msgid "None" +msgstr "Няма" diff --git a/l10n/bn_BD/files_encryption.po b/l10n/bn_BD/files_encryption.po index 8c13e55a14..4be08a9e00 100644 --- a/l10n/bn_BD/files_encryption.po +++ b/l10n/bn_BD/files_encryption.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-11 00:05+0100\n" -"PO-Revision-Date: 2013-01-10 10:15+0000\n" -"Last-Translator: Shubhra Paul \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Bengali (Bangladesh) (http://www.transifex.com/projects/p/owncloud/language/bn_BD/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,18 +17,66 @@ msgstr "" "Language: bn_BD\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "সংকেতায়ন" -#: templates/settings.php:6 -msgid "Enable Encryption" -msgstr "সংকেতায়ন সক্রিয় কর" - -#: templates/settings.php:7 -msgid "None" -msgstr "কোনটিই নয়" - -#: templates/settings.php:12 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "সংকেতায়ন থেকে নিম্নোক্ত ধরণসমূহ বাদ দাও" + +#: templates/settings.php:71 +msgid "None" +msgstr "কোনটিই নয়" diff --git a/l10n/ca/files.po b/l10n/ca/files.po index ba79bb72cd..68ecfef29b 100644 --- a/l10n/ca/files.po +++ b/l10n/ca/files.po @@ -7,15 +7,16 @@ # , 2012. # , 2012. # Josep Tomàs , 2012. +# , 2013. # , 2011-2013. # , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 08:39+0000\n" +"Last-Translator: rogerc \n" "Language-Team: Catalan (http://www.transifex.com/projects/p/owncloud/language/ca/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -155,7 +156,7 @@ msgstr "El nóm no és vàlid, '\\', '/', '<', '>', ':', '\"', '|', '?' i '*' no msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "S'està preparant la baixada. Pot trigar una estona si els fitxers són grans." #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/ca/files_encryption.po b/l10n/ca/files_encryption.po index 98571697a6..e76e21e1e5 100644 --- a/l10n/ca/files_encryption.po +++ b/l10n/ca/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-13 18:30+0000\n" -"Last-Translator: rogerc \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Catalan (http://www.transifex.com/projects/p/owncloud/language/ca/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ca\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Encriptatge" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Exclou els tipus de fitxers següents de l'encriptatge" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Cap" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Activa l'encriptatge" diff --git a/l10n/cs_CZ/files_encryption.po b/l10n/cs_CZ/files_encryption.po index 96298cc220..4421784cb4 100644 --- a/l10n/cs_CZ/files_encryption.po +++ b/l10n/cs_CZ/files_encryption.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-06 02:01+0200\n" -"PO-Revision-Date: 2012-09-05 13:37+0000\n" -"Last-Translator: Tomáš Chvátal \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/owncloud/language/cs_CZ/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,18 +19,66 @@ msgstr "" "Language: cs_CZ\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Šifrování" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Při šifrování vynechat následující typy souborů" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Žádné" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Povolit šifrování" diff --git a/l10n/da/files_encryption.po b/l10n/da/files_encryption.po index bd1c986451..14b94d9d7a 100644 --- a/l10n/da/files_encryption.po +++ b/l10n/da/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-14 02:01+0200\n" -"PO-Revision-Date: 2012-09-13 09:42+0000\n" -"Last-Translator: osos \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Danish (http://www.transifex.com/projects/p/owncloud/language/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Kryptering" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Ekskluder følgende filtyper fra kryptering" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ingen" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Aktivér kryptering" diff --git a/l10n/de/files_encryption.po b/l10n/de/files_encryption.po index 2231e6ffdf..ba08625264 100644 --- a/l10n/de/files_encryption.po +++ b/l10n/de/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-10-02 23:16+0200\n" -"PO-Revision-Date: 2012-10-02 09:06+0000\n" -"Last-Translator: Mirodin \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: German (http://www.transifex.com/projects/p/owncloud/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Verschlüsselung" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Die folgenden Dateitypen von der Verschlüsselung ausnehmen" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Keine" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Verschlüsselung aktivieren" diff --git a/l10n/de_DE/files_encryption.po b/l10n/de_DE/files_encryption.po index 52f9f34a77..749067c3bb 100644 --- a/l10n/de_DE/files_encryption.po +++ b/l10n/de_DE/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-10-20 02:02+0200\n" -"PO-Revision-Date: 2012-10-19 21:33+0000\n" -"Last-Translator: Mirodin \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: German (Germany) (http://www.transifex.com/projects/p/owncloud/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Verschlüsselung" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Die folgenden Dateitypen von der Verschlüsselung ausnehmen" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Keine" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Verschlüsselung aktivieren" diff --git a/l10n/el/files.po b/l10n/el/files.po index 607ae91bec..d98fff41fb 100644 --- a/l10n/el/files.po +++ b/l10n/el/files.po @@ -5,6 +5,7 @@ # Translators: # Dimitris M. , 2012. # Efstathios Iosifidis , 2012-2013. +# Efstathios Iosifidis , 2013. # Efstathios Iosifidis , 2012. # Konstantinos Tzanidis , 2012. # Marios Bekatoros <>, 2012. @@ -14,9 +15,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 12:10+0000\n" +"Last-Translator: Efstathios Iosifidis \n" "Language-Team: Greek (http://www.transifex.com/projects/p/owncloud/language/el/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -156,7 +157,7 @@ msgstr "Μη έγκυρο όνομα, '\\', '/', '<', '>', ':', '\"', '|', '?' msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "Η λήψη προετοιμάζεται. Αυτό μπορεί να πάρει ώρα εάν τα αρχεία έχουν μεγάλο μέγεθος." #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/el/files_encryption.po b/l10n/el/files_encryption.po index 6d54cf8abc..2ece2edcaf 100644 --- a/l10n/el/files_encryption.po +++ b/l10n/el/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-24 02:02+0200\n" -"PO-Revision-Date: 2012-08-23 13:34+0000\n" -"Last-Translator: Efstathios Iosifidis \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Greek (http://www.transifex.com/projects/p/owncloud/language/el/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: el\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Κρυπτογράφηση" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Εξαίρεση των παρακάτω τύπων αρχείων από την κρυπτογράφηση" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Καμία" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Ενεργοποίηση Κρυπτογράφησης" diff --git a/l10n/eo/files_encryption.po b/l10n/eo/files_encryption.po index dbcedb1a56..ee8d61876c 100644 --- a/l10n/eo/files_encryption.po +++ b/l10n/eo/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-16 02:04+0200\n" -"PO-Revision-Date: 2012-08-15 19:41+0000\n" -"Last-Translator: Mariano \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Esperanto (http://www.transifex.com/projects/p/owncloud/language/eo/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: eo\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Ĉifrado" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Malinkluzivigi la jenajn dosiertipojn el ĉifrado" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Nenio" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Kapabligi ĉifradon" diff --git a/l10n/es/files_encryption.po b/l10n/es/files_encryption.po index 9b75acf31d..c58884a970 100644 --- a/l10n/es/files_encryption.po +++ b/l10n/es/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-28 02:01+0200\n" -"PO-Revision-Date: 2012-08-27 05:27+0000\n" -"Last-Translator: juanman \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Cifrado" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Excluir del cifrado los siguientes tipos de archivo" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ninguno" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Habilitar cifrado" diff --git a/l10n/es_AR/files_encryption.po b/l10n/es_AR/files_encryption.po index 16b134f329..63c4ec0058 100644 --- a/l10n/es_AR/files_encryption.po +++ b/l10n/es_AR/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-25 02:02+0200\n" -"PO-Revision-Date: 2012-09-24 04:41+0000\n" -"Last-Translator: cjtess \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Spanish (Argentina) (http://www.transifex.com/projects/p/owncloud/language/es_AR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: es_AR\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Encriptación" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Exceptuar de la encriptación los siguientes tipos de archivo" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ninguno" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Habilitar encriptación" diff --git a/l10n/et_EE/files_encryption.po b/l10n/et_EE/files_encryption.po index 8a0593fa33..eb1004d7be 100644 --- a/l10n/et_EE/files_encryption.po +++ b/l10n/et_EE/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-19 02:02+0200\n" -"PO-Revision-Date: 2012-08-18 06:39+0000\n" -"Last-Translator: Rivo Zängov \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Estonian (Estonia) (http://www.transifex.com/projects/p/owncloud/language/et_EE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: et_EE\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Krüpteerimine" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Järgnevaid failitüüpe ära krüpteeri" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Pole" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Luba krüpteerimine" diff --git a/l10n/eu/files_encryption.po b/l10n/eu/files_encryption.po index cd97e58a49..deacd189bf 100644 --- a/l10n/eu/files_encryption.po +++ b/l10n/eu/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-28 02:01+0200\n" -"PO-Revision-Date: 2012-08-27 09:08+0000\n" -"Last-Translator: asieriko \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Basque (http://www.transifex.com/projects/p/owncloud/language/eu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: eu\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Enkriptazioa" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Ez enkriptatu hurrengo fitxategi motak" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Bat ere ez" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Gaitu enkriptazioa" diff --git a/l10n/fa/core.po b/l10n/fa/core.po index 2e9ba76047..363c28a30a 100644 --- a/l10n/fa/core.po +++ b/l10n/fa/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:03+0000\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 08:21+0000\n" "Last-Translator: I Robot \n" "Language-Team: Persian (http://www.transifex.com/projects/p/owncloud/language/fa/)\n" "MIME-Version: 1.0\n" @@ -84,55 +84,55 @@ msgstr "" msgid "Settings" msgstr "تنظیمات" -#: js/js.js:711 +#: js/js.js:706 msgid "seconds ago" msgstr "ثانیه‌ها پیش" -#: js/js.js:712 +#: js/js.js:707 msgid "1 minute ago" msgstr "1 دقیقه پیش" -#: js/js.js:713 +#: js/js.js:708 msgid "{minutes} minutes ago" msgstr "" -#: js/js.js:714 +#: js/js.js:709 msgid "1 hour ago" msgstr "" -#: js/js.js:715 +#: js/js.js:710 msgid "{hours} hours ago" msgstr "" -#: js/js.js:716 +#: js/js.js:711 msgid "today" msgstr "امروز" -#: js/js.js:717 +#: js/js.js:712 msgid "yesterday" msgstr "دیروز" -#: js/js.js:718 +#: js/js.js:713 msgid "{days} days ago" msgstr "" -#: js/js.js:719 +#: js/js.js:714 msgid "last month" msgstr "ماه قبل" -#: js/js.js:720 +#: js/js.js:715 msgid "{months} months ago" msgstr "" -#: js/js.js:721 +#: js/js.js:716 msgid "months ago" msgstr "ماه‌های قبل" -#: js/js.js:722 +#: js/js.js:717 msgid "last year" msgstr "سال قبل" -#: js/js.js:723 +#: js/js.js:718 msgid "years ago" msgstr "سال‌های قبل" @@ -245,7 +245,7 @@ msgstr "" #: js/share.js:296 msgid "Unshare" -msgstr "" +msgstr "لغو اشتراک" #: js/share.js:308 msgid "can edit" @@ -442,83 +442,83 @@ msgstr "هاست پایگاه داده" msgid "Finish setup" msgstr "اتمام نصب" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Sunday" msgstr "یکشنبه" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Monday" msgstr "دوشنبه" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Tuesday" msgstr "سه شنبه" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Wednesday" msgstr "چهارشنبه" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Thursday" msgstr "پنجشنبه" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Friday" msgstr "جمعه" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Saturday" msgstr "شنبه" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "January" msgstr "ژانویه" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "February" msgstr "فبریه" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "March" msgstr "مارس" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "April" msgstr "آوریل" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "May" msgstr "می" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "June" msgstr "ژوئن" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "July" msgstr "جولای" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "August" msgstr "آگوست" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "September" msgstr "سپتامبر" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "October" msgstr "اکتبر" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "November" msgstr "نوامبر" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "December" msgstr "دسامبر" -#: templates/layout.guest.php:42 +#: templates/layout.guest.php:41 msgid "web services under your control" msgstr "سرویس وب تحت کنترل شما" diff --git a/l10n/fa/files.po b/l10n/fa/files.po index 73ae7c1ed1..287637e339 100644 --- a/l10n/fa/files.po +++ b/l10n/fa/files.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 08:21+0000\n" "Last-Translator: I Robot \n" "Language-Team: Persian (http://www.transifex.com/projects/p/owncloud/language/fa/)\n" "MIME-Version: 1.0\n" @@ -88,7 +88,7 @@ msgstr "فایل ها" #: js/fileactions.js:117 templates/index.php:82 templates/index.php:83 msgid "Unshare" -msgstr "" +msgstr "لغو اشتراک" #: js/fileactions.js:119 templates/index.php:88 templates/index.php:89 msgid "Delete" diff --git a/l10n/fa/files_encryption.po b/l10n/fa/files_encryption.po index 74f153d436..b5ac04c90a 100644 --- a/l10n/fa/files_encryption.po +++ b/l10n/fa/files_encryption.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-11-15 00:02+0100\n" -"PO-Revision-Date: 2012-11-14 08:31+0000\n" -"Last-Translator: basir \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Persian (http://www.transifex.com/projects/p/owncloud/language/fa/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,18 +19,66 @@ msgstr "" "Language: fa\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "رمزگذاری" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "نادیده گرفتن فایل های زیر برای رمز گذاری" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "هیچ‌کدام" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "فعال کردن رمزگذاری" diff --git a/l10n/fi_FI/files_encryption.po b/l10n/fi_FI/files_encryption.po index 89ad916e38..5f63593759 100644 --- a/l10n/fi_FI/files_encryption.po +++ b/l10n/fi_FI/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-17 00:44+0200\n" -"PO-Revision-Date: 2012-08-16 10:56+0000\n" -"Last-Translator: Jiri Grönroos \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Finnish (Finland) (http://www.transifex.com/projects/p/owncloud/language/fi_FI/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fi_FI\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Salaus" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Jätä seuraavat tiedostotyypit salaamatta" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ei mitään" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Käytä salausta" diff --git a/l10n/fr/files_encryption.po b/l10n/fr/files_encryption.po index cbad09601f..8c8754a7a8 100644 --- a/l10n/fr/files_encryption.po +++ b/l10n/fr/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-15 02:02+0200\n" -"PO-Revision-Date: 2012-08-14 16:26+0000\n" -"Last-Translator: Romain DEP. \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Chiffrement" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Ne pas chiffrer les fichiers dont les types sont les suivants" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Aucun" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Activer le chiffrement" diff --git a/l10n/gl/files_encryption.po b/l10n/gl/files_encryption.po index 367cd2cd06..ba0a8e899d 100644 --- a/l10n/gl/files_encryption.po +++ b/l10n/gl/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-11-21 00:01+0100\n" -"PO-Revision-Date: 2012-11-20 22:19+0000\n" -"Last-Translator: Miguel Branco \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Galician (http://www.transifex.com/projects/p/owncloud/language/gl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: gl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Cifrado" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Excluír os seguintes tipos de ficheiro do cifrado" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Nada" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Activar o cifrado" diff --git a/l10n/gl/lib.po b/l10n/gl/lib.po index 21150b035b..c6fc161311 100644 --- a/l10n/gl/lib.po +++ b/l10n/gl/lib.po @@ -5,14 +5,14 @@ # Translators: # , 2012. # Miguel Branco , 2012. -# Xosé M. Lamas , 2012. +# Xosé M. Lamas , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 06:11+0000\n" +"Last-Translator: Xosé M. Lamas \n" "Language-Team: Galician (http://www.transifex.com/projects/p/owncloud/language/gl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -60,9 +60,9 @@ msgstr "Volver aos ficheiros" msgid "Selected files too large to generate zip file." msgstr "Os ficheiros seleccionados son demasiado grandes como para xerar un ficheiro zip." -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "non puido ser determinado" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/he/files_encryption.po b/l10n/he/files_encryption.po index 860989631c..cd62f06daf 100644 --- a/l10n/he/files_encryption.po +++ b/l10n/he/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-12-27 00:04+0100\n" -"PO-Revision-Date: 2012-12-26 17:21+0000\n" -"Last-Translator: Gilad Naaman \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Hebrew (http://www.transifex.com/projects/p/owncloud/language/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: he\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "הצפנה" -#: templates/settings.php:6 -msgid "Enable Encryption" -msgstr "הפעל הצפנה" - -#: templates/settings.php:7 -msgid "None" -msgstr "כלום" - -#: templates/settings.php:12 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "הוצא את סוגי הקבצים הבאים מהצפנה" + +#: templates/settings.php:71 +msgid "None" +msgstr "כלום" diff --git a/l10n/hi/files_encryption.po b/l10n/hi/files_encryption.po index e6ff91a68b..83154bdbcb 100644 --- a/l10n/hi/files_encryption.po +++ b/l10n/hi/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-29 02:01+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Hindi (http://www.transifex.com/projects/p/owncloud/language/hi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: hi\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/hr/files_encryption.po b/l10n/hr/files_encryption.po index d2734fd9fd..d284b96247 100644 --- a/l10n/hr/files_encryption.po +++ b/l10n/hr/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Croatian (http://www.transifex.com/projects/p/owncloud/language/hr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: hr\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/hu_HU/files_encryption.po b/l10n/hu_HU/files_encryption.po index 896e96e2c7..4aea6abf21 100644 --- a/l10n/hu_HU/files_encryption.po +++ b/l10n/hu_HU/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-12-31 00:04+0100\n" -"PO-Revision-Date: 2012-12-30 17:43+0000\n" -"Last-Translator: Laszlo Tornoci \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: hu_HU\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Titkosítás" -#: templates/settings.php:6 -msgid "Enable Encryption" -msgstr "A titkosítás engedélyezése" - -#: templates/settings.php:7 -msgid "None" -msgstr "Egyik sem" - -#: templates/settings.php:12 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "A következő fájltípusok kizárása a titkosításból" + +#: templates/settings.php:71 +msgid "None" +msgstr "Egyik sem" diff --git a/l10n/ia/files_encryption.po b/l10n/ia/files_encryption.po index 8b85b14f5c..bd7a38a6b1 100644 --- a/l10n/ia/files_encryption.po +++ b/l10n/ia/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Interlingua (http://www.transifex.com/projects/p/owncloud/language/ia/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ia\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/id/files_encryption.po b/l10n/id/files_encryption.po index 5ab924354c..d6d66e61e0 100644 --- a/l10n/id/files_encryption.po +++ b/l10n/id/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-10-21 02:03+0200\n" -"PO-Revision-Date: 2012-10-20 23:08+0000\n" -"Last-Translator: elmakong \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/owncloud/language/id/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: id\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "enkripsi" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "pengecualian untuk tipe file berikut dari enkripsi" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "tidak ada" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "aktifkan enkripsi" diff --git a/l10n/is/files_encryption.po b/l10n/is/files_encryption.po index 3dfd91e61a..b46b5ff3c1 100644 --- a/l10n/is/files_encryption.po +++ b/l10n/is/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-12-31 00:04+0100\n" -"PO-Revision-Date: 2012-12-30 19:56+0000\n" -"Last-Translator: sveinn \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Icelandic (http://www.transifex.com/projects/p/owncloud/language/is/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: is\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Dulkóðun" -#: templates/settings.php:6 -msgid "Enable Encryption" -msgstr "Virkja dulkóðun" - -#: templates/settings.php:7 -msgid "None" -msgstr "Ekkert" - -#: templates/settings.php:12 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Undanskilja eftirfarandi skráartegundir frá dulkóðun" + +#: templates/settings.php:71 +msgid "None" +msgstr "Ekkert" diff --git a/l10n/it/files_encryption.po b/l10n/it/files_encryption.po index 573a32a14a..06ffe73b73 100644 --- a/l10n/it/files_encryption.po +++ b/l10n/it/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-15 02:02+0200\n" -"PO-Revision-Date: 2012-08-14 11:49+0000\n" -"Last-Translator: Vincenzo Reale \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Cifratura" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Escludi i seguenti tipi di file dalla cifratura" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Nessuna" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Abilita cifratura" diff --git a/l10n/ja_JP/files.po b/l10n/ja_JP/files.po index 9ec5741e01..d94cd87e30 100644 --- a/l10n/ja_JP/files.po +++ b/l10n/ja_JP/files.po @@ -11,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 00:25+0000\n" +"Last-Translator: Daisuke Deguchi \n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -153,7 +153,7 @@ msgstr "無効な名前、'\\', '/', '<', '>', ':', '\"', '|', '?', '*' は使 msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "ダウンロードの準備中です。ファイルサイズが大きい場合は少し時間がかかるかもしれません。" #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/ja_JP/files_encryption.po b/l10n/ja_JP/files_encryption.po index c9941a81c9..99e1f305cb 100644 --- a/l10n/ja_JP/files_encryption.po +++ b/l10n/ja_JP/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-16 02:04+0200\n" -"PO-Revision-Date: 2012-08-15 02:43+0000\n" -"Last-Translator: Daisuke Deguchi \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ja_JP\n" -"Plural-Forms: nplurals=1; plural=0\n" +"Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "暗号化" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "暗号化から除外するファイルタイプ" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "なし" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "暗号化を有効にする" diff --git a/l10n/ka_GE/files_encryption.po b/l10n/ka_GE/files_encryption.po index 3cdf3ae4e9..f0cc786850 100644 --- a/l10n/ka_GE/files_encryption.po +++ b/l10n/ka_GE/files_encryption.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-10-22 02:02+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Georgian (Georgia) (http://www.transifex.com/projects/p/owncloud/language/ka_GE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,18 +17,66 @@ msgstr "" "Language: ka_GE\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/ko/files_encryption.po b/l10n/ko/files_encryption.po index 7317bd55f1..441ba8cec4 100644 --- a/l10n/ko/files_encryption.po +++ b/l10n/ko/files_encryption.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-12-10 00:11+0100\n" -"PO-Revision-Date: 2012-12-09 06:13+0000\n" -"Last-Translator: Shinjo Park \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Korean (http://www.transifex.com/projects/p/owncloud/language/ko/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,18 +19,66 @@ msgstr "" "Language: ko\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "암호화" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "다음 파일 형식은 암호화하지 않음" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "없음" - -#: templates/settings.php:12 -msgid "Enable Encryption" -msgstr "암호화 사용" diff --git a/l10n/ku_IQ/files_encryption.po b/l10n/ku_IQ/files_encryption.po index ebb1c84437..d372d58b03 100644 --- a/l10n/ku_IQ/files_encryption.po +++ b/l10n/ku_IQ/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-10-08 02:02+0200\n" -"PO-Revision-Date: 2012-10-07 00:06+0000\n" -"Last-Translator: Hozha Koyi \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Kurdish (Iraq) (http://www.transifex.com/projects/p/owncloud/language/ku_IQ/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: ku_IQ\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "نهێنیکردن" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "به‌ربه‌ست کردنی ئه‌م جۆره‌ په‌ڕگانه له‌ نهێنیکردن" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "هیچ" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "چالاکردنی نهێنیکردن" diff --git a/l10n/lb/files_encryption.po b/l10n/lb/files_encryption.po index 5446d2366b..f88e884164 100644 --- a/l10n/lb/files_encryption.po +++ b/l10n/lb/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Luxembourgish (http://www.transifex.com/projects/p/owncloud/language/lb/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: lb\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/lt_LT/files_encryption.po b/l10n/lt_LT/files_encryption.po index 41529366d3..152f3677f8 100644 --- a/l10n/lt_LT/files_encryption.po +++ b/l10n/lt_LT/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-23 02:03+0200\n" -"PO-Revision-Date: 2012-08-22 12:29+0000\n" -"Last-Translator: Dr. ROX \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Lithuanian (Lithuania) (http://www.transifex.com/projects/p/owncloud/language/lt_LT/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: lt_LT\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Šifravimas" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Nešifruoti pasirinkto tipo failų" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Nieko" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Įjungti šifravimą" diff --git a/l10n/lv/files_encryption.po b/l10n/lv/files_encryption.po index 6b2dc7673d..9ceadebe30 100644 --- a/l10n/lv/files_encryption.po +++ b/l10n/lv/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Latvian (http://www.transifex.com/projects/p/owncloud/language/lv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: lv\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/mk/files_encryption.po b/l10n/mk/files_encryption.po index 2b4f5dfb57..b34192fc86 100644 --- a/l10n/mk/files_encryption.po +++ b/l10n/mk/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-12-18 00:13+0100\n" -"PO-Revision-Date: 2012-12-17 13:14+0000\n" -"Last-Translator: Georgi Stanojevski \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Macedonian (http://www.transifex.com/projects/p/owncloud/language/mk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: mk\n" "Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Енкрипција" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Исклучи ги следните типови на датотеки од енкрипција" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ништо" - -#: templates/settings.php:12 -msgid "Enable Encryption" -msgstr "Овозможи енкрипција" diff --git a/l10n/ms_MY/files_encryption.po b/l10n/ms_MY/files_encryption.po index 33de1d365d..65777823e5 100644 --- a/l10n/ms_MY/files_encryption.po +++ b/l10n/ms_MY/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Malay (Malaysia) (http://www.transifex.com/projects/p/owncloud/language/ms_MY/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ms_MY\n" -"Plural-Forms: nplurals=1; plural=0\n" +"Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/nb_NO/files_encryption.po b/l10n/nb_NO/files_encryption.po index a74d1bacc7..5e2f1a4cf9 100644 --- a/l10n/nb_NO/files_encryption.po +++ b/l10n/nb_NO/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-24 02:02+0200\n" -"PO-Revision-Date: 2012-08-23 17:13+0000\n" -"Last-Translator: Arvid Nornes \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Norwegian Bokmål (Norway) (http://www.transifex.com/projects/p/owncloud/language/nb_NO/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nb_NO\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Kryptering" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Ekskluder følgende filer fra kryptering" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ingen" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Slå på kryptering" diff --git a/l10n/nl/files_encryption.po b/l10n/nl/files_encryption.po index bd80bdcae7..b1ef07dc13 100644 --- a/l10n/nl/files_encryption.po +++ b/l10n/nl/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-25 02:04+0200\n" -"PO-Revision-Date: 2012-08-24 19:11+0000\n" -"Last-Translator: Richard Bos \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Dutch (http://www.transifex.com/projects/p/owncloud/language/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Versleuteling" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Versleutel de volgende bestand types niet" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Geen" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Zet versleuteling aan" diff --git a/l10n/nn_NO/files_encryption.po b/l10n/nn_NO/files_encryption.po index 8ad39e5cbf..f821638fbc 100644 --- a/l10n/nn_NO/files_encryption.po +++ b/l10n/nn_NO/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Norwegian Nynorsk (Norway) (http://www.transifex.com/projects/p/owncloud/language/nn_NO/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nn_NO\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/oc/files_encryption.po b/l10n/oc/files_encryption.po index d6e0c7a83b..91f6f906aa 100644 --- a/l10n/oc/files_encryption.po +++ b/l10n/oc/files_encryption.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-08 02:01+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Occitan (post 1500) (http://www.transifex.com/projects/p/owncloud/language/oc/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,18 +17,66 @@ msgstr "" "Language: oc\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/pl/files_encryption.po b/l10n/pl/files_encryption.po index fbb12dbe1f..21fa364ff1 100644 --- a/l10n/pl/files_encryption.po +++ b/l10n/pl/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-13 12:15+0000\n" -"Last-Translator: Cyryl Sochacki <>\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Polish (http://www.transifex.com/projects/p/owncloud/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Szyfrowanie" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Wyłącz następujące typy plików z szyfrowania" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Brak" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Włącz szyfrowanie" diff --git a/l10n/pl_PL/files_encryption.po b/l10n/pl_PL/files_encryption.po index 6512705ecb..ce8f0779ca 100644 --- a/l10n/pl_PL/files_encryption.po +++ b/l10n/pl_PL/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-31 02:02+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Polish (Poland) (http://www.transifex.com/projects/p/owncloud/language/pl_PL/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl_PL\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/pt_BR/files_encryption.po b/l10n/pt_BR/files_encryption.po index 250fed658f..ee24c51910 100644 --- a/l10n/pt_BR/files_encryption.po +++ b/l10n/pt_BR/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-24 02:01+0200\n" -"PO-Revision-Date: 2012-09-23 16:57+0000\n" -"Last-Translator: sedir \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/owncloud/language/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Criptografia" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Excluir os seguintes tipos de arquivo da criptografia" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Nenhuma" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Habilitar Criptografia" diff --git a/l10n/pt_PT/files.po b/l10n/pt_PT/files.po index 8ea6fe5d6e..1ba8520b85 100644 --- a/l10n/pt_PT/files.po +++ b/l10n/pt_PT/files.po @@ -4,6 +4,7 @@ # # Translators: # , 2012-2013. +# Daniel Pinto , 2013. # Duarte Velez Grilo , 2012. # , 2012. # Helder Meneses , 2012. @@ -12,9 +13,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 12:23+0000\n" +"Last-Translator: Mouxy \n" "Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/owncloud/language/pt_PT/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -154,7 +155,7 @@ msgstr "Nome Inválido, os caracteres '\\', '/', '<', '>', ':', '\"', '|', '?' e msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "O seu download está a ser preparado. Este processo pode demorar algum tempo se os ficheiros forem grandes." #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/pt_PT/files_encryption.po b/l10n/pt_PT/files_encryption.po index 803037caf4..08eeb3d7e7 100644 --- a/l10n/pt_PT/files_encryption.po +++ b/l10n/pt_PT/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-27 02:01+0200\n" -"PO-Revision-Date: 2012-09-26 13:24+0000\n" -"Last-Translator: Duarte Velez Grilo \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/owncloud/language/pt_PT/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: pt_PT\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Encriptação" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Excluir da encriptação os seguintes tipo de ficheiros" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Nenhum" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Activar Encriptação" diff --git a/l10n/ro/files_encryption.po b/l10n/ro/files_encryption.po index 2c3a3ed30b..701aea30fb 100644 --- a/l10n/ro/files_encryption.po +++ b/l10n/ro/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-19 02:02+0200\n" -"PO-Revision-Date: 2012-09-18 11:31+0000\n" -"Last-Translator: g.ciprian \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Romanian (http://www.transifex.com/projects/p/owncloud/language/ro/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: ro\n" "Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Încriptare" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Exclude următoarele tipuri de fișiere de la încriptare" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Niciuna" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Activare încriptare" diff --git a/l10n/ru/files_encryption.po b/l10n/ru/files_encryption.po index 5ae5f48522..9a2315aa14 100644 --- a/l10n/ru/files_encryption.po +++ b/l10n/ru/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-25 02:04+0200\n" -"PO-Revision-Date: 2012-08-24 07:47+0000\n" -"Last-Translator: Denis \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Russian (http://www.transifex.com/projects/p/owncloud/language/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ru\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Шифрование" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Исключить шифрование следующих типов файлов" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ничего" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Включить шифрование" diff --git a/l10n/ru_RU/files_encryption.po b/l10n/ru_RU/files_encryption.po index 11a6170114..b27f0a2def 100644 --- a/l10n/ru_RU/files_encryption.po +++ b/l10n/ru_RU/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-20 02:05+0200\n" -"PO-Revision-Date: 2012-09-19 12:14+0000\n" -"Last-Translator: AnnaSch \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/owncloud/language/ru_RU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: ru_RU\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Шифрование" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Исключите следующие типы файлов из шифрования" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ни один" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Включить шифрование" diff --git a/l10n/si_LK/files_encryption.po b/l10n/si_LK/files_encryption.po index 7e40f2c3ea..8f8475ed59 100644 --- a/l10n/si_LK/files_encryption.po +++ b/l10n/si_LK/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-10-20 02:02+0200\n" -"PO-Revision-Date: 2012-10-19 11:00+0000\n" -"Last-Translator: Anushke Guneratne \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Sinhala (Sri Lanka) (http://www.transifex.com/projects/p/owncloud/language/si_LK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: si_LK\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "ගුප්ත කේතනය" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "මෙම ගොනු වර්ග ගුප්ත කේතනය කිරීමෙන් බැහැරව තබන්න" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "කිසිවක් නැත" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "ගුප්ත කේතනය සක්‍රිය කරන්න" diff --git a/l10n/sk_SK/files_encryption.po b/l10n/sk_SK/files_encryption.po index a698624cb5..813c05deb3 100644 --- a/l10n/sk_SK/files_encryption.po +++ b/l10n/sk_SK/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-06 02:01+0200\n" -"PO-Revision-Date: 2012-09-05 17:32+0000\n" -"Last-Translator: intense \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: sk_SK\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Šifrovanie" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Vynechať nasledujúce súbory pri šifrovaní" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Žiadne" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Zapnúť šifrovanie" diff --git a/l10n/sl/files_encryption.po b/l10n/sl/files_encryption.po index ee5f5c6ec0..934903b3bc 100644 --- a/l10n/sl/files_encryption.po +++ b/l10n/sl/files_encryption.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-10-23 02:02+0200\n" -"PO-Revision-Date: 2012-10-22 16:57+0000\n" -"Last-Translator: mateju <>\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Slovenian (http://www.transifex.com/projects/p/owncloud/language/sl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,18 +19,66 @@ msgstr "" "Language: sl\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Šifriranje" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Navedene vrste datotek naj ne bodo šifrirane" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Brez" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Omogoči šifriranje" diff --git a/l10n/sr/files_encryption.po b/l10n/sr/files_encryption.po index a0a21dd2c8..7765fc06e6 100644 --- a/l10n/sr/files_encryption.po +++ b/l10n/sr/files_encryption.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-12-05 00:04+0100\n" -"PO-Revision-Date: 2012-12-04 15:06+0000\n" -"Last-Translator: Kostic \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Serbian (http://www.transifex.com/projects/p/owncloud/language/sr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,18 +19,66 @@ msgstr "" "Language: sr\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Шифровање" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Не шифруј следеће типове датотека" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ништа" - -#: templates/settings.php:12 -msgid "Enable Encryption" -msgstr "Омогући шифровање" diff --git a/l10n/sr@latin/files_encryption.po b/l10n/sr@latin/files_encryption.po index c6f3f5b636..39f12cfb59 100644 --- a/l10n/sr@latin/files_encryption.po +++ b/l10n/sr@latin/files_encryption.po @@ -7,28 +7,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Serbian (Latin) (http://www.transifex.com/projects/p/owncloud/language/sr@latin/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sr@latin\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/sv/files.po b/l10n/sv/files.po index 9be1edb50f..4dc201683e 100644 --- a/l10n/sv/files.po +++ b/l10n/sv/files.po @@ -13,9 +13,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 14:36+0000\n" +"Last-Translator: Magnus Höglund \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -31,16 +31,16 @@ msgstr "Ladda upp" #: ajax/move.php:17 #, php-format msgid "Could not move %s - File with this name already exists" -msgstr "" +msgstr "Kunde inte flytta %s - Det finns redan en fil med detta namn" #: ajax/move.php:24 #, php-format msgid "Could not move %s" -msgstr "" +msgstr "Kan inte flytta %s" #: ajax/rename.php:19 msgid "Unable to rename file" -msgstr "" +msgstr "Kan inte byta namn på filen" #: ajax/upload.php:20 msgid "No file was uploaded. Unknown error" @@ -155,7 +155,7 @@ msgstr "Ogiltigt namn, '\\', '/', '<', '>', ':', '\"', '|', '?' och '*' är inte msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "Din nedladdning förbereds. Det kan ta tid om det är stora filer." #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/sv/files_encryption.po b/l10n/sv/files_encryption.po index 4216506948..946f272acc 100644 --- a/l10n/sv/files_encryption.po +++ b/l10n/sv/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-13 23:12+0200\n" -"PO-Revision-Date: 2012-08-13 10:20+0000\n" -"Last-Translator: Magnus Höglund \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sv\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Kryptering" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Exkludera följande filtyper från kryptering" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Ingen" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Aktivera kryptering" diff --git a/l10n/sv/lib.po b/l10n/sv/lib.po index e7015f915b..3fea987f13 100644 --- a/l10n/sv/lib.po +++ b/l10n/sv/lib.po @@ -3,15 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# Magnus Höglund , 2012. +# Magnus Höglund , 2012-2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 14:32+0000\n" +"Last-Translator: Magnus Höglund \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -59,9 +59,9 @@ msgstr "Tillbaka till Filer" msgid "Selected files too large to generate zip file." msgstr "Valda filer är för stora för att skapa zip-fil." -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "kunde inte bestämmas" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/sv/user_ldap.po b/l10n/sv/user_ldap.po index a86fd7f318..4455df0fb2 100644 --- a/l10n/sv/user_ldap.po +++ b/l10n/sv/user_ldap.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# Magnus Höglund , 2012. +# Magnus Höglund , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-16 00:19+0100\n" -"PO-Revision-Date: 2013-01-15 23:20+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 15:10+0000\n" +"Last-Translator: Magnus Höglund \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -29,7 +29,7 @@ msgstr "Varning: Apps user_ldap och user_webdavauth är inkompatibla. Ov msgid "" "Warning: The PHP LDAP module is not installed, the backend will not " "work. Please ask your system administrator to install it." -msgstr "" +msgstr "Varning: PHP LDAP - modulen är inte installerad, serversidan kommer inte att fungera. Kontakta din systemadministratör för installation." #: templates/settings.php:15 msgid "Host" @@ -46,7 +46,7 @@ msgstr "Start DN" #: templates/settings.php:16 msgid "One Base DN per line" -msgstr "" +msgstr "Ett Start DN per rad" #: templates/settings.php:16 msgid "You can specify Base DN for users and groups in the Advanced tab" @@ -121,7 +121,7 @@ msgstr "Bas för användare i katalogtjänst" #: templates/settings.php:25 msgid "One User Base DN per line" -msgstr "" +msgstr "En Användare start DN per rad" #: templates/settings.php:26 msgid "Base Group Tree" @@ -129,7 +129,7 @@ msgstr "Bas för grupper i katalogtjänst" #: templates/settings.php:26 msgid "One Group Base DN per line" -msgstr "" +msgstr "En Grupp start DN per rad" #: templates/settings.php:27 msgid "Group-Member association" diff --git a/l10n/sv/user_webdavauth.po b/l10n/sv/user_webdavauth.po index f85d57aca3..98475a8bd9 100644 --- a/l10n/sv/user_webdavauth.po +++ b/l10n/sv/user_webdavauth.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# Magnus Höglund , 2012. +# Magnus Höglund , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:04+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 15:25+0000\n" +"Last-Translator: Magnus Höglund \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,7 +20,7 @@ msgstr "" #: templates/settings.php:3 msgid "WebDAV Authentication" -msgstr "" +msgstr "WebDAV Autentisering" #: templates/settings.php:4 msgid "URL: http://" @@ -31,4 +31,4 @@ msgid "" "ownCloud will send the user credentials to this URL. This plugin checks the " "response and will interpret the HTTP statuscodes 401 and 403 as invalid " "credentials, and all other responses as valid credentials." -msgstr "" +msgstr "ownCloud kommer skicka användaruppgifterna till denna URL. Denna plugin kontrollerar svaret och tolkar HTTP-statuskoderna 401 och 403 som felaktiga uppgifter, och alla andra svar som giltiga uppgifter." diff --git a/l10n/ta_LK/files_encryption.po b/l10n/ta_LK/files_encryption.po index 2eee3be9df..82cfd11914 100644 --- a/l10n/ta_LK/files_encryption.po +++ b/l10n/ta_LK/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-11-18 00:01+0100\n" -"PO-Revision-Date: 2012-11-17 05:33+0000\n" -"Last-Translator: suganthi \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Tamil (Sri-Lanka) (http://www.transifex.com/projects/p/owncloud/language/ta_LK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: ta_LK\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "மறைக்குறியீடு" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "மறைக்குறியாக்கலில் பின்வரும் கோப்பு வகைகளை நீக்கவும்" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "ஒன்றுமில்லை" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "மறைக்குறியாக்கலை இயலுமைப்படுத்துக" diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot index bc536ce226..753402f214 100644 --- a/l10n/templates/core.pot +++ b/l10n/templates/core.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -441,83 +441,83 @@ msgstr "" msgid "Finish setup" msgstr "" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Sunday" msgstr "" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Monday" msgstr "" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Tuesday" msgstr "" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Wednesday" msgstr "" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Thursday" msgstr "" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Friday" msgstr "" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Saturday" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "January" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "February" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "March" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "April" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "May" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "June" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "July" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "August" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "September" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "October" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "November" msgstr "" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "December" msgstr "" -#: templates/layout.guest.php:42 +#: templates/layout.guest.php:41 msgid "web services under your control" msgstr "" diff --git a/l10n/templates/files.pot b/l10n/templates/files.pot index 8a06303e8f..535c86fc44 100644 --- a/l10n/templates/files.pot +++ b/l10n/templates/files.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_encryption.pot b/l10n/templates/files_encryption.pot index c35af47ba7..b0174b4df0 100644 --- a/l10n/templates/files_encryption.pot +++ b/l10n/templates/files_encryption.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,18 +17,66 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to " +"complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it " +"back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "" -#: templates/settings.php:6 -msgid "Enable Encryption" -msgstr "" - -#: templates/settings.php:7 -msgid "None" -msgstr "" - -#: templates/settings.php:12 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "" + +#: templates/settings.php:71 +msgid "None" +msgstr "" diff --git a/l10n/templates/files_external.pot b/l10n/templates/files_external.pot index 2c56292b24..0b141e370d 100644 --- a/l10n/templates/files_external.pot +++ b/l10n/templates/files_external.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_sharing.pot b/l10n/templates/files_sharing.pot index 0a5d77fa0b..5291a185d3 100644 --- a/l10n/templates/files_sharing.pot +++ b/l10n/templates/files_sharing.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_versions.pot b/l10n/templates/files_versions.pot index dece38d430..0fd775d551 100644 --- a/l10n/templates/files_versions.pot +++ b/l10n/templates/files_versions.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/lib.pot b/l10n/templates/lib.pot index ac3a56175f..d9c2c44387 100644 --- a/l10n/templates/lib.pot +++ b/l10n/templates/lib.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot index d76adc8562..89ce02d393 100644 --- a/l10n/templates/settings.pot +++ b/l10n/templates/settings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/user_ldap.pot b/l10n/templates/user_ldap.pot index 85414ccc8d..03c8c9e73c 100644 --- a/l10n/templates/user_ldap.pot +++ b/l10n/templates/user_ldap.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/user_webdavauth.pot b/l10n/templates/user_webdavauth.pot index 871470c64d..63897bf14b 100644 --- a/l10n/templates/user_webdavauth.pot +++ b/l10n/templates/user_webdavauth.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/th_TH/core.po b/l10n/th_TH/core.po index 895eb8a344..e9fe1ca9c9 100644 --- a/l10n/th_TH/core.po +++ b/l10n/th_TH/core.po @@ -3,15 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# AriesAnywhere Anywhere , 2012. +# AriesAnywhere Anywhere , 2012-2013. # AriesAnywhere Anywhere , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:03+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 01:02+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,26 +22,26 @@ msgstr "" #: ajax/share.php:84 #, php-format msgid "User %s shared a file with you" -msgstr "" +msgstr "ผู้ใช้งาน %s ได้แชร์ไฟล์ให้กับคุณ" #: ajax/share.php:86 #, php-format msgid "User %s shared a folder with you" -msgstr "" +msgstr "ผู้ใช้งาน %s ได้แชร์โฟลเดอร์ให้กับคุณ" #: ajax/share.php:88 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" -msgstr "" +msgstr "ผู้ใช้งาน %s ได้แชร์ไฟล์ \"%s\" ให้กับคุณ และคุณสามารถสามารถดาวน์โหลดไฟล์ดังกล่าวได้จากที่นี่: %s" #: ajax/share.php:90 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " "here: %s" -msgstr "" +msgstr "ผู้ใช้งาน %s ได้แชร์โฟลเดอร์ \"%s\" ให้กับคุณ และคุณสามารถดาวน์โหลดโฟลเดอร์ดังกล่าวได้จากที่นี่: %s" #: ajax/vcategories/add.php:26 ajax/vcategories/edit.php:25 msgid "Category type not provided." @@ -85,55 +85,55 @@ msgstr "เกิดข้อผิดพลาดในการลบ %s อ msgid "Settings" msgstr "ตั้งค่า" -#: js/js.js:711 +#: js/js.js:706 msgid "seconds ago" msgstr "วินาที ก่อนหน้านี้" -#: js/js.js:712 +#: js/js.js:707 msgid "1 minute ago" msgstr "1 นาทีก่อนหน้านี้" -#: js/js.js:713 +#: js/js.js:708 msgid "{minutes} minutes ago" msgstr "{minutes} นาทีก่อนหน้านี้" -#: js/js.js:714 +#: js/js.js:709 msgid "1 hour ago" msgstr "1 ชั่วโมงก่อนหน้านี้" -#: js/js.js:715 +#: js/js.js:710 msgid "{hours} hours ago" msgstr "{hours} ชั่วโมงก่อนหน้านี้" -#: js/js.js:716 +#: js/js.js:711 msgid "today" msgstr "วันนี้" -#: js/js.js:717 +#: js/js.js:712 msgid "yesterday" msgstr "เมื่อวานนี้" -#: js/js.js:718 +#: js/js.js:713 msgid "{days} days ago" msgstr "{day} วันก่อนหน้านี้" -#: js/js.js:719 +#: js/js.js:714 msgid "last month" msgstr "เดือนที่แล้ว" -#: js/js.js:720 +#: js/js.js:715 msgid "{months} months ago" msgstr "{months} เดือนก่อนหน้านี้" -#: js/js.js:721 +#: js/js.js:716 msgid "months ago" msgstr "เดือน ที่ผ่านมา" -#: js/js.js:722 +#: js/js.js:717 msgid "last year" msgstr "ปีที่แล้ว" -#: js/js.js:723 +#: js/js.js:718 msgid "years ago" msgstr "ปี ที่ผ่านมา" @@ -214,11 +214,11 @@ msgstr "รหัสผ่าน" #: js/share.js:172 msgid "Email link to person" -msgstr "" +msgstr "ส่งลิงก์ให้ทางอีเมล" #: js/share.js:173 msgid "Send" -msgstr "" +msgstr "ส่ง" #: js/share.js:177 msgid "Set expiration date" @@ -286,11 +286,11 @@ msgstr "เกิดข้อผิดพลาดในการตั้งค #: js/share.js:581 msgid "Sending ..." -msgstr "" +msgstr "กำลังส่ง..." #: js/share.js:592 msgid "Email sent" -msgstr "" +msgstr "ส่งอีเมล์แล้ว" #: lostpassword/controller.php:47 msgid "ownCloud password reset" @@ -443,83 +443,83 @@ msgstr "Database host" msgid "Finish setup" msgstr "ติดตั้งเรียบร้อยแล้ว" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Sunday" msgstr "วันอาทิตย์" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Monday" msgstr "วันจันทร์" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Tuesday" msgstr "วันอังคาร" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Wednesday" msgstr "วันพุธ" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Thursday" msgstr "วันพฤหัสบดี" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Friday" msgstr "วันศุกร์" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Saturday" msgstr "วันเสาร์" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "January" msgstr "มกราคม" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "February" msgstr "กุมภาพันธ์" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "March" msgstr "มีนาคม" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "April" msgstr "เมษายน" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "May" msgstr "พฤษภาคม" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "June" msgstr "มิถุนายน" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "July" msgstr "กรกฏาคม" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "August" msgstr "สิงหาคม" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "September" msgstr "กันยายน" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "October" msgstr "ตุลาคม" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "November" msgstr "พฤศจิกายน" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "December" msgstr "ธันวาคม" -#: templates/layout.guest.php:42 +#: templates/layout.guest.php:41 msgid "web services under your control" msgstr "web services under your control" @@ -564,4 +564,4 @@ msgstr "ถัดไป" #: templates/update.php:3 #, php-format msgid "Updating ownCloud to version %s, this may take a while." -msgstr "" +msgstr "กำลังอัพเดท ownCloud ไปเป็นรุ่น %s, กรุณารอสักครู่" diff --git a/l10n/th_TH/files.po b/l10n/th_TH/files.po index 44f9070ded..691310546f 100644 --- a/l10n/th_TH/files.po +++ b/l10n/th_TH/files.po @@ -3,15 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# AriesAnywhere Anywhere , 2012. +# AriesAnywhere Anywhere , 2012-2013. # AriesAnywhere Anywhere , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 01:13+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -27,16 +27,16 @@ msgstr "อัพโหลด" #: ajax/move.php:17 #, php-format msgid "Could not move %s - File with this name already exists" -msgstr "" +msgstr "ไม่สามารถย้าย %s ได้ - ไฟล์ที่ใช้ชื่อนี้มีอยู่แล้ว" #: ajax/move.php:24 #, php-format msgid "Could not move %s" -msgstr "" +msgstr "ไม่สามารถย้าย %s ได้" #: ajax/rename.php:19 msgid "Unable to rename file" -msgstr "" +msgstr "ไม่สามารถเปลี่ยนชื่อไฟล์ได้" #: ajax/upload.php:20 msgid "No file was uploaded. Unknown error" @@ -75,11 +75,11 @@ msgstr "เขียนข้อมูลลงแผ่นดิสก์ล้ #: ajax/upload.php:57 msgid "Not enough space available" -msgstr "" +msgstr "มีพื้นที่เหลือไม่เพียงพอ" #: ajax/upload.php:91 msgid "Invalid directory." -msgstr "" +msgstr "ไดเร็กทอรี่ไม่ถูกต้อง" #: appinfo/app.php:10 msgid "Files" @@ -135,11 +135,11 @@ msgstr "ลบไฟล์แล้ว {files} ไฟล์" #: js/files.js:48 msgid "'.' is an invalid file name." -msgstr "" +msgstr "'.' เป็นชื่อไฟล์ที่ไม่ถูกต้อง" #: js/files.js:53 msgid "File name cannot be empty." -msgstr "" +msgstr "ชื่อไฟล์ไม่สามารถเว้นว่างได้" #: js/files.js:62 msgid "" @@ -151,7 +151,7 @@ msgstr "ชื่อที่ใช้ไม่ถูกต้อง, '\\', '/', msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "กำลังเตรียมดาวน์โหลดข้อมูล หากไฟล์มีขนาดใหญ่ อาจใช้เวลาสักครู่" #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" @@ -192,7 +192,7 @@ msgstr "URL ไม่สามารถเว้นว่างได้" #: js/files.js:565 msgid "Invalid folder name. Usage of 'Shared' is reserved by Owncloud" -msgstr "" +msgstr "ชื่อโฟลเดอร์ไม่ถูกต้อง การใช้งาน 'แชร์' สงวนไว้สำหรับ Owncloud เท่านั้น" #: js/files.js:775 msgid "{count} files scanned" diff --git a/l10n/th_TH/files_encryption.po b/l10n/th_TH/files_encryption.po index f396eed4da..747fd64f1a 100644 --- a/l10n/th_TH/files_encryption.po +++ b/l10n/th_TH/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-08-15 02:02+0200\n" -"PO-Revision-Date: 2012-08-14 13:12+0000\n" -"Last-Translator: AriesAnywhere Anywhere \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: th_TH\n" -"Plural-Forms: nplurals=1; plural=0\n" +"Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "การเข้ารหัส" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "ไม่ต้องรวมชนิดของไฟล์ดังต่อไปนี้จากการเข้ารหัส" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "ไม่ต้อง" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "เปิดใช้งานการเข้ารหัส" diff --git a/l10n/th_TH/files_external.po b/l10n/th_TH/files_external.po index efca59c6be..6d58bbeaf8 100644 --- a/l10n/th_TH/files_external.po +++ b/l10n/th_TH/files_external.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# AriesAnywhere Anywhere , 2012. +# AriesAnywhere Anywhere , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-12-13 00:17+0100\n" -"PO-Revision-Date: 2012-12-11 23:22+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 00:50+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -46,14 +46,14 @@ msgstr "เกิดข้อผิดพลาดในการกำหนด msgid "" "Warning: \"smbclient\" is not installed. Mounting of CIFS/SMB shares " "is not possible. Please ask your system administrator to install it." -msgstr "" +msgstr "คำเตือน: \"smbclient\" ยังไม่ได้ถูกติดตั้ง. การชี้ CIFS/SMB เพื่อแชร์ข้อมูลไม่สามารถกระทำได้ กรุณาสอบถามข้อมูลเพิ่มเติมจากผู้ดูแลระบบเพื่อติดตั้ง." #: lib/config.php:435 msgid "" "Warning: The FTP support in PHP is not enabled or installed. Mounting" " of FTP shares is not possible. Please ask your system administrator to " "install it." -msgstr "" +msgstr "คำเตือน: การสนับสนุนการใช้งาน FTP ในภาษา PHP ยังไม่ได้ถูกเปิดใช้งานหรือถูกติดตั้ง. การชี้ FTP เพื่อแชร์ข้อมูลไม่สามารถดำเนินการได้ กรุณาสอบถามข้อมูลเพิ่มเติมจากผู้ดูแลระบบเพื่อติดตั้ง" #: templates/settings.php:3 msgid "External Storage" @@ -100,7 +100,7 @@ msgid "Users" msgstr "ผู้ใช้งาน" #: templates/settings.php:108 templates/settings.php:109 -#: templates/settings.php:149 templates/settings.php:150 +#: templates/settings.php:144 templates/settings.php:145 msgid "Delete" msgstr "ลบ" @@ -112,10 +112,10 @@ msgstr "เปิดให้มีการใช้พื้นที่จั msgid "Allow users to mount their own external storage" msgstr "อนุญาตให้ผู้ใช้งานสามารถชี้ตำแหน่งไปที่พื้นที่จัดเก็บข้อมูลภายนอกของตนเองได้" -#: templates/settings.php:139 +#: templates/settings.php:136 msgid "SSL root certificates" msgstr "ใบรับรองความปลอดภัยด้วยระบบ SSL จาก Root" -#: templates/settings.php:158 +#: templates/settings.php:153 msgid "Import Root Certificate" msgstr "นำเข้าข้อมูลใบรับรองความปลอดภัยจาก Root" diff --git a/l10n/th_TH/lib.po b/l10n/th_TH/lib.po index 71618495c4..ab2e313276 100644 --- a/l10n/th_TH/lib.po +++ b/l10n/th_TH/lib.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# AriesAnywhere Anywhere , 2012. +# AriesAnywhere Anywhere , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 00:44+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -58,9 +58,9 @@ msgstr "กลับไปที่ไฟล์" msgid "Selected files too large to generate zip file." msgstr "ไฟล์ที่เลือกมีขนาดใหญ่เกินกว่าที่จะสร้างเป็นไฟล์ zip" -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "ไม่สามารถกำหนดได้" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/th_TH/settings.po b/l10n/th_TH/settings.po index a024b5901a..9e7676e802 100644 --- a/l10n/th_TH/settings.po +++ b/l10n/th_TH/settings.po @@ -3,16 +3,16 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# AriesAnywhere Anywhere , 2012. +# AriesAnywhere Anywhere , 2012-2013. # AriesAnywhere Anywhere , 2012. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 00:59+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -66,7 +66,7 @@ msgstr "คำร้องขอไม่ถูกต้อง" #: ajax/togglegroups.php:12 msgid "Admins can't remove themself from the admin group" -msgstr "" +msgstr "ผู้ดูแลระบบไม่สามารถลบตัวเองออกจากกลุ่มผู้ดูแลได้" #: ajax/togglegroups.php:28 #, php-format @@ -116,27 +116,27 @@ msgstr "-ลิขสิทธิ์การใ #: templates/help.php:3 msgid "User Documentation" -msgstr "" +msgstr "เอกสารคู่มือการใช้งานสำหรับผู้ใช้งาน" #: templates/help.php:4 msgid "Administrator Documentation" -msgstr "" +msgstr "เอกสารคู่มือการใช้งานสำหรับผู้ดูแลระบบ" #: templates/help.php:6 msgid "Online Documentation" -msgstr "" +msgstr "เอกสารคู่มือการใช้งานออนไลน์" #: templates/help.php:7 msgid "Forum" -msgstr "" +msgstr "กระดานสนทนา" #: templates/help.php:9 msgid "Bugtracker" -msgstr "" +msgstr "Bugtracker" #: templates/help.php:11 msgid "Commercial Support" -msgstr "" +msgstr "บริการลูกค้าแบบเสียค่าใช้จ่าย" #: templates/personal.php:8 #, php-format @@ -149,15 +149,15 @@ msgstr "ลูกค้า" #: templates/personal.php:13 msgid "Download Desktop Clients" -msgstr "" +msgstr "ดาวน์โหลดโปรแกรมไคลเอนต์สำหรับเครื่องเดสก์ท็อป" #: templates/personal.php:14 msgid "Download Android Client" -msgstr "" +msgstr "ดาวน์โหลดโปรแกรมไคลเอนต์สำหรับแอนดรอยด์" #: templates/personal.php:15 msgid "Download iOS Client" -msgstr "" +msgstr "ดาวน์โหลดโปรแกรมไคลเอนต์สำหรับ iOS" #: templates/personal.php:21 templates/users.php:23 templates/users.php:82 msgid "Password" @@ -209,15 +209,15 @@ msgstr "ช่วยกันแปล" #: templates/personal.php:52 msgid "WebDAV" -msgstr "" +msgstr "WebDAV" #: templates/personal.php:54 msgid "Use this address to connect to your ownCloud in your file manager" -msgstr "" +msgstr "ใช้ที่อยู่นี้เพื่อเชื่อมต่อกับ ownCloud ในโปรแกรมจัดการไฟล์ของคุณ" #: templates/personal.php:63 msgid "Version" -msgstr "" +msgstr "รุ่น" #: templates/personal.php:65 msgid "" @@ -243,11 +243,11 @@ msgstr "สร้าง" #: templates/users.php:35 msgid "Default Storage" -msgstr "" +msgstr "พื้นที่จำกัดข้อมูลเริ่มต้น" #: templates/users.php:42 templates/users.php:138 msgid "Unlimited" -msgstr "" +msgstr "ไม่จำกัดจำนวน" #: templates/users.php:60 templates/users.php:153 msgid "Other" @@ -259,11 +259,11 @@ msgstr "ผู้ดูแลกลุ่ม" #: templates/users.php:87 msgid "Storage" -msgstr "" +msgstr "พื้นที่จัดเก็บข้อมูล" #: templates/users.php:133 msgid "Default" -msgstr "" +msgstr "ค่าเริ่มต้น" #: templates/users.php:161 msgid "Delete" diff --git a/l10n/th_TH/user_ldap.po b/l10n/th_TH/user_ldap.po index c770828e2a..bb0c9b6441 100644 --- a/l10n/th_TH/user_ldap.po +++ b/l10n/th_TH/user_ldap.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# AriesAnywhere Anywhere , 2012. +# AriesAnywhere Anywhere , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-16 00:19+0100\n" -"PO-Revision-Date: 2013-01-15 23:20+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 01:21+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,13 +23,13 @@ msgid "" "Warning: Apps user_ldap and user_webdavauth are incompatible. You may" " experience unexpected behaviour. Please ask your system administrator to " "disable one of them." -msgstr "" +msgstr "คำเตือน: แอปฯ user_ldap และ user_webdavauth ไม่สามารถใช้งานร่วมกันได้. คุณอาจประสพปัญหาที่ไม่คาดคิดจากเหตุการณ์ดังกล่าว กรุณาติดต่อผู้ดูแลระบบของคุณเพื่อระงับการใช้งานแอปฯ ตัวใดตัวหนึ่งข้างต้น" #: templates/settings.php:11 msgid "" "Warning: The PHP LDAP module is not installed, the backend will not " "work. Please ask your system administrator to install it." -msgstr "" +msgstr "คำเตือน: โมดูล PHP LDAP ยังไม่ได้ถูกติดตั้ง, ระบบด้านหลังจะไม่สามารถทำงานได้ กรุณาติดต่อผู้ดูแลระบบของคุณเพื่อทำการติดตั้งโมดูลดังกล่าว" #: templates/settings.php:15 msgid "Host" @@ -46,7 +46,7 @@ msgstr "DN ฐาน" #: templates/settings.php:16 msgid "One Base DN per line" -msgstr "" +msgstr "หนึ่ง Base DN ต่อบรรทัด" #: templates/settings.php:16 msgid "You can specify Base DN for users and groups in the Advanced tab" @@ -121,7 +121,7 @@ msgstr "รายการผู้ใช้งานหลักแบบ Tree" #: templates/settings.php:25 msgid "One User Base DN per line" -msgstr "" +msgstr "หนึ่ง User Base DN ต่อบรรทัด" #: templates/settings.php:26 msgid "Base Group Tree" @@ -129,7 +129,7 @@ msgstr "รายการกลุ่มหลักแบบ Tree" #: templates/settings.php:26 msgid "One Group Base DN per line" -msgstr "" +msgstr "หนึ่ง Group Base DN ต่อบรรทัด" #: templates/settings.php:27 msgid "Group-Member association" diff --git a/l10n/th_TH/user_webdavauth.po b/l10n/th_TH/user_webdavauth.po index 12c2efcc21..3493831b2c 100644 --- a/l10n/th_TH/user_webdavauth.po +++ b/l10n/th_TH/user_webdavauth.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# AriesAnywhere Anywhere , 2012. +# AriesAnywhere Anywhere , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:04+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 00:54+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,15 +20,15 @@ msgstr "" #: templates/settings.php:3 msgid "WebDAV Authentication" -msgstr "" +msgstr "WebDAV Authentication" #: templates/settings.php:4 msgid "URL: http://" -msgstr "" +msgstr "URL: http://" #: templates/settings.php:6 msgid "" "ownCloud will send the user credentials to this URL. This plugin checks the " "response and will interpret the HTTP statuscodes 401 and 403 as invalid " "credentials, and all other responses as valid credentials." -msgstr "" +msgstr "ownCloud จะส่งข้อมูลการเข้าใช้งานของผู้ใช้งานไปยังที่อยู่ URL ดังกล่าวนี้ ปลั๊กอินดังกล่าวจะทำการตรวจสอบข้อมูลที่โต้ตอบกลับมาและจะทำการแปลรหัส HTTP statuscodes 401 และ 403 ให้เป็นข้อมูลการเข้าใช้งานที่ไม่สามารถใช้งานได้ ส่วนข้อมูลอื่นๆที่เหลือทั้งหมดจะเป็นข้อมูลการเข้าใช้งานที่สามารถใช้งานได้" diff --git a/l10n/tr/core.po b/l10n/tr/core.po index 12efc8d5b5..b35d17c7b5 100644 --- a/l10n/tr/core.po +++ b/l10n/tr/core.po @@ -6,14 +6,15 @@ # Aranel Surion , 2011, 2012. # Caner Başaran , 2012. # , 2012. +# ismail yenigul , 2013. # Necdet Yücel , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:03+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:04+0000\n" +"Last-Translator: ismail yenigül \n" "Language-Team: Turkish (http://www.transifex.com/projects/p/owncloud/language/tr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,26 +25,26 @@ msgstr "" #: ajax/share.php:84 #, php-format msgid "User %s shared a file with you" -msgstr "" +msgstr "%s kullanıcısı sizinle bir dosyayı paylaştı" #: ajax/share.php:86 #, php-format msgid "User %s shared a folder with you" -msgstr "" +msgstr "%s kullanıcısı sizinle bir dizini paylaştı" #: ajax/share.php:88 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" -msgstr "" +msgstr "%s kullanıcısı \"%s\" dosyasını sizinle paylaştı. %s adresinden indirilebilir" #: ajax/share.php:90 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " "here: %s" -msgstr "" +msgstr "%s kullanıcısı \"%s\" dizinini sizinle paylaştı. %s adresinden indirilebilir" #: ajax/vcategories/add.php:26 ajax/vcategories/edit.php:25 msgid "Category type not provided." @@ -67,12 +68,12 @@ msgstr "Nesne türü desteklenmemektedir." #: ajax/vcategories/removeFromFavorites.php:30 #, php-format msgid "%s ID not provided." -msgstr "" +msgstr "%s ID belirtilmedi." #: ajax/vcategories/addToFavorites.php:35 #, php-format msgid "Error adding %s to favorites." -msgstr "" +msgstr "%s favorilere eklenirken hata oluştu" #: ajax/vcategories/delete.php:35 js/oc-vcategories.js:136 msgid "No categories selected for deletion." @@ -81,61 +82,61 @@ msgstr "Silmek için bir kategori seçilmedi" #: ajax/vcategories/removeFromFavorites.php:35 #, php-format msgid "Error removing %s from favorites." -msgstr "" +msgstr "%s favorilere çıkarılırken hata oluştu" #: js/js.js:259 templates/layout.user.php:60 templates/layout.user.php:61 msgid "Settings" msgstr "Ayarlar" -#: js/js.js:711 +#: js/js.js:706 msgid "seconds ago" msgstr "saniye önce" -#: js/js.js:712 +#: js/js.js:707 msgid "1 minute ago" msgstr "1 dakika önce" -#: js/js.js:713 +#: js/js.js:708 msgid "{minutes} minutes ago" msgstr "{minutes} dakika önce" -#: js/js.js:714 +#: js/js.js:709 msgid "1 hour ago" msgstr "1 saat önce" -#: js/js.js:715 +#: js/js.js:710 msgid "{hours} hours ago" msgstr "{hours} saat önce" -#: js/js.js:716 +#: js/js.js:711 msgid "today" msgstr "bugün" -#: js/js.js:717 +#: js/js.js:712 msgid "yesterday" msgstr "dün" -#: js/js.js:718 +#: js/js.js:713 msgid "{days} days ago" msgstr "{days} gün önce" -#: js/js.js:719 +#: js/js.js:714 msgid "last month" msgstr "geçen ay" -#: js/js.js:720 +#: js/js.js:715 msgid "{months} months ago" msgstr "{months} ay önce" -#: js/js.js:721 +#: js/js.js:716 msgid "months ago" msgstr "ay önce" -#: js/js.js:722 +#: js/js.js:717 msgid "last year" msgstr "geçen yıl" -#: js/js.js:723 +#: js/js.js:718 msgid "years ago" msgstr "yıl önce" @@ -172,11 +173,11 @@ msgstr "Hata" #: js/oc-vcategories.js:179 msgid "The app name is not specified." -msgstr "" +msgstr "uygulama adı belirtilmedi." #: js/oc-vcategories.js:194 msgid "The required file {file} is not installed!" -msgstr "" +msgstr "İhtiyaç duyulan {file} dosyası kurulu değil." #: js/share.js:124 js/share.js:594 msgid "Error while sharing" @@ -184,7 +185,7 @@ msgstr "Paylaşım sırasında hata " #: js/share.js:135 msgid "Error while unsharing" -msgstr "" +msgstr "Paylaşım iptal ediliyorken hata" #: js/share.js:142 msgid "Error while changing permissions" @@ -192,11 +193,11 @@ msgstr "İzinleri değiştirirken hata oluştu" #: js/share.js:151 msgid "Shared with you and the group {group} by {owner}" -msgstr "" +msgstr " {owner} tarafından sizinle ve {group} ile paylaştırılmış" #: js/share.js:153 msgid "Shared with you by {owner}" -msgstr "" +msgstr "{owner} trafından sizinle paylaştırıldı" #: js/share.js:158 msgid "Share with" @@ -216,7 +217,7 @@ msgstr "Parola" #: js/share.js:172 msgid "Email link to person" -msgstr "" +msgstr "Kişiye e-posta linki" #: js/share.js:173 msgid "Send" @@ -244,7 +245,7 @@ msgstr "Tekrar paylaşmaya izin verilmiyor" #: js/share.js:275 msgid "Shared in {item} with {user}" -msgstr "" +msgstr " {item} içinde {user} ile paylaşılanlarlar" #: js/share.js:296 msgid "Unshare" @@ -280,11 +281,11 @@ msgstr "Paralo korumalı" #: js/share.js:554 msgid "Error unsetting expiration date" -msgstr "" +msgstr "Geçerlilik tarihi tanımlama kaldırma hatası" #: js/share.js:566 msgid "Error setting expiration date" -msgstr "" +msgstr "Geçerlilik tarihi tanımlama hatası" #: js/share.js:581 msgid "Sending ..." @@ -383,13 +384,13 @@ msgstr "Güvenlik Uyarisi" msgid "" "No secure random number generator is available, please enable the PHP " "OpenSSL extension." -msgstr "" +msgstr "Güvenli rasgele sayı üreticisi bulunamadı. Lütfen PHP OpenSSL eklentisini etkinleştirin." #: templates/installation.php:26 msgid "" "Without a secure random number generator an attacker may be able to predict " "password reset tokens and take over your account." -msgstr "" +msgstr "Güvenli rasgele sayı üreticisi olmadan saldırganlar parola sıfırlama simgelerini tahmin edip hesabınızı ele geçirebilir." #: templates/installation.php:32 msgid "" @@ -398,7 +399,7 @@ msgid "" "strongly suggest that you configure your webserver in a way that the data " "directory is no longer accessible or you move the data directory outside the" " webserver document root." -msgstr "" +msgstr "data dizininiz ve dosyalarınız büyük ihtimalle internet üzerinden erişilebilir. Owncloud tarafından sağlanan .htaccess dosyası çalışmıyor. Web sunucunuzu yapılandırarak data dizinine erişimi kapatmanızı veya data dizinini web sunucu döküman dizini dışına almanızı şiddetle tavsiye ederiz." #: templates/installation.php:36 msgid "Create an admin account" @@ -445,83 +446,83 @@ msgstr "Veritabanı sunucusu" msgid "Finish setup" msgstr "Kurulumu tamamla" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Sunday" msgstr "Pazar" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Monday" msgstr "Pazartesi" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Tuesday" msgstr "Salı" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Wednesday" msgstr "Çarşamba" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Thursday" msgstr "Perşembe" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Friday" msgstr "Cuma" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Saturday" msgstr "Cumartesi" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "January" msgstr "Ocak" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "February" msgstr "Şubat" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "March" msgstr "Mart" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "April" msgstr "Nisan" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "May" msgstr "Mayıs" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "June" msgstr "Haziran" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "July" msgstr "Temmuz" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "August" msgstr "Ağustos" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "September" msgstr "Eylül" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "October" msgstr "Ekim" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "November" msgstr "Kasım" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "December" msgstr "Aralık" -#: templates/layout.guest.php:42 +#: templates/layout.guest.php:41 msgid "web services under your control" msgstr "kontrolünüzdeki web servisleri" @@ -537,11 +538,11 @@ msgstr "Otomatik oturum açma reddedildi!" msgid "" "If you did not change your password recently, your account may be " "compromised!" -msgstr "" +msgstr "Yakın zamanda parolanızı değiştirmedi iseniz hesabınız riske girebilir." #: templates/login.php:13 msgid "Please change your password to secure your account again." -msgstr "" +msgstr "Hesabınızı korumak için lütfen parolanızı değiştirin." #: templates/login.php:19 msgid "Lost your password?" @@ -566,4 +567,4 @@ msgstr "sonraki" #: templates/update.php:3 #, php-format msgid "Updating ownCloud to version %s, this may take a while." -msgstr "" +msgstr "Owncloud %s versiyonuna güncelleniyor. Biraz zaman alabilir." diff --git a/l10n/tr/files.po b/l10n/tr/files.po index b42bad885b..6a8b2bf601 100644 --- a/l10n/tr/files.po +++ b/l10n/tr/files.po @@ -7,14 +7,15 @@ # Caner Başaran , 2012. # Emre , 2012. # , 2012. +# ismail yenigul , 2013. # Necdet Yücel , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 21:35+0000\n" +"Last-Translator: ismail yenigül \n" "Language-Team: Turkish (http://www.transifex.com/projects/p/owncloud/language/tr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -30,16 +31,16 @@ msgstr "Yükle" #: ajax/move.php:17 #, php-format msgid "Could not move %s - File with this name already exists" -msgstr "" +msgstr "%s taşınamadı. Bu isimde dosya zaten var." #: ajax/move.php:24 #, php-format msgid "Could not move %s" -msgstr "" +msgstr "%s taşınamadı" #: ajax/rename.php:19 msgid "Unable to rename file" -msgstr "" +msgstr "Dosya adı değiştirilemedi" #: ajax/upload.php:20 msgid "No file was uploaded. Unknown error" @@ -78,11 +79,11 @@ msgstr "Diske yazılamadı" #: ajax/upload.php:57 msgid "Not enough space available" -msgstr "" +msgstr "Yeterli disk alanı yok" #: ajax/upload.php:91 msgid "Invalid directory." -msgstr "" +msgstr "Geçersiz dizin." #: appinfo/app.php:10 msgid "Files" @@ -138,11 +139,11 @@ msgstr "silinen {files}" #: js/files.js:48 msgid "'.' is an invalid file name." -msgstr "" +msgstr "'.' geçersiz dosya adı." #: js/files.js:53 msgid "File name cannot be empty." -msgstr "" +msgstr "Dosya adı boş olamaz." #: js/files.js:62 msgid "" @@ -154,7 +155,7 @@ msgstr "Geçersiz isim, '\\', '/', '<', '>', ':', '\"', '|', '?' ve '*' karakter msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "İndirmeniz hazırlanıyor. Dosya büyük ise biraz zaman alabilir." #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" @@ -195,7 +196,7 @@ msgstr "URL boş olamaz." #: js/files.js:565 msgid "Invalid folder name. Usage of 'Shared' is reserved by Owncloud" -msgstr "" +msgstr "Geçersiz dizin adı. Shared isminin kullanımı Owncloud tarafından rezerver edilmiştir." #: js/files.js:775 msgid "{count} files scanned" diff --git a/l10n/tr/files_encryption.po b/l10n/tr/files_encryption.po index c48e3908ae..e95281ce02 100644 --- a/l10n/tr/files_encryption.po +++ b/l10n/tr/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-12-28 00:20+0100\n" -"PO-Revision-Date: 2012-12-27 10:35+0000\n" -"Last-Translator: Necdet Yücel \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Turkish (http://www.transifex.com/projects/p/owncloud/language/tr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: tr\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Şifreleme" -#: templates/settings.php:6 -msgid "Enable Encryption" -msgstr "Şifrelemeyi Etkinleştir" - -#: templates/settings.php:7 -msgid "None" -msgstr "Hiçbiri" - -#: templates/settings.php:12 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Aşağıdaki dosya tiplerini şifrelemeye dahil etme" + +#: templates/settings.php:71 +msgid "None" +msgstr "Hiçbiri" diff --git a/l10n/tr/lib.po b/l10n/tr/lib.po index 1b796458af..fadb1957cf 100644 --- a/l10n/tr/lib.po +++ b/l10n/tr/lib.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# ismail yenigul , 2013. # Necdet Yücel , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 09:28+0000\n" +"Last-Translator: ismail yenigül \n" "Language-Team: Turkish (http://www.transifex.com/projects/p/owncloud/language/tr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -58,9 +59,9 @@ msgstr "Dosyalara dön" msgid "Selected files too large to generate zip file." msgstr "Seçilen dosyalar bir zip dosyası oluşturmak için fazla büyüktür." -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "tespit edilemedi" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/uk/files_encryption.po b/l10n/uk/files_encryption.po index 9b00d3b7a3..884db2f7af 100644 --- a/l10n/uk/files_encryption.po +++ b/l10n/uk/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-10-23 02:02+0200\n" -"PO-Revision-Date: 2012-10-22 12:05+0000\n" -"Last-Translator: skoptev \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Ukrainian (http://www.transifex.com/projects/p/owncloud/language/uk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: uk\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Шифрування" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Не шифрувати файли наступних типів" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Жоден" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "Включити шифрування" diff --git a/l10n/vi/files_encryption.po b/l10n/vi/files_encryption.po index 0ac3a53087..a6019e0302 100644 --- a/l10n/vi/files_encryption.po +++ b/l10n/vi/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-11-21 00:01+0100\n" -"PO-Revision-Date: 2012-11-20 05:48+0000\n" -"Last-Translator: Sơn Nguyễn \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: vi\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "Mã hóa" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "Loại trừ các loại tập tin sau đây từ mã hóa" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "Không có gì hết" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "BẬT mã hóa" diff --git a/l10n/zh_CN.GB2312/files_encryption.po b/l10n/zh_CN.GB2312/files_encryption.po index eb4ddd9c54..f85989afca 100644 --- a/l10n/zh_CN.GB2312/files_encryption.po +++ b/l10n/zh_CN.GB2312/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-18 02:01+0200\n" -"PO-Revision-Date: 2012-09-17 10:51+0000\n" -"Last-Translator: marguerite su \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Chinese (China) (GB2312) (http://www.transifex.com/projects/p/owncloud/language/zh_CN.GB2312/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: zh_CN.GB2312\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "加密" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "从加密中排除如下文件类型" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "无" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "启用加密" diff --git a/l10n/zh_CN/files.po b/l10n/zh_CN/files.po index 95316b1a41..c5a96d2013 100644 --- a/l10n/zh_CN/files.po +++ b/l10n/zh_CN/files.po @@ -8,14 +8,15 @@ # marguerite su , 2013. # , 2012. # , 2012. +# , 2013. # , 2011, 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 23:17+0000\n" +"Last-Translator: Xuetian Weng \n" "Language-Team: Chinese (China) (http://www.transifex.com/projects/p/owncloud/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -155,7 +156,7 @@ msgstr "无效名称,'\\', '/', '<', '>', ':', '\"', '|', '?' 和 '*' 不被 msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "下载正在准备中。如果文件较大可能会花费一些时间。" #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/zh_CN/files_encryption.po b/l10n/zh_CN/files_encryption.po index 502f4e08a6..5395d6734d 100644 --- a/l10n/zh_CN/files_encryption.po +++ b/l10n/zh_CN/files_encryption.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-08 02:01+0200\n" -"PO-Revision-Date: 2012-09-07 09:38+0000\n" -"Last-Translator: hanfeng \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Chinese (China) (http://www.transifex.com/projects/p/owncloud/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,18 +18,66 @@ msgstr "" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "加密" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "从加密中排除列出的文件类型" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "None" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "开启加密" diff --git a/l10n/zh_CN/user_webdavauth.po b/l10n/zh_CN/user_webdavauth.po index 507b60d8a0..a642c9b21d 100644 --- a/l10n/zh_CN/user_webdavauth.po +++ b/l10n/zh_CN/user_webdavauth.po @@ -6,13 +6,14 @@ # , 2012. # Dianjin Wang <1132321739qq@gmail.com>, 2012. # marguerite su , 2013. +# , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:04+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-21 23:23+0000\n" +"Last-Translator: Xuetian Weng \n" "Language-Team: Chinese (China) (http://www.transifex.com/projects/p/owncloud/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,7 +23,7 @@ msgstr "" #: templates/settings.php:3 msgid "WebDAV Authentication" -msgstr "" +msgstr "WebDAV 认证" #: templates/settings.php:4 msgid "URL: http://" @@ -33,4 +34,4 @@ msgid "" "ownCloud will send the user credentials to this URL. This plugin checks the " "response and will interpret the HTTP statuscodes 401 and 403 as invalid " "credentials, and all other responses as valid credentials." -msgstr "" +msgstr "ownCloud 将会发送用户的身份到此 URL。这个插件检查返回值并且将 HTTP 状态编码 401 和 403 解释为非法身份,其他所有返回值为合法身份。" diff --git a/l10n/zh_HK/files_encryption.po b/l10n/zh_HK/files_encryption.po index 52a31f20ba..adf957c6ee 100644 --- a/l10n/zh_HK/files_encryption.po +++ b/l10n/zh_HK/files_encryption.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-11-19 00:01+0100\n" -"PO-Revision-Date: 2012-08-12 22:33+0000\n" -"Last-Translator: FULL NAME \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Chinese (Hong Kong) (http://www.transifex.com/projects/p/owncloud/language/zh_HK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,18 +17,66 @@ msgstr "" "Language: zh_HK\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 -msgid "Encryption" +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." msgstr "" -#: templates/settings.php:4 -msgid "Exclude the following file types from encryption" +#: js/settings-personal.js:17 +msgid "switched to client side encryption" msgstr "" -#: templates/settings.php:5 -msgid "None" +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" msgstr "" #: templates/settings.php:10 -msgid "Enable Encryption" +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 +msgid "Encryption" +msgstr "" + +#: templates/settings.php:67 +msgid "Exclude the following file types from encryption" +msgstr "" + +#: templates/settings.php:71 +msgid "None" msgstr "" diff --git a/l10n/zh_TW/files_encryption.po b/l10n/zh_TW/files_encryption.po index 1da95b438b..08bcf01b0d 100644 --- a/l10n/zh_TW/files_encryption.po +++ b/l10n/zh_TW/files_encryption.po @@ -8,28 +8,76 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-02 02:01+0200\n" -"PO-Revision-Date: 2012-09-01 14:48+0000\n" -"Last-Translator: ywang \n" +"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"PO-Revision-Date: 2013-01-22 23:05+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/owncloud/language/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_TW\n" -"Plural-Forms: nplurals=1; plural=0\n" +"Plural-Forms: nplurals=1; plural=0;\n" -#: templates/settings.php:3 +#: js/settings-personal.js:17 +msgid "" +"Please switch to your ownCloud client and change your encryption password to" +" complete the conversion." +msgstr "" + +#: js/settings-personal.js:17 +msgid "switched to client side encryption" +msgstr "" + +#: js/settings-personal.js:21 +msgid "Change encryption password to login password" +msgstr "" + +#: js/settings-personal.js:25 +msgid "Please check your passwords and try again." +msgstr "" + +#: js/settings-personal.js:25 +msgid "Could not change your file encryption password to your login password" +msgstr "" + +#: templates/settings-personal.php:3 templates/settings.php:5 +msgid "Choose encryption mode:" +msgstr "" + +#: templates/settings-personal.php:20 templates/settings.php:24 +msgid "" +"Client side encryption (most secure but makes it impossible to access your " +"data from the web interface)" +msgstr "" + +#: templates/settings-personal.php:30 templates/settings.php:36 +msgid "" +"Server side encryption (allows you to access your files from the web " +"interface and the desktop client)" +msgstr "" + +#: templates/settings-personal.php:41 templates/settings.php:60 +msgid "None (no encryption at all)" +msgstr "" + +#: templates/settings.php:10 +msgid "" +"Important: Once you selected an encryption mode there is no way to change it" +" back" +msgstr "" + +#: templates/settings.php:48 +msgid "User specific (let the user decide)" +msgstr "" + +#: templates/settings.php:65 msgid "Encryption" msgstr "加密" -#: templates/settings.php:4 +#: templates/settings.php:67 msgid "Exclude the following file types from encryption" msgstr "下列的檔案類型不加密" -#: templates/settings.php:5 +#: templates/settings.php:71 msgid "None" msgstr "無" - -#: templates/settings.php:10 -msgid "Enable Encryption" -msgstr "啟用加密" diff --git a/lib/l10n/gl.php b/lib/l10n/gl.php index 1e897959e4..532b3443b4 100644 --- a/lib/l10n/gl.php +++ b/lib/l10n/gl.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "Os ficheiros necesitan seren descargados de un en un.", "Back to Files" => "Volver aos ficheiros", "Selected files too large to generate zip file." => "Os ficheiros seleccionados son demasiado grandes como para xerar un ficheiro zip.", +"couldn't be determined" => "non puido ser determinado", "Application is not enabled" => "O aplicativo non está activado", "Authentication error" => "Produciuse un erro na autenticación", "Token expired. Please reload page." => "Testemuña caducada. Recargue a páxina.", diff --git a/lib/l10n/sv.php b/lib/l10n/sv.php index 5799e2dd1a..36f00636b2 100644 --- a/lib/l10n/sv.php +++ b/lib/l10n/sv.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "Filer laddas ner en åt gången.", "Back to Files" => "Tillbaka till Filer", "Selected files too large to generate zip file." => "Valda filer är för stora för att skapa zip-fil.", +"couldn't be determined" => "kunde inte bestämmas", "Application is not enabled" => "Applikationen är inte aktiverad", "Authentication error" => "Fel vid autentisering", "Token expired. Please reload page." => "Ogiltig token. Ladda om sidan.", diff --git a/lib/l10n/th_TH.php b/lib/l10n/th_TH.php index 75fa02f84b..0da607a058 100644 --- a/lib/l10n/th_TH.php +++ b/lib/l10n/th_TH.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "ไฟล์สามารถดาวน์โหลดได้ทีละครั้งเท่านั้น", "Back to Files" => "กลับไปที่ไฟล์", "Selected files too large to generate zip file." => "ไฟล์ที่เลือกมีขนาดใหญ่เกินกว่าที่จะสร้างเป็นไฟล์ zip", +"couldn't be determined" => "ไม่สามารถกำหนดได้", "Application is not enabled" => "แอพพลิเคชั่นดังกล่าวยังไม่ได้เปิดใช้งาน", "Authentication error" => "เกิดข้อผิดพลาดในสิทธิ์การเข้าใช้งาน", "Token expired. Please reload page." => "รหัสยืนยันความถูกต้องหมดอายุแล้ว กรุณาโหลดหน้าเว็บใหม่อีกครั้ง", diff --git a/lib/l10n/tr.php b/lib/l10n/tr.php index 9b7f1815fa..e55caa1597 100644 --- a/lib/l10n/tr.php +++ b/lib/l10n/tr.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "Dosyaların birer birer indirilmesi gerekmektedir.", "Back to Files" => "Dosyalara dön", "Selected files too large to generate zip file." => "Seçilen dosyalar bir zip dosyası oluşturmak için fazla büyüktür.", +"couldn't be determined" => "tespit edilemedi", "Application is not enabled" => "Uygulama etkinleştirilmedi", "Authentication error" => "Kimlik doğrulama hatası", "Token expired. Please reload page." => "Jetonun süresi geçti. Lütfen sayfayı yenileyin.", diff --git a/settings/l10n/th_TH.php b/settings/l10n/th_TH.php index f4e6398ae2..c0c606662e 100644 --- a/settings/l10n/th_TH.php +++ b/settings/l10n/th_TH.php @@ -10,6 +10,7 @@ "Unable to delete user" => "ไม่สามารถลบผู้ใช้งานได้", "Language changed" => "เปลี่ยนภาษาเรียบร้อยแล้ว", "Invalid request" => "คำร้องขอไม่ถูกต้อง", +"Admins can't remove themself from the admin group" => "ผู้ดูแลระบบไม่สามารถลบตัวเองออกจากกลุ่มผู้ดูแลได้", "Unable to add user to group %s" => "ไม่สามารถเพิ่มผู้ใช้งานเข้าไปที่กลุ่ม %s ได้", "Unable to remove user from group %s" => "ไม่สามารถลบผู้ใช้งานออกจากกลุ่ม %s ได้", "Disable" => "ปิดใช้งาน", @@ -21,8 +22,17 @@ "Select an App" => "เลือก App", "See application page at apps.owncloud.com" => "ดูหน้าแอพพลิเคชั่นที่ apps.owncloud.com", "-licensed by " => "-ลิขสิทธิ์การใช้งานโดย ", +"User Documentation" => "เอกสารคู่มือการใช้งานสำหรับผู้ใช้งาน", +"Administrator Documentation" => "เอกสารคู่มือการใช้งานสำหรับผู้ดูแลระบบ", +"Online Documentation" => "เอกสารคู่มือการใช้งานออนไลน์", +"Forum" => "กระดานสนทนา", +"Bugtracker" => "Bugtracker", +"Commercial Support" => "บริการลูกค้าแบบเสียค่าใช้จ่าย", "You have used %s of the available %s" => "คุณได้ใช้งานไปแล้ว %s จากจำนวนที่สามารถใช้ได้ %s", "Clients" => "ลูกค้า", +"Download Desktop Clients" => "ดาวน์โหลดโปรแกรมไคลเอนต์สำหรับเครื่องเดสก์ท็อป", +"Download Android Client" => "ดาวน์โหลดโปรแกรมไคลเอนต์สำหรับแอนดรอยด์", +"Download iOS Client" => "ดาวน์โหลดโปรแกรมไคลเอนต์สำหรับ iOS", "Password" => "รหัสผ่าน", "Your password was changed" => "รหัสผ่านของคุณถูกเปลี่ยนแล้ว", "Unable to change your password" => "ไม่สามารถเปลี่ยนรหัสผ่านของคุณได้", @@ -35,11 +45,18 @@ "Fill in an email address to enable password recovery" => "กรอกที่อยู่อีเมล์ของคุณเพื่อเปิดให้มีการกู้คืนรหัสผ่านได้", "Language" => "ภาษา", "Help translate" => "ช่วยกันแปล", +"WebDAV" => "WebDAV", +"Use this address to connect to your ownCloud in your file manager" => "ใช้ที่อยู่นี้เพื่อเชื่อมต่อกับ ownCloud ในโปรแกรมจัดการไฟล์ของคุณ", +"Version" => "รุ่น", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "พัฒนาโดย the ชุมชนผู้ใช้งาน ownCloud, the ซอร์สโค้ดอยู่ภายใต้สัญญาอนุญาตของ AGPL.", "Name" => "ชื่อ", "Groups" => "กลุ่ม", "Create" => "สร้าง", +"Default Storage" => "พื้นที่จำกัดข้อมูลเริ่มต้น", +"Unlimited" => "ไม่จำกัดจำนวน", "Other" => "อื่นๆ", "Group Admin" => "ผู้ดูแลกลุ่ม", +"Storage" => "พื้นที่จัดเก็บข้อมูล", +"Default" => "ค่าเริ่มต้น", "Delete" => "ลบ" ); From 5fadd530888459a62c7113a916247033fb14c96c Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Wed, 23 Jan 2013 09:18:26 +0100 Subject: [PATCH 242/315] missing renames of publicListView to disableSharing --- apps/files_sharing/js/share.js | 2 +- apps/files_sharing/public.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index a46d017980..780b9c1bf6 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -1,6 +1,6 @@ $(document).ready(function() { - if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !publicListView) { + if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !disableSharing) { FileActions.register('all', 'Share', OC.PERMISSION_READ, OC.imagePath('core', 'actions/share'), function(filename) { if ($('#dir').val() == '/') { diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index efd977a1b6..acd5353faf 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -257,7 +257,7 @@ if ($linkItem) { $list = new OCP\Template('files', 'part.list', ''); $list->assign('files', $files, false); - $list->assign('publicListView', true); + $list->assign('disableSharing', true); $list->assign('baseURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&path=', false); $list->assign('downloadURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&download&path=', false); $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '' ); From 48949ba04acacd5cc4039ba15266619ebe61a52b Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 23 Jan 2013 11:21:27 +0100 Subject: [PATCH 243/315] Move appid to external file --- settings/apps.php | 2 -- settings/js/apps-custom.php | 4 +++- settings/templates/apps.php | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/settings/apps.php b/settings/apps.php index 384e92bfbb..b6426a31c9 100644 --- a/settings/apps.php +++ b/settings/apps.php @@ -26,10 +26,8 @@ OC_App::loadApps(); // Load the files we need OC_Util::addStyle( "settings", "settings" ); -OC_Util::addScript( "settings", "apps" ); OC_App::setActiveNavigationEntry( "core_apps" ); - function app_sort( $a, $b ) { if ($a['active'] != $b['active']) { diff --git a/settings/js/apps-custom.php b/settings/js/apps-custom.php index e0e7a2d6c7..9ec2a758ee 100644 --- a/settings/js/apps-custom.php +++ b/settings/js/apps-custom.php @@ -21,4 +21,6 @@ $combinedApps = OC_App::listAllApps(); foreach($combinedApps as $app) { echo("appData_".$app['id']."=".json_encode($app)); echo("\n"); -} \ No newline at end of file +} + +echo ("var appid =\"".$_GET['appid']."\";"); \ No newline at end of file diff --git a/settings/templates/apps.php b/settings/templates/apps.php index 98b0e6c725..d418b9a66a 100644 --- a/settings/templates/apps.php +++ b/settings/templates/apps.php @@ -3,7 +3,8 @@ * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. */?> - + +
                t('Add your App');?> From fe56e4df7d6e2e9f37c378acbf0327c0ed694eb2 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 23 Jan 2013 11:32:14 +0100 Subject: [PATCH 244/315] Fix merge conflict --- core/templates/layout.base.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/core/templates/layout.base.php b/core/templates/layout.base.php index 08083a2924..47fb75612c 100644 --- a/core/templates/layout.base.php +++ b/core/templates/layout.base.php @@ -7,15 +7,7 @@ -<<<<<<< HEAD -======= - ->>>>>>> master From 846971ec11b74c92e58ada6ed8977b6b9871df7d Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 23 Jan 2013 11:33:25 +0100 Subject: [PATCH 245/315] Fix merge conflict --- core/templates/layout.guest.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php index 7f33d53965..499d49e445 100644 --- a/core/templates/layout.guest.php +++ b/core/templates/layout.guest.php @@ -7,19 +7,7 @@ -<<<<<<< HEAD -======= - ->>>>>>> master From b4c3dd84b405b5cdd463cc0e82762b4d8d29f382 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Wed, 23 Jan 2013 11:37:28 +0100 Subject: [PATCH 246/315] update to jquery-ui 1.10.0 --- build/phpcs.xml | 2 +- core/css/images/animated-overlay.gif | Bin 0 -> 1738 bytes .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 0 -> 260 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 0 -> 251 bytes .../images/ui-bg_flat_100_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_flat_10_000000_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_flat_35_1d2d44_40x100.png | Bin 0 -> 183 bytes .../images/ui-bg_glass_100_f8f8f8_1x400.png | Bin 0 -> 105 bytes .../ui-bg_highlight-hard_100_f8f8f8_1x100.png | Bin 0 -> 88 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 0 -> 90 bytes core/css/images/ui-icons_1d2d44_256x240.png | Bin 0 -> 4369 bytes core/css/images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes core/css/images/ui-icons_ffd27a_256x240.png | Bin 0 -> 4369 bytes core/css/images/ui-icons_ffffff_256x240.png | Bin 0 -> 4369 bytes core/css/jquery-ui-1.10.0.custom.css | 1174 ++ core/css/jquery-ui-1.8.16.custom.css | 362 - core/js/jquery-ui-1.10.0.custom.js | 14850 ++++++++++++++++ core/js/jquery-ui-1.8.16.custom.min.js | 761 - lib/base.php | 4 +- 19 files changed, 16027 insertions(+), 1126 deletions(-) create mode 100644 core/css/images/animated-overlay.gif create mode 100644 core/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png create mode 100644 core/css/images/ui-bg_diagonals-thick_20_666666_40x40.png create mode 100644 core/css/images/ui-bg_flat_100_ffffff_40x100.png create mode 100644 core/css/images/ui-bg_flat_10_000000_40x100.png create mode 100644 core/css/images/ui-bg_flat_35_1d2d44_40x100.png create mode 100644 core/css/images/ui-bg_glass_100_f8f8f8_1x400.png create mode 100644 core/css/images/ui-bg_highlight-hard_100_f8f8f8_1x100.png create mode 100644 core/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png create mode 100644 core/css/images/ui-icons_1d2d44_256x240.png create mode 100644 core/css/images/ui-icons_222222_256x240.png create mode 100644 core/css/images/ui-icons_ffd27a_256x240.png create mode 100644 core/css/images/ui-icons_ffffff_256x240.png create mode 100644 core/css/jquery-ui-1.10.0.custom.css delete mode 100644 core/css/jquery-ui-1.8.16.custom.css create mode 100644 core/js/jquery-ui-1.10.0.custom.js delete mode 100644 core/js/jquery-ui-1.8.16.custom.min.js diff --git a/build/phpcs.xml b/build/phpcs.xml index 1e10be1a11..d2909955ed 100644 --- a/build/phpcs.xml +++ b/build/phpcs.xml @@ -10,7 +10,7 @@ */files_pdfviewer/js/pdfjs/* */files_odfviewer/src/* */files_svgedit/svg-edit/* - *jquery-ui-1.8.16.custom.css + *jquery-ui-*.css php diff --git a/core/css/images/animated-overlay.gif b/core/css/images/animated-overlay.gif new file mode 100644 index 0000000000000000000000000000000000000000..d441f75ebfbdf26a265dfccd670120d25c0a341c GIT binary patch literal 1738 zcmZ|OX;ji_6b5ixNYt8>l?gOuO)6lU%W(mxn(`>1S(XO;u`D+P%xqBvMr|w-Vyr1s z7R|Cn0b8|Hu<=Zmv1mFqh9Fj!NuZfKB2MP$e75`XJ@>=!y!Ux9xR3x;EW!q1^V>X| znVFuRUN`NqJ2)ybXh%e__h!!pv(M|S3+?9F%(K}zyE40MGyhWF5-IDgL&=%2-9`Nk z!1@8uk4t%_{(K~>N;sK&dzJbwJ=$kYTlL=$%#0Pfh>U{%i@~wWbvYsD_K-D`&+u1( z#Ma`>%q<^UhzGvi(hyE`zCD{-=2|zL5>wnB=DE!U?(CZG%q4@lDnCq_%&3DCla#(X zmBhDD+RN$aMWWHm?ig*>1Onn6~r?Ma~N2JKAxN>H%UtRyRqS)6Um!-Tz%-r=& zQmTb^JFIe3W^-kAm`}`2P|niMh>RYyd)S^f(dbrx965?rzbhP|XeP}o&&DSZ4|oYQ z)I{f!SfycYw?3=9W;o-B%U5xs(pP267X~9-7L|4WzaYexC0GtG8wWygm63rF{llCEraxzkc=IxvFQ-y37=_;e5 zJLq^gsSO0Ayz?a>E_?{dmUc+t#qv$)XN8$<<}rQ#)lsiw+pmL&J>~+hgpo>i$m+;l zZIa_ZRIfSeT$~v5d`EBV&*k`apPgjv&B|+d`Q!nyu{L4rs%ZfoF0*Kq8I%ByOcFpL zK=>wzofZo<+0GZLCnWM3oQ^pb(gRSf02;~cEn@LJ>~XB9IkEX{$N#Z`m%>S!U{uPx zloI%bLdo$Adxlh(Uv^yX7s5G&C zLwNRG>~T?G{kzupp8EcyLGPoPf)@&9Wqfw_l&uU-6cexk%5;uQg%wb=0k_733{i#& z1a2p)gV3S2+QG1-K9tZ}E~I<(P0r2aFFY-c{o?TUOz3Xjod#TLE2A_c?*T7t z=1>~%YW450{Qqno4t`}gvLnuMrcu8+#xEBoY%2_+Mb#Z6S38+r*M4O`-+!zl(@m`D zQsi|GA2l3gEy}LFe<#Hv8?$_L#u8E|3-bP$*La*E>B{X!Sy4i6?TKam!49aXCAW4S*P_O^H4^*DpiA40o}Uqw~Eo&veh1`|8i zD2$x+>_b^bXE4N;AW=5>iYak2%!JAh0j1*k1{p#iRCjbB7!cSws~U{1IA@acLII$t z$>X#A+^s6iJ5~DFG!xa?>z{=lxtdi1rzbM-(nqAu3D8h-&64xo6|E!p?pK0xT;qoK z`6%+SpBk+~M?nO}>2mTw!A{yZ6O>Z@kwSd4;8aWU5z!P~tQl?u==^+R`{OmOS}oZh zOXQ3{6kuz?Is^n^L7;9ieB9C+8B{>t+pDrlq4xGDDn#T#3T5$l1g`FTQkU;b-981j zNm{zC`$wn7etklM#qHI4=3m5gwa6DNS{?Z!vSObi_od{4eUo=_S2BKNpkSdiqe(k9WtkeM79;2-%CFbb)aB=&H1?i1}uwFzoZQ(38Kn1zBP ORn*B%u*Wk|4g3!*Rv{Mv literal 0 HcmV?d00001 diff --git a/core/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/core/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..954e22dbd99e8c6dd7091335599abf2d10bf8003 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEr#)R9Ln2z=UU%d=WFXS=@V?HT z#xG*`>Yvsgk=}99w^d^D^d*@m74oMo<%#FcopJf?u00-~YVKV2wzrI*_R6;UORMea zBFVSEnN~eiVA6V&z`E)YLz5Aok^D)In}Yn=OzDpgR5Wv0XfT8pOkmV{sKAJ-PO9#T zZK}IXj&Q-V!U)!LcB_3K0&C*{ literal 0 HcmV?d00001 diff --git a/core/css/images/ui-bg_diagonals-thick_20_666666_40x40.png b/core/css/images/ui-bg_diagonals-thick_20_666666_40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..64ece5707d91a6edf9fad4bfcce0c4dbcafcf58d GIT binary patch literal 251 zcmVbvPcjKS|RKP(6sDcCAB(_QB%0978a<$Ah$!b|E zwn;|HO0i8cQj@~)s!ajF0S002ovPDHLkV1oEp BYH0uf literal 0 HcmV?d00001 diff --git a/core/css/images/ui-bg_flat_100_ffffff_40x100.png b/core/css/images/ui-bg_flat_100_ffffff_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..ac8b229af950c29356abf64a6c4aa894575445f0 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQYz+E8 zPo9&<{J;c_6SHRil>2s{Zw^OT)6@jj2u|u!(plXsM>LJD`vD!n;OXk;vd$@?2>^GI BH@yG= literal 0 HcmV?d00001 diff --git a/core/css/images/ui-bg_flat_10_000000_40x100.png b/core/css/images/ui-bg_flat_10_000000_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..abdc01082bf3534eafecc5819d28c9574d44ea89 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQY-ImG zFPf9b{J;c_6SHRK%WcbN_hZpM=(Ry;4Rxv2@@2Y=$K57eF$X$=!PC{xWt~$(69B)$ BI)4BF literal 0 HcmV?d00001 diff --git a/core/css/images/ui-bg_flat_35_1d2d44_40x100.png b/core/css/images/ui-bg_flat_35_1d2d44_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..904ef14c37d9cff5afe71ef9733141328f22ac3c GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsX9*=$B>N1x91EQ8x$BA9G9>Q z<|O|25^8+NCi_q5&enI&W$n%O^UV)`n7(8A5T-G@y GGywnz958+W literal 0 HcmV?d00001 diff --git a/core/css/images/ui-bg_glass_100_f8f8f8_1x400.png b/core/css/images/ui-bg_glass_100_f8f8f8_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..cd79e9f1966df03e2956237b5a878a7c7cc32872 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouqzpV=978O6lYe}DeZ5|djg74> zFlmZ}YMbuI_xJ5n^pusA+k{LEm8SFvEk2@QID>;>p$C_c^rhBHpk4+~S3j3^P6PmYTG^FX}c% zlGE{DS1Q;~I7-6ze&TN@+F-xsI6sd%SwK#*O5K|pDRZqEy< zJg0Nd8F@!OxqElm`~U#piM22@u@8B<moyKE%ct`B(jysxK+1m?G)UyIFs1t0}L zemGR&?jGaM1YQblj?v&@0iXS#fi-VbR9zLEnHLP?xQ|=%Ihrc7^yPWR!tW$yH!zrw z#I2}_!JnT^(qk)VgJr`NGdPtT^dmQIZc%=6nTAyJDXk+^3}wUOilJuwq>s=T_!9V) zr1)DT6VQ2~rgd@!Jlrte3}}m~j}juCS`J4(d-5+e-3@EzzTJNCE2z)w(kJ90z*QE) zBtnV@4mM>jTrZZ*$01SnGov0&=A-JrX5Ge%Pce1Vj}=5YQqBD^W@n4KmFxxpFK`uH zP;(xKV+6VJ2|g+?_Lct7`uElL<&jzGS8Gfva2+=8A@#V+xsAj9|Dkg)vL5yhX@~B= zN2KZSAUD%QH`x>H+@Ou(D1~Pyv#0nc&$!1kI?IO01yw3jD0@80qvc?T*Nr8?-%rC8 z@5$|WY?Hqp`ixmEkzeJTz_`_wsSRi1%Zivd`#+T{Aib6-rf$}M8sz6v zb6ERbr-SniO2wbOv!M4)nb}6UVzoVZEh5kQWh_5x4rYy3c!871NeaM(_p=4(kbS6U#x<*k8Wg^KHs2ttCz<+pBxQ$Z zQMv;kVm5_fF_vH`Mzrq$Y&6u?j6~ftIV0Yg)Nw7JysIN_ z-_n*K_v1c&D}-1{NbBwS2h#m1y0a5RiEcYil+58$8IDh49bPnzE7R8In6P%V{2IZU z7#clr=V4yyrRe@oXNqbqo^^LvlLE?%8XaI&N(Np90-psU}7kqmbWk zZ;YBwJNnNs$~d!mx9oMGyT( znaBoj0d}gpQ^aRr?6nW)$4god*`@Uh2e+YpS@0(Mw{|z|6ko3NbTvDiCu3YO+)egL z>uW(^ahKFj>iJ-JF!^KhKQyPTznJa;xyHYwxJgr16&Wid_9)-%*mEwo{B_|M9t@S1 zf@T@q?b2Qgl!~_(Roe;fdK)y|XG0;ls;ZbT)w-aOVttk#daQcY7$cpY496H*`m@+L zeP#$&yRbBjFWv}B)|5-1v=(66M_;V1SWv6MHnO}}1=vby&9l+gaP?|pXwp0AFDe#L z&MRJ^*qX6wgxhA_`*o=LGZ>G_NTX%AKHPz4bO^R72ZYK}ale3lffDgM8H!Wrw{B7A z{?c_|dh2J*y8b04c37OmqUw;#;G<* z@nz@dV`;7&^$)e!B}cd5tl0{g(Q>5_7H^@bEJi7;fQ4B$NGZerH#Ae1#8WDTH`iB&) zC6Et3BYY#mcJxh&)b2C^{aLq~psFN)Q1SucCaBaBUr%5PYX{~-q{KGEh)*;n;?75k z=hq%i^I}rd;z-#YyI`8-OfMpWz5kgJE3I!3ean6=UZi!BxG7i(YBk? z02HM7wS0)Wni{dWbQMRtd-A)_Az!t>F;IwWf~!*)-Az4}yryNkz&9)w>ElA80Oc`6 zHo#9H!Y3*Qx9n@Jn)!w6G^hb;e_n8zpIyXCN`JFkPc)^Q?2MsLNFhMgrcZI-<#1ne zjH;KFf?4eAT9mQZ}ZfHLGA#d%s;SZK4p0FwZT2S^{ zQ2BG1xJsbK6?yrHTjJi|5C0u=!|r!?*4FL%y%3q#(d+e>b_2I9!*iI!30}42Ia0bq zUf`Z?LGSEvtz8s``Tg5o_CP(FbR0X$FlE0yCnB7suDPmI2=yOg^*2#cY9o`X z;NY-3VBHZjnVcGS){GZ98{e+lq~O$u6pEcgd0CrnIsWffN1MbCZDH<7c^hv+Z0Ucf0{w zSzi^qKuUHD9Dgp0EAGg@@$zr32dQx>N=ws`MESEsmzgT2&L;?MSTo&ky&!-JR3g~1 zPGTt515X)wr+Bx(G9lWd;@Y3^Vl}50Wb&6-Tiy;HPS0drF`rC}qYq22K4)G#AoD0X zYw$E+Bz@Zr^50MAwu@$?%f9$r4WHH?*2|67&FXFhXBrVFGmg)6?h3^-1?t;UzH0*I zNVf9wQLNLnG2@q>6CGm>&y|lC`iCFfYd}9i%+xkl^5oBJ?<;aneCfcHqJh7Yl5uLS z9Fx-(kMdcNyZejXh22N{mCw_rX1O!cOE&3>e(ZH81PR95wQC37En4O{w;{3q9n1t&;p)D%&Z%Nw$gSPa!nz8Slh7=ko2am)XARwOWw zpsz0~K!s{(dM$NB=(A=kkp>T(*yU6<_dwIx>cH4+LWl282hXa6-EUq>R3t?G2623< z*RwTN%-fgBmD{fu*ejNn)1@KG?Sg*8z3hYtkQJQjB6 zQ|x>wA=o$=O)+nLmgTXW3_6diA;b4EY{*i*R%6dO2EMg z@6g?M3rpbnfB@hOdUeb96=~I?OIA3@BWAGmTwiQ{x5Cqq<8c10L!P zd@Qk^BseTX%$Q7^s}5n%HB|)gKx}H$d8Sb$bBnq9-AglT2dGR2(+I;_fL|R4p$odJ zllfb0NqI)7=^z~qAm1V{(PkpxXsQ#4*NH9yYZ`Vf@)?#ueGgtCmGGY|9U#v|hRdg- zQ%0#cGIfXCd{Y)JB~qykO;KPvHu|5Ck&(Hn%DF~cct@}j+87xhs2ew;fLm5#2+mb| z8{9e*YI(u|gt|{x1G+U=DA3y)9s2w7@cvQ($ZJIA)x$e~5_3LKFV~ASci8W}jF&VeJoPDUy(BB>ExJpck;%;!`0AAo zAcHgcnT8%OX&UW_n|%{2B|<6Wp2MMGvd5`T2KKv;ltt_~H+w00x6+SlAD`{K4!9zx z*1?EpQ%Lwiik){3n{-+YNrT;fH_niD_Ng9|58@m8RsKFVF!6pk@qxa{BH-&8tsim0 zdAQ(GyC^9ane7_KW*#^vMIoeQdpJqmPp%%px3GIftbwESu#+vPyI*YTuJ6+4`z{s? zpkv~0x4c_PFH`-tqafw5)>4AuQ78SkZ!$8}INLK;Egr;2tS18hEO5=t;QDmZ-qu?I zG+=DN`nR72Xto{{bJp||`k}-2G;5#xg8E~xgz22)^_Z;=K|4@(E&5J)SY2of=olcw z5)@L)_Ntcm!*5nEy0M9v0`S33;pO4TN;>4(Z+19p_0>u#e-vE zXCU(6gAvu~I7Cw(xd%0e59MNLw^U37ZDbsBrj%eDCexw8a3G`nTcXVNL6{B7Hj@i& zbVB{;ApEtHk76q08DJ48dSxd$C(;$K6=FpU<~l9pVoT9arW^Vu{%Bcn4`eIpkOVC| z$)AKYG_`ypM{0@BUb3^9lqi_c?ONH|4UJMJWDowMVjacycX7}9g={O7swOB+{;+?; zjBo!9?+nd)ie#x5IbFW-zBOo0c4q@9wGVt5;pNt`=-~Zgcw#*`m($6ibxtZ`H=e=} zF#GZ~5$%AUn};8U#tRem0J(JTR}d4vR(dgK2ML~lZsPhayJ2h1%sD4FVst| zKF)+@`iNzLRjg4=K8@**0=5cE>%?FDc({I^+g9USk<8$&^qD~@%W0i4b|yMG*p4`N zh}I!ltTRI8Ex$+@V{02Br%xq#O?UlhO{r8WsaZnZCZq0MK9%AXU%MDLT;3=0A9(BV z9VxxxJd7jo$hw3q;3o?yBLmA=azBUrd9>-<_ANs0n3?-Ic*6&ytb@H~?0E(*d>T5n z-HiH2jsDf6uWhID%#n>SzOqrFCPDfUcu5QPd?<(=w6pv1BE#nsxS{n!UnC9qAha1< z;3cpZ9A-e$+Y)%b;w@!!YRA9p%Kf9IHGGg^{+p`mh;q8i7}&e@V3EQaMsItEMS&=X plT@$;k0WcB_jb;cn%_Idz4HO$QU*abf4}+wi?e96N>fbq{{fq~4TJyy literal 0 HcmV?d00001 diff --git a/core/css/images/ui-icons_222222_256x240.png b/core/css/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..b273ff111d219c9b9a8b96d57683d0075fb7871a GIT binary patch literal 4369 zcmd^?`8O2)_s3^phOrG}UnfiUEn8(9QW1?MNkxXVDEpFin2{xWrLx5kBC;k~GmPmYTG^FX}c% zlGE{DS1Q;~I7-6ze&TN@+F-xsI6sd%SwK#*O5K|pDRZqEy< zJg0Nd8F@!OxqElm`~U#piM22@u@8B<moyKE%ct`B(jysxK+1m?G)UyIFs1t0}L zemGR&?jGaM1YQblj?v&@0iXS#fi-VbR9zLEnHLP?xQ|=%Ihrc7^yPWR!tW$yH!zrw z#I2}_!JnT^(qk)VgJr`NGdPtT^dmQIZc%=6nTAyJDXk+^3}wUOilJuwq>s=T_!9V) zr1)DT6VQ2~rgd@!Jlrte3}}m~j}juCS`J4(d-5+e-3@EzzTJNCE2z)w(kJ90z*QE) zBtnV@4mM>jTrZZ*$01SnGov0&=A-JrX5Ge%Pce1Vj}=5YQqBD^W@n4KmFxxpFK`uH zP;(xKV+6VJ2|g+?_Lct7`uElL<&jzGS8Gfva2+=8A@#V+xsAj9|Dkg)vL5yhX@~B= zN2KZSAUD%QH`x>H+@Ou(D1~Pyv#0nc&$!1kI?IO01yw3jD0@80qvc?T*Nr8?-%rC8 z@5$|WY?Hqp`ixmEkzeJTz_`_wsSRi1%Zivd`#+T{Aib6-rf$}M8sz6v zb6ERbr-SniO2wbOv!M4)nb}6UVzoVZEh5kQWh_5x4rYy3c!871NeaM(_p=4(kbS6U#x<*k8Wg^KHs2ttCz<+pBxQ$Z zQMv;kVm5_fF_vH`Mzrq$Y&6u?j6~ftIV0Yg)Nw7JysIN_ z-_n*K_v1c&D}-1{NbBwS2h#m1y0a5RiEcYil+58$8IDh49bPnzE7R8In6P%V{2IZU z7#clr=V4yyrRe@oXNqbqo^^LvlLE?%8XaI&N(Np90-psU}7kqmbWk zZ;YBwJNnNs$~d!mx9oMGyT( znaBoj0d}gpQ^aRr?6nW)$4god*`@Uh2e+YpS@0(Mw{|z|6ko3NbTvDiCu3YO+)egL z>uW(^ahKFj>iJ-JF!^KhKQyPTznJa;xyHYwxJgr16&Wid_9)-%*mEwo{B_|M9t@S1 zf@T@q?b2Qgl!~_(Roe;fdK)y|XG0;ls;ZbT)w-aOVttk#daQcY7$cpY496H*`m@+L zeP#$&yRbBjFWv}B)|5-1v=(66M_;V1SWv6MHnO}}1=vby&9l+gaP?|pXwp0AFDe#L z&MRJ^*qX6wgxhA_`*o=LGZ>G_NTX%AKHPz4bO^R72ZYK}ale3lffDgM8H!Wrw{B7A z{?c_|dh2J*y8b04c37OmqUw;#;G<* z@nz@dV`;7&^$)e!B}cd5tl0{g(Q>5_7H^@bEJi7;fQ4B$NGZerH#Ae1#8WDTH`iB&) zC6Et3BYY#mcJxh&)b2C^{aLq~psFN)Q1SucCaBaBUr%5PYX{~-q{KGEh)*;n;?75k z=hq%i^I}rd;z-#YyI`8-OfMpWz5kgJE3I!3ean6=UZi!BxG7i(YBk? z02HM7wS0)Wni{dWbQMRtd-A)_Az!t>F;IwWf~!*)-Az4}yryNkz&9)w>ElA80Oc`6 zHo#9H!Y3*Qx9n@Jn)!w6G^hb;e_n8zpIyXCN`JFkPc)^Q?2MsLNFhMgrcZI-<#1ne zjH;KFf?4eAT9mQZ}ZfHLGA#d%s;SZK4p0FwZT2S^{ zQ2BG1xJsbK6?yrHTjJi|5C0u=!|r!?*4FL%y%3q#(d+e>b_2I9!*iI!30}42Ia0bq zUf`Z?LGSEvtz8s``Tg5o_CP(FbR0X$FlE0yCnB7suDPmI2=yOg^*2#cY9o`X z;NY-3VBHZjnVcGS){GZ98{e+lq~O$u6pEcgd0CrnIsWffN1MbCZDH<7c^hv+Z0Ucf0{w zSzi^qKuUHD9Dgp0EAGg@@$zr32dQx>N=ws`MESEsmzgT2&L;?MSTo&ky&!-JR3g~1 zPGTt515X)wr+Bx(G9lWd;@Y3^Vl}50Wb&6-Tiy;HPS0drF`rC}qYq22K4)G#AoD0X zYw$E+Bz@Zr^50MAwu@$?%f9$r4WHH?*2|67&FXFhXBrVFGmg)6?h3^-1?t;UzH0*I zNVf9wQLNLnG2@q>6CGm>&y|lC`iCFfYd}9i%+xkl^5oBJ?<;aneCfcHqJh7Yl5uLS z9Fx-(kMdcNyZejXh22N{mCw_rX1O!cOE&3>e(ZH81PR95wQC37En4O{w;{3q9n1t&;p)D%&Z%Nw$gSPa!nz8Slh7=ko2am)XARwOWw zpsz0~K!s{(dM$NB=(A=kkp>T(*yU6<_dwIx>cH4+LWl282hXa6-EUq>R3t?G2623< z*RwTN%-fgBmD{fu*ejNn)1@KG?Sg*8z3hYtkQJQjB6 zQ|x>wA=o$=O)+nLmgTXW3_6diA;b4EY{*i*R%6dO2EMg z@6g?M3rpbnfB@hOdUeb96=~I?OIA3@BWAGmTwiQ{x5Cqq<8c10L!P zd@Qk^BseTX%$Q7^s}5n%HB|)gKx}H$d8Sb$bBnq9-AglT2dGR2(+I;_fL|R4p$odJ zllfb0NqI)7=^z~qAm1V{(PkpxXsQ#4*NH9yYZ`Vf@)?#ueGgtCmGGY|9U#v|hRdg- zQ%0#cGIfXCd{Y)JB~qykO;KPvHu|5Ck&(Hn%DF~cct@}j+87xhs2ew;fLm5#2+mb| z8{9e*YI(u|gt|{x1G+U=DA3y)9s2w7@cvQ($ZJIA)x$e~5_3LKFV~ASci8W}jF&VeJoPDUy(BB>ExJpck;%;!`0AAo zAcHgcnT8%OX&UW_n|%{2B|<6Wp2MMGvd5`T2KKv;ltt_~H+w00x6+SlAD`{K4!9zx z*1?EpQ%Lwiik){3n{-+YNrT;fH_niD_Ng9|58@m8RsKFVF!6pk@qxa{BH-&8tsim0 zdAQ(GyC^9ane7_KW*#^vMIoeQdpJqmPp%%px3GIftbwESu#+vPyI*YTuJ6+4`z{s? zpkv~0x4c_PFH`-tqafw5)>4AuQ78SkZ!$8}INLK;Egr;2tS18hEO5=t;QDmZ-qu?I zG+=DN`nR72Xto{{bJp||`k}-2G;5#xg8E~xgz22)^_Z;=K|4@(E&5J)SY2of=olcw z5)@L)_Ntcm!*5nEy0M9v0`S33;pO4TN;>4(Z+19p_0>u#e-vE zXCU(6gAvu~I7Cw(xd%0e59MNLw^U37ZDbsBrj%eDCexw8a3G`nTcXVNL6{B7Hj@i& zbVB{;ApEtHk76q08DJ48dSxd$C(;$K6=FpU<~l9pVoT9arW^Vu{%Bcn4`eIpkOVC| z$)AKYG_`ypM{0@BUb3^9lqi_c?ONH|4UJMJWDowMVjacycX7}9g={O7swOB+{;+?; zjBo!9?+nd)ie#x5IbFW-zBOo0c4q@9wGVt5;pNt`=-~Zgcw#*`m($6ibxtZ`H=e=} zF#GZ~5$%AUn};8U#tRem0J(JTR}d4vR(dgK2ML~lZsPhayJ2h1%sD4FVst| zKF)+@`iNzLRjg4=K8@**0=5cE>%?FDc({I^+g9USk<8$&^qD~@%W0i4b|yMG*p4`N zh}I!ltTRI8Ex$+@V{02Br%xq#O?UlhO{r8WsaZnZCZq0MK9%AXU%MDLT;3=0A9(BV z9VxxxJd7jo$hw3q;3o?yBLmA=azBUrd9>-<_ANs0n3?-Ic*6&ytb@H~?0E(*d>T5n z-HiH2jsDf6uWhID%#n>SzOqrFCPDfUcu5QPd?<(=w6pv1BE#nsxS{n!UnC9qAha1< z;3cpZ9A-e$+Y)%b;w@!!YRA9p%Kf9IHGGg^{+p`mh;q8i7}&e@V3EQaMsItEMS&=X plT@$;k0WcB_jb;cn%_Idz4HO$QU*abf4}+wi?e96N>fbq{{i|W0@(ln literal 0 HcmV?d00001 diff --git a/core/css/images/ui-icons_ffd27a_256x240.png b/core/css/images/ui-icons_ffd27a_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..e117effa3dca24e7978cfc5f8b967f661e81044f GIT binary patch literal 4369 zcmd^?`8O2)_s3@pGmLE*`#M>&Z`mr_kcwz5Nh&g=McJ3E!;CE1E0ryV5Ro;>nvtvt zk&I==Xd;cVGZ@>q_xtnx{1u%7-D)N|5YqOB>i;(bZ#o62{J2Y9&^D3~R^$o+X? zwbxAEIb)xwCwK3TSR4QVym6N1rVgPmmt0caryBUceHP_&u}{?^Jn7f0PT$#h>UDqI zr!q(F&1jJ2_!jxdAB<)7H$foI*2zuncvu;;$SoU7br=AiJ@4=BC4vNO>DS`&UIB=K z;2)0F*t^FBvVfPuT4FVMSwUw%Xksjyl+;#*DDy%=ocFOyzDLvLR(`zCSOuJ=?FWYn z5ZD!UaoF>-$@=Vt?a&;UQYM$Oqe0ZB?Je?8ZnMxDe&uzzs*zlHd)V58nfJPc8S^({_4bj5HQ_B&EXHWj6wx@B;!mr04b_Mx)UFL)W7`V!c zpMp#C!a!!sh3h491y}^qfimXVY%!+sYu0_DWoJMqpN(FR9LM#jdZ{vJzEck`P^9(1N=4J za9%u4$2J8TAkUaJk_FX%iHuv#svL_mMmp{SR}ifc#ZcXv%CFsT?*>N^6r(%D?1YnU zAaT?UZGlOna6UXXs0m)3YDp}d%hb@)@Y!lK_A&D6{OPlNnj zYY*$b>vnRzL8=CDbQSi!DL3D!P^xhNtwrYByo?h-&OvQZYJ6ka{Re# zSc0ry_d(K$_Q2M{Y^O~DOK(szDOnMi_*h_Rx%eSRxA%n|FuC&=F=)B z_Qsgmj8g!GA+LZOX)gOW}vbo9|l8QW3iYw9qCD{o~xt^HIU>;dV5MJgc0#uHTA z80%Ee_r;G`GUjssm z*AhtwpW%Ly;X4Lq1Zq#ZpuwzrZE$sR087dN{w7PA6|Mo#6wwJP085K+h7+D>NyeX# zk|?MJ^Es)JtP-2eNr0EQe*ZM`&}OU zCD*uSSviE&p}uX|@1g_%|3*ra*MbBV#~cshdcFQ(dGLnTqaO-3{u==x1;Pp2im!#` zuZ2`ThfAmiSzb|4h`c4?^ZoGOF*oXYcV}(ge!v@^bse?daA`Ma+bSZLIg;pIN17vM zIOYfK=@s_Pj?~#lqnY2o?d1$MpoqsYQw%eX%X6Y4*^27{hMWGqILEMnVYUEMW#x7f zu^I*nzXQ@6HJ8n;26 zo^1+Ewi$fN$Unum1(FTb8I#cYgcGklwIExt#Mb(D=x~OTeZ^ubJ)S-ywfdZS?SRCq zDm=eU+CCWO@8S_m!W{alT)zj zZJbjxm5&No5xe_~Jw-i7`&G}=r)POGGfFq+c@kQbB#)ay`coj&C3- z(#&xV@Q3@VJd{qdH4g@4ZJi&mx9e@Io7@~(o5vTrkW>QEO1T-gmlTRHH+3)gcUC0P zk07rvDnf*7Y5J}8!>F_7D^Z3IoH^uGH}_a(ax{Q(IrvV$olf3WN&DY?uYZfvXI(;Vv&EAoQtfH;+4VI_a>yh*J+Cj!?h!QX?O`QXk@@G7AjloJe51Cw*rPXQ>#y?B^^ExRQFui zolmv*C5K|-p){rZiCNai^0H`1(Qr(Hz3v%7NnmriXu2tD>xsbN#*R3*wsZhRj6Lvb zn0Cu=qkC?*e4{NF_3=^bTb1f!g?@ryFH6Zw2tz%A zzz&o{w`dDv66!6Wk9w1-dglS#Sm{doxw&h5Z8&ONmlBBte{J)puaDzc!LC==rPRQK zQNH23?-rIo^MQdt3Tk!B@8l#}fxVtrlc8Y<>ORaVE($DKc{77qV^`+`%_DotrUD=8 z4}L7QnZi3RgUy*tteY-=$SqA2@IZWe(}mI`nzhAT{qC)my#rJsfoS*)xCXj!Tk6=3)cr@Jw#OcNqgS3pg7x|4!A$|w15X!huR*vB3q9Ya4 zF{xuzEQz{9YPl(gk`}Gffut%jotgqp$jZvzRO4EsExf~93vY~04AxH=lR>R3v3Qs2 zy$v4SN%ee@Kz#kDtARaQD`d!R%}#@T1=v8DAow*r>+0d1KS{ZtA~KMtgm)+$JHumW zw=;@qWk&MuG@LKx#K3@&WMw?r=jD2_)(*$LmkCm4_@};QZI|SPe8hIC6xqBy!LQyK z01_xmfNA9UlBU@Kzu7;zQYxHE>OCADA$gwaVqm`eN?XQF@NkrocB}lU4hcCf>wqir z>Ya=PcE!Xm#JG8v@G0lj&~)hScM}X57vGw3g<$^SUls53f|Bk>5FQwqE&{%u(f$!1 zl8+53vyYZ`mEEp&YT<=(krhKrw?~pS{N)?q{0qBR#2Y!w4!hWMdj`a(@A@r$zVB+u z06Hb@_9(cQ_AxbXI|-2w>#QUhp7k<+`z9+(jkh~v-Renr#C9U+&jL4vg6-E$f7@UU z(1fxB8{U2vq}h3rE!Z+n7=(>D&}@9~3mJ^R5}|WVG@!RSh3r{!>QHwg!t29YS&jiR ztyn_q*k9H0efZ7hO*b(WR|G!TDY`rol~Ob4&1OwdM8kbGj`^$~L5gdWYceWwL=PB{~NX=cu3p-{S;hqaE?bSHv$g+SA6bxy+VU3YVTPDj6CN zKLb_(9gM2Y#KW8ONxjH9To^Y)r?ql2cq8+WE438uIF$hjfdLs6-;!jv55jGcc3Ipg z;}aT32NAEGeU;J}&j5=+u`4?%xlwL7?NDn%2={4WS39yn3f;&r=|}5=M-Y2yrxeSw zv%*PmV{_{#Qk1sD>?M2KDapb~z3!E*-LPmCe9q86D%MGSe;4~~K-jKQxq6b^902_{ z%>4G>@Xqk8muR*|vGe5{@7sds2i|i;g}oMkd!o^0=HG+vcPrcN54A zLGv$PlTePRxp~-OSb_*aACO1qc{MpfS-fv(@UmRv%UO)cSt;ee@9(S)f>|~bwU@eZ z=kTS*sdjLclwMZG#?%U3)bq-uj?@@vj~6tq)ZS||Jxz`+di-M5SXM=h3EL`?pB>W9A;`V2vM)vk&%KFy|TAh#AQA zb_?J==3f@%LL{`vU$3Z@A2a9C3aC-YY43dR> pI7J0n@;b3~`)ubvsr|iU(l;L{A#E6J`}eC4usn-0uQEf&{2ws1m(ltoqJ#RmwV2==ic*rz7lOw=eaq=H~;_ux21)-Jpcgw zdj+hrf&W^f<%Qk9Zpqf#;q3n5{{POY;f!wmTR1An9(4&I0z1LNX50QSTV2M%4|y9c z#{ZQIVJKu~aY5?ZaZP*GIGqGs=e@q6o|EPhZB3CC?@LnORK8O@z{{<0KtSn5?#~OW zy=L;x8T&*%xqElS;s5~Pjk7d2bqIaA)xZbovnZd7eX17WNxx=w`p(8vulwUZ zl{so}MuRNJx5!8S5G;$o2?BApPHt+)!^#*Ww`?rcVE}mcyuY`X2o|uVUyI9o1t11O zemGWR?;aD#0$vJhiPhv~0iXS#iLq!>Qd$` zU{}<|Vb9Md>$4TMbL7C3GP#r;4Wc$}Z;^j;n}yc!E3d;`wry$!JkmJP0%(tIh!!TET8=+{rhUi^60G0t2HJSxXv-*DgC(HrJd8`|Dp3NvL5yg>xAvU zho|fEA~w^-HrW&H-JwkqNX2I-bEXBR&Uhp+y2^)1h1IIlNCzC!v-Mz@&z&VPz+cl1 z=f&f6Y*U~C`ixm4Sy1hl$hg(4%Dy;bq~k7d1<@K&%%NLT`L+A)-QXyKVswX?op90( zB#yeFEih@c{OXU8Oq~1CFI_38GXmns3(`;W(i+bslovCx4u7gvK>DrGOug*?G|1nz z_OR}|ZYS3pq-p?rS7G0qa`TM}r5XqDT4cV>%Qyk#9ES}`jc+Ww|DcbZrF6UG>CeXp zOVIV}K1e#z9@tu#?X)Ri=?zXMB`X3G-_I7FL-Zq`nbfWtX_EO1*!+U6pJW-_k&+vk zMd}THh}{(Ch_wPk(PI4vVB_KT76kGxVytLxpWg}&bHw`a3G#QzxV@ICNax&@hk3<_ zBh`Tq66G{-tCw$V{(y0v7l!tp20~@gdFXjzFbF#bJE7i>T4ux zQdrF3org^wFcnw$#bQMv@SfN3$Fuo7HnB_`2ZGB{ZqGr>%xP;2_!Q{=N-ZhU1c~^5 zdt=OO#wmcpkXJyCG?{{&n=R{Sn=Ytg;<09CH)l7TA&wkt{Q;>RrA2Ia6-QixEPLrU z%0)N$3Nh0?U825&v($Sz}0G_(!v&xSSAzje4{rup+^W@^}ByqOb95$E0sbwK*%#GP}!6`%*Z@L;&C z3^dE&>5%bWAXmP*X1 z_m}Pivs*u7@9i>qA!58fDCwj^M<1P(u^m;urVdlM@>aIf+E3-d9ZW>fc4cS7w5O3sCmKKn z+94A?VyfSBb9{}rEbCIYtXORJBCv__fnZ>?a}edaA%bP$jI?J^q0UKO!mduA8U!3b z0CJ_Js}NWQZoebapVUHP%pPOUm?1<)zd%`hzUM-Y6g1z|@@3G_kio?S0bcbjQuxJd>vU$Uyz(4*peEDSVc-G;O;% z9Y97%Tq}TRsH+oN%2u(oyC=W<9`e@&m;i;jC%L;sP(9RBDQnth3;ZMEQNFH3GEf0c zU<3RF!hNG-vCDooYFS^nPlFnv4(ElI1=vNcr42TF^uq67f{MoN>{f&>xA91r4pz5Zc&@P^i-9||`98v$Si!U@}ouZ88W zg;YL=OQ;4}UQtkpyd~lD{qWy0H|lwJXKmenz#E=*9kt$YX*X!wDk7ITlIUGWnj>a7 z<_GQR752@J)Y(U)ncu(dIit7P}oBq8x$FP85)&Nsw<#rOW z8U_x(1J)Zgm(8tZXU%+(yYcO+Z7#ZszPwa2`ygiMPayX9KondtFMRK!7x`9uWN;(f zfWW?8yOdj;GA3We0YAW92gWipn(d>zcbA+vZ_21BxF?-pfcW` zbqY??6ie(6M)p@6@WQ?Tl7 zoKrKEj|x~2yZehhMLkFRRnOC>XL&L+N;m0B{_OQ9gzzTYb!!Jct=bk?_hIpY9rOwY zMnr69R(?8EN52qR+k!~qnCYc-KmV&*d$&NY?t5cjR)V+ncMor=puTRoo?{5dH;@!* z<~RrV!+ljAN+;Qx2LraY&JWnz^|sYbZjP+Y;|pC#DuHUH+>F~x3PqTkx)=OAE0X9( z(AO6gp~AH^{nq+n)LHYDD8mQN?DDFcd!U&d4PaajzSD1~lXq3p{x=^vItrq3gD^4O z=hYS`?&C-0&KuAV>Jv}T?ba0IafL$~+bZ}p$9lwyyx=-uPN`Hpvv<)Ia>OWHa4+N4 z6zscrW$^XA32EJw^7hYtkRJr{Q8 zQ|*1pp_q6Mno|D6EX!kgSv0h0I3~ef_l%$DTFjL`0y16n%^dGNQn;2V82mqoIi9i{15vu zLq&(BTl9CInUjZlTIa>^!!HlMK3W8Sd_Ow0+E8IT?h$=55$^Z)$WYIuig=O;Lp_1Q z4wOT;XbWQ!>Mh`pdXuSo=KBba;wT!wK`Hf1Ueh04*%D7Kfj*#b~BNfvz zsbf?uiMm5-xhaQ|7Om2OrYbU>ngUM9%F5nU<65IFyu(`yZ;Vb1)=wCd!L2K?c$ezE z4IbS|^?Z>)eEp}ZfjwF)Waw?pPJ?{~*g%;efxO~Nx7dQGLWZ)cPQ*T!((W- zGm2?tM)K}7oG<0Xz<`ltWjxvE<$AH!4*R{A2~uYGr@m!vm*j+e#CE9^*}Oc#uihB| z5;#kMY2^8mrr80%*+02bDx6B{Jsch(d7kQGV7~iGTgFZBu$Pf`tNf`B2{|t7fGhIq zos0xF#l$bfxOtcGDd*MDbdKBaCKxgCEbr8JTNd_1bjWC{Ubgk z9~)9;A1&=FyIt$l!VBXfD~6VCk0fjO%QwLJ7k00RH*%I8cCqF542VzP^;`OU-_?=< zbV}OoQE)HqV`|)X5+WbgSxGWH>t+7-O;(l~Z+FJJ)sygu^+eF01#Suj+pnAcw!s>p z$-xF}c>7t9X6H$^V9hvT5H{jKv+=zzWHA0pgw8e5fZpm9vIphVq3%S4*N3%&jsY^Q zK%sSPuj=?d{ATs0o0y6#0w3%YT^@-_sTuTUwI(Q{;l3KjeAbVk#Wmi%PDxm`zoqQ~ z((<-}*FSP%5gt7uI3t1&75ne{@1^bpdW1;MMGNkSr~UAuDbB4+VQi|x(gdO^zin_) zncfs2hj8xdiiy)@vVkfkItLKvsGtJhrTb0T~tFl4Q3J!flauS==b& z6Bm!g%dDvlCf(St$kVofvH90|9yl-gmvRvcKS&Ye9DdoTK@2m}iSvC{3m%4E0 z@TJD7c1V?!URM7+t?f3)%{X(6JXg~A9TvGQyX6n(^Yt0NX;>vDPcr~mICPooLWA_` z<1A>FuXr|C)dtDr*PQt%Xs5WePWUB&gBj$zZ#BIY%?jDdpbSA-PV0`dGf^oa_Jp}Z zlrGV7oe`#B^+nPIQ`ZDJeJas=ru#=*YL#+n?Go}f33>1GsZ{TTy2bdBihj}mz*mp! zOzn%{WgLM=*CpiuKUs*GnHa{B$2siJqfNi|Z;|rH%stM*8b26kAMCYY&NHwPGtlYn z7UVx_^sgR$Z8x27foS63FCPt|gtcG_ zy#@C|!VQV~TY}G5e57qp?F4jRxqq~@h6^?-cvD>ySwVLl2m7=gERtEn>Fw_@ND%pO oiVC*mbz<%I+0K1Z`+LWvZ$3~$+A!Gm?^hpSc@||}WrmLVKLvuzv;Y7A literal 0 HcmV?d00001 diff --git a/core/css/jquery-ui-1.10.0.custom.css b/core/css/jquery-ui-1.10.0.custom.css new file mode 100644 index 0000000000..71b3979aa8 --- /dev/null +++ b/core/css/jquery-ui-1.10.0.custom.css @@ -0,0 +1,1174 @@ +/*! jQuery UI - v1.10.0 - 2013-01-22 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=%22Lucida%20Grande%22%2C%20Arial%2C%20Verdana%2C%20sans-serif&fwDefault=bold&fsDefault=1em&cornerRadius=4px&bgColorHeader=1d2d44&bgTextureHeader=01_flat.png&bgImgOpacityHeader=35&borderColorHeader=1d2d44&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f8f8f8&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=ddd&fcDefault=555&iconColorDefault=1d2d44&bgColorHover=ffffff&bgTextureHover=01_flat.png&bgImgOpacityHover=100&borderColorHover=ddd&fcHover=333&iconColorHover=1d2d44&bgColorActive=f8f8f8&bgTextureActive=02_glass.png&bgImgOpacityActive=100&borderColorActive=1d2d44&fcActive=1d2d44&iconColorActive=1d2d44&bgColorHighlight=f8f8f8&bgTextureHighlight=04_highlight_hard.png&bgImgOpacityHighlight=100&borderColorHighlight=ddd&fcHighlight=555&iconColorHighlight=ffffff&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px +* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:Alpha(Opacity=0); +} + +.ui-front { + z-index: 100; +} + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; +} + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; +} + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin-top: 2px; + padding: .5em .5em .5em .7em; + min-height: 0; /* support: IE7 */ +} +.ui-accordion .ui-accordion-icons { + padding-left: 2.2em; +} +.ui-accordion .ui-accordion-noicons { + padding-left: .7em; +} +.ui-accordion .ui-accordion-icons .ui-accordion-icons { + padding-left: 2.2em; +} +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { + position: absolute; + left: .5em; + top: 50%; + margin-top: -8px; +} +.ui-accordion .ui-accordion-content { + padding: 1em 2.2em; + border-top: 0; + overflow: auto; +} +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: default; +} +.ui-button { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + margin-right: .1em; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ +} +.ui-button, +.ui-button:link, +.ui-button:visited, +.ui-button:hover, +.ui-button:active { + text-decoration: none; +} +/* to make room for the icon, a width needs to be set here */ +.ui-button-icon-only { + width: 2.2em; +} +/* button elements seem to need a little more width */ +button.ui-button-icon-only { + width: 2.4em; +} +.ui-button-icons-only { + width: 3.4em; +} +button.ui-button-icons-only { + width: 3.7em; +} + +/* button text element */ +.ui-button .ui-button-text { + display: block; + line-height: normal; +} +.ui-button-text-only .ui-button-text { + padding: .4em 1em; +} +.ui-button-icon-only .ui-button-text, +.ui-button-icons-only .ui-button-text { + padding: .4em; + text-indent: -9999999px; +} +.ui-button-text-icon-primary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: .4em 1em .4em 2.1em; +} +.ui-button-text-icon-secondary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: .4em 2.1em .4em 1em; +} +.ui-button-text-icons .ui-button-text { + padding-left: 2.1em; + padding-right: 2.1em; +} +/* no icon support for input elements, provide padding by default */ +input.ui-button { + padding: .4em 1em; +} + +/* button icon element(s) */ +.ui-button-icon-only .ui-icon, +.ui-button-text-icon-primary .ui-icon, +.ui-button-text-icon-secondary .ui-icon, +.ui-button-text-icons .ui-icon, +.ui-button-icons-only .ui-icon { + position: absolute; + top: 50%; + margin-top: -8px; +} +.ui-button-icon-only .ui-icon { + left: 50%; + margin-left: -8px; +} +.ui-button-text-icon-primary .ui-button-icon-primary, +.ui-button-text-icons .ui-button-icon-primary, +.ui-button-icons-only .ui-button-icon-primary { + left: .5em; +} +.ui-button-text-icon-secondary .ui-button-icon-secondary, +.ui-button-text-icons .ui-button-icon-secondary, +.ui-button-icons-only .ui-button-icon-secondary { + right: .5em; +} + +/* button sets */ +.ui-buttonset { + margin-right: 7px; +} +.ui-buttonset .ui-button { + margin-left: 0; + margin-right: -.3em; +} + +/* workarounds */ +/* reset extra padding in Firefox, see h5bp.com/l */ +input.ui-button::-moz-focus-inner, +button.ui-button::-moz-focus-inner { + border: 0; + padding: 0; +} +.ui-datepicker { + width: 17em; + padding: .2em .2em 0; + display: none; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: .2em 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 2px; + width: 1.8em; + height: 1.8em; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 1px; +} +.ui-datepicker .ui-datepicker-prev { + left: 2px; +} +.ui-datepicker .ui-datepicker-next { + right: 2px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 1px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 1px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin: 1px 0; +} +.ui-datepicker select.ui-datepicker-month-year { + width: 100%; +} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 49%; +} +.ui-datepicker table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em; +} +.ui-datepicker th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible; +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + width: 100%; + font-size: 0; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} +.ui-dialog { + position: absolute; + top: 0; + left: 0; + padding: .2em; + outline: 0; +} +.ui-dialog .ui-dialog-titlebar { + padding: .4em 1em; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: .1em 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 21px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: .5em 1em; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + margin-top: .5em; + padding: .3em 1em .5em .4em; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: .5em .4em .5em 0; + cursor: pointer; +} +.ui-dialog .ui-resizable-se { + width: 12px; + height: 12px; + right: -5px; + bottom: -5px; + background-position: 16px 16px; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} +.ui-menu { + list-style: none; + padding: 2px; + margin: 0; + display: block; + outline: none; +} +.ui-menu .ui-menu { + margin-top: -3px; + position: absolute; +} +.ui-menu .ui-menu-item { + margin: 0; + padding: 0; + width: 100%; +} +.ui-menu .ui-menu-divider { + margin: 5px -2px 5px -2px; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0; +} +.ui-menu .ui-menu-item a { + text-decoration: none; + display: block; + padding: 2px .4em; + line-height: 1.5; + min-height: 0; /* support: IE7 */ + font-weight: normal; +} +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} + +.ui-menu .ui-state-disabled { + font-weight: normal; + margin: .4em 0 .2em; + line-height: 1.5; +} +.ui-menu .ui-state-disabled a { + cursor: default; +} + +/* icon support */ +.ui-menu-icons { + position: relative; +} +.ui-menu-icons .ui-menu-item a { + position: relative; + padding-left: 2em; +} + +/* left-aligned */ +.ui-menu .ui-icon { + position: absolute; + top: .2em; + left: .2em; +} + +/* right-aligned */ +.ui-menu .ui-menu-icon { + position: static; + float: right; +} +.ui-progressbar { + height: 2em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + background: url("images/animated-overlay.gif"); + height: 100%; + filter: alpha(opacity=25); + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} +.ui-slider { + position: relative; + text-align: left; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 1.2em; + height: 1.2em; + cursor: default; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0; +} + +/* For IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: .8em; +} +.ui-slider-horizontal .ui-slider-handle { + top: -.3em; + margin-left: -.6em; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: .8em; + height: 100px; +} +.ui-slider-vertical .ui-slider-handle { + left: -.3em; + margin-left: 0; + margin-bottom: -.6em; +} +.ui-slider-vertical .ui-slider-range { + left: 0; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} +.ui-spinner { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; +} +.ui-spinner-input { + border: none; + background: none; + color: inherit; + padding: 0; + margin: .2em 0; + vertical-align: middle; + margin-left: .4em; + margin-right: 22px; +} +.ui-spinner-button { + width: 16px; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to overide default borders */ +.ui-spinner a.ui-spinner-button { + border-top: none; + border-bottom: none; + border-right: none; +} +/* vertical centre icon */ +.ui-spinner .ui-icon { + position: absolute; + margin-top: -8px; + top: 50%; + left: 0; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} + +/* TR overrides */ +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position: -65px -16px; +} +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ + padding: .2em; +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px .2em 0 0; + border-bottom: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav li a { + float: left; + padding: .5em 1em; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, +.ui-tabs .ui-tabs-nav li.ui-state-disabled a, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading a { + cursor: text; +} +.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em 1.4em; + background: none; +} +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +body .ui-tooltip { + border-width: 2px; +} + +/* Component containers +----------------------------------*/ +.ui-widget { + font-family: "Lucida Grande", Arial, Verdana, sans-serif; + font-size: 1em; +} +.ui-widget .ui-widget { + font-size: 1em; +} +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-family: "Lucida Grande", Arial, Verdana, sans-serif; + font-size: 1em; +} +.ui-widget-content { + border: 1px solid #dddddd; + background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; + color: #333333; +} +.ui-widget-content a { + color: #333333; +} +.ui-widget-header { + border: 1px solid #1d2d44; + background: #1d2d44 url(images/ui-bg_flat_35_1d2d44_40x100.png) 50% 50% repeat-x; + color: #ffffff; + font-weight: bold; +} +.ui-widget-header a { + color: #ffffff; +} + +/* Interaction states +----------------------------------*/ +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default { + border: 1px solid #ddd; + background: #f8f8f8 url(images/ui-bg_glass_100_f8f8f8_1x400.png) 50% 50% repeat-x; + font-weight: bold; + color: #555; +} +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited { + color: #555; + text-decoration: none; +} +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus { + border: 1px solid #ddd; + background: #ffffff url(images/ui-bg_flat_100_ffffff_40x100.png) 50% 50% repeat-x; + font-weight: bold; + color: #333; +} +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited { + color: #333; + text-decoration: none; +} +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active { + border: 1px solid #1d2d44; + background: #f8f8f8 url(images/ui-bg_glass_100_f8f8f8_1x400.png) 50% 50% repeat-x; + font-weight: bold; + color: #1d2d44; +} +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + color: #1d2d44; + text-decoration: none; +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #ddd; + background: #f8f8f8 url(images/ui-bg_highlight-hard_100_f8f8f8_1x100.png) 50% top repeat-x; + color: #555; +} +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a { + color: #555; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #cd0a0a; + background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; + color: #ffffff; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a { + color: #ffffff; +} +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #ffffff; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .7; + filter:Alpha(Opacity=70); + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .35; + filter:Alpha(Opacity=35); + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:Alpha(Opacity=35); /* For IE8 - See #6059 */ +} + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + width: 16px; + height: 16px; + background-position: 16px 16px; +} +.ui-icon, +.ui-widget-content .ui-icon { + background-image: url(images/ui-icons_222222_256x240.png); +} +.ui-widget-header .ui-icon { + background-image: url(images/ui-icons_ffffff_256x240.png); +} +.ui-state-default .ui-icon { + background-image: url(images/ui-icons_1d2d44_256x240.png); +} +.ui-state-hover .ui-icon, +.ui-state-focus .ui-icon { + background-image: url(images/ui-icons_1d2d44_256x240.png); +} +.ui-state-active .ui-icon { + background-image: url(images/ui-icons_1d2d44_256x240.png); +} +.ui-state-highlight .ui-icon { + background-image: url(images/ui-icons_ffffff_256x240.png); +} +.ui-state-error .ui-icon, +.ui-state-error-text .ui-icon { + background-image: url(images/ui-icons_ffd27a_256x240.png); +} + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl { + border-top-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr { + border-top-right-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl { + border-bottom-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br { + border-bottom-right-radius: 4px; +} + +/* Overlays */ +.ui-widget-overlay { + background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; + opacity: .5; + filter: Alpha(Opacity=50); +} +.ui-widget-shadow { + margin: -5px 0 0 -5px; + padding: 5px; + background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; + opacity: .2; + filter: Alpha(Opacity=20); + border-radius: 5px; +} diff --git a/core/css/jquery-ui-1.8.16.custom.css b/core/css/jquery-ui-1.8.16.custom.css deleted file mode 100644 index add1c6af08..0000000000 --- a/core/css/jquery-ui-1.8.16.custom.css +++ /dev/null @@ -1,362 +0,0 @@ -/* - * jQuery UI CSS Framework 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } -.ui-helper-clearfix { display: inline-block; } -/* required comment for clearfix to work in Opera \*/ -* html .ui-helper-clearfix { height:1%; } -.ui-helper-clearfix { display:block; } -/* end clearfix */ -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/* - * jQuery UI CSS Framework 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault="Lucida%20Grande",%20Arial,%20Verdana,%20sans-serif&fwDefault=bold&fsDefault=1em&cornerRadius=4px&bgColorHeader=1d2d44&bgTextureHeader=01_flat.png&bgImgOpacityHeader=35&borderColorHeader=1d2d44&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f8f8f8&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=ddd&fcDefault=555&iconColorDefault=1d2d44&bgColorHover=ffffff&bgTextureHover=01_flat.png&bgImgOpacityHover=100&borderColorHover=ddd&fcHover=333&iconColorHover=1d2d44&bgColorActive=f8f8f8&bgTextureActive=02_glass.png&bgImgOpacityActive=100&borderColorActive=1d2d44&fcActive=1d2d44&iconColorActive=1d2d44&bgColorHighlight=f8f8f8&bgTextureHighlight=04_highlight_hard.png&bgImgOpacityHighlight=100&borderColorHighlight=ddd&fcHighlight=555&iconColorHighlight=ffffff&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px - */ - - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: \\\"Lucida Grande\\\", Arial, Verdana, sans-serif; font-size: 1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: \\\"Lucida Grande\\\", Arial, Verdana, sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee; color: #333333; } -.ui-widget-content a { color: #333333; } -.ui-widget-header { border: 1px solid #1d2d44; background: #1d2d44; color: #ffffff; font-weight: bold; } -.ui-widget-header a { color: #ffffff; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #ddd; background: #f8f8f8; font-weight: bold; color: #555; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #ddd; background: #ffffff; font-weight: bold; color: #333; } -.ui-state-hover a, .ui-state-hover a:hover { color: #333; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #1d2d44; background: #f8f8f8; font-weight: bold; color: #1d2d44; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #1d2d44; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - -/* states and images */ -.ui-icon { width: 16px; height: 16px; } -.ui-icon-closethick { background-image: url(../img/actions/delete.png); } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } -.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } - -/* Overlays */ -.ui-widget-overlay { background: #666666; opacity: .50;filter:Alpha(Opacity=50); } -.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* - * jQuery UI Resizable 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizable#theming - */ -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* - * jQuery UI Selectable 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectable#theming - */ -.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } -/* - * jQuery UI Autocomplete 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu 1.8.16 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/* - * jQuery UI Button 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/* - * jQuery UI Dialog 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog#theming - */ -.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; background-color: #EEE;} -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } -/* - * jQuery UI Slider 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider#theming - */ -.ui-slider { position: relative; text-align: left; } -.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } -.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } - -.ui-slider-horizontal { height: .8em; } -.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: .8em; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; }/* - * jQuery UI Tabs 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs#theming - */ -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } -.ui-tabs .ui-tabs-hide { display: none !important; } -/* - * jQuery UI Datepicker 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ -}/* - * jQuery UI Progressbar 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar#theming - */ -.ui-progressbar { height:2em; text-align: left; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/core/js/jquery-ui-1.10.0.custom.js b/core/js/jquery-ui-1.10.0.custom.js new file mode 100644 index 0000000000..ca57f47ede --- /dev/null +++ b/core/js/jquery-ui-1.10.0.custom.js @@ -0,0 +1,14850 @@ +/*! jQuery UI - v1.10.0 - 2013-01-22 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js +* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */ + +(function( $, undefined ) { + +var uuid = 0, + runiqueId = /^ui-id-\d+$/; + +// prevent duplicate loading +// this is only a problem because we proxy existing functions +// and we don't want to double proxy them +$.ui = $.ui || {}; +if ( $.ui.version ) { + return; +} + +$.extend( $.ui, { + version: "1.10.0", + + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + } +}); + +// plugins +$.fn.extend({ + _focus: $.fn.focus, + focus: function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + this._focus.apply( this, arguments ); + }, + + scrollParent: function() { + var scrollParent; + if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { + scrollParent = this.parents().filter(function() { + return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); + }).eq(0); + } else { + scrollParent = this.parents().filter(function() { + return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); + }).eq(0); + } + + return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + //
                + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; + }, + + uniqueId: function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + (++uuid); + } + }); + }, + + removeUniqueId: function() { + return this.each(function() { + if ( runiqueId.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + }); + } +}); + +// selectors +function focusable( element, isTabIndexNotNaN ) { + var map, mapName, img, + nodeName = element.nodeName.toLowerCase(); + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap=#" + mapName + "]" )[0]; + return !!img && visible( img ); + } + return ( /input|select|textarea|button|object/.test( nodeName ) ? + !element.disabled : + "a" === nodeName ? + element.href || isTabIndexNotNaN : + isTabIndexNotNaN) && + // the element and all of its ancestors must be visible + visible( element ); +} + +function visible( element ) { + return $.expr.filters.visible( element ) && + !$( element ).parents().addBack().filter(function() { + return $.css( this, "visibility" ) === "hidden"; + }).length; +} + +$.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + }, + + focusable: function( element ) { + return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); + }, + + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + isTabIndexNaN = isNaN( tabIndex ); + return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); + } +}); + +// support: jQuery <1.8 +if ( !$( "
                " ).outerWidth( 1 ).jquery ) { + $.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; + } + }); + return size; + } + + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each(function() { + $( this ).css( type, reduce( this, size ) + "px" ); + }); + }; + + $.fn[ "outer" + name] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; + }); +} + +// support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) +if ( $( "" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { + $.fn.removeData = (function( removeData ) { + return function( key ) { + if ( arguments.length ) { + return removeData.call( this, $.camelCase( key ) ); + } else { + return removeData.call( this ); + } + }; + })( $.fn.removeData ); +} + + + + + +// deprecated +$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + +$.support.selectstart = "onselectstart" in document.createElement( "div" ); +$.fn.extend({ + disableSelection: function() { + return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }, + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + } +}); + +$.extend( $.ui, { + // $.ui.plugin is deprecated. Use the proxy pattern instead. + plugin: { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args ) { + var i, + set = instance.plugins[ name ]; + if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } + }, + + // only used by resizable + hasScroll: function( el, a ) { + + //If overflow is hidden, the element might have extra content, but the user wants to hide it + if ( $( el ).css( "overflow" ) === "hidden") { + return false; + } + + var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + has = false; + + if ( el[ scroll ] > 0 ) { + return true; + } + + // TODO: determine which cases actually cause this to happen + // if the element doesn't have the scroll set, see if it's possible to + // set the scroll + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + return has; + } +}); + +})( jQuery ); +(function( $, undefined ) { + +var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; +$.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); +}; + +$.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); +}; + +$.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply( null, [ options ].concat(args) ) : + options; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} )._init(); + } else { + $.data( this, fullName, new object( options, this ) ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( /* options, element */ ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "
                ", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData( this.widgetName ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( value === undefined ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( value === undefined ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + instance = this; + + // no suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + // accept selectors, DOM elements + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^(\w+)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; +}); + +})( jQuery ); +(function( $, undefined ) { + +var mouseHandled = false; +$( document ).mouseup( function() { + mouseHandled = false; +}); + +$.widget("ui.mouse", { + version: "1.10.0", + options: { + cancel: "input,textarea,button,select,option", + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .bind("mousedown."+this.widgetName, function(event) { + return that._mouseDown(event); + }) + .bind("click."+this.widgetName, function(event) { + if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { + $.removeData(event.target, that.widgetName + ".preventClickEvent"); + event.stopImmediatePropagation(); + return false; + } + }); + + this.started = false; + }, + + // TODO: make sure destroying one instance of mouse doesn't mess with + // other instances of mouse + _mouseDestroy: function() { + this.element.unbind("."+this.widgetName); + if ( this._mouseMoveDelegate ) { + $(document) + .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); + } + }, + + _mouseDown: function(event) { + // don't let more than one widget handle mouseStart + if( mouseHandled ) { return; } + + // we may have missed mouseup (out of window) + (this._mouseStarted && this._mouseUp(event)); + + this._mouseDownEvent = event; + + var that = this, + btnIsLeft = (event.which === 1), + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); + if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { + return true; + } + + this.mouseDelayMet = !this.options.delay; + if (!this.mouseDelayMet) { + this._mouseDelayTimer = setTimeout(function() { + that.mouseDelayMet = true; + }, this.options.delay); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = (this._mouseStart(event) !== false); + if (!this._mouseStarted) { + event.preventDefault(); + return true; + } + } + + // Click event may never have fired (Gecko & Opera) + if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { + $.removeData(event.target, this.widgetName + ".preventClickEvent"); + } + + // these delegates are required to keep context + this._mouseMoveDelegate = function(event) { + return that._mouseMove(event); + }; + this._mouseUpDelegate = function(event) { + return that._mouseUp(event); + }; + $(document) + .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .bind("mouseup."+this.widgetName, this._mouseUpDelegate); + + event.preventDefault(); + + mouseHandled = true; + return true; + }, + + _mouseMove: function(event) { + // IE mouseup check - mouseup happened when mouse was out of window + if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { + return this._mouseUp(event); + } + + if (this._mouseStarted) { + this._mouseDrag(event); + return event.preventDefault(); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = + (this._mouseStart(this._mouseDownEvent, event) !== false); + (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); + } + + return !this._mouseStarted; + }, + + _mouseUp: function(event) { + $(document) + .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); + + if (this._mouseStarted) { + this._mouseStarted = false; + + if (event.target === this._mouseDownEvent.target) { + $.data(event.target, this.widgetName + ".preventClickEvent", true); + } + + this._mouseStop(event); + } + + return false; + }, + + _mouseDistanceMet: function(event) { + return (Math.max( + Math.abs(this._mouseDownEvent.pageX - event.pageX), + Math.abs(this._mouseDownEvent.pageY - event.pageY) + ) >= this.options.distance + ); + }, + + _mouseDelayMet: function(/* event */) { + return this.mouseDelayMet; + }, + + // These are placeholder methods, to be overriden by extending plugin + _mouseStart: function(/* event */) {}, + _mouseDrag: function(/* event */) {}, + _mouseStop: function(/* event */) {}, + _mouseCapture: function(/* event */) { return true; } +}); + +})(jQuery); +(function( $, undefined ) { + +$.ui = $.ui || {}; + +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + round = Math.round, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} + +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +function getDimensions( elem ) { + var raw = elem[0]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( $.isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; +} + +$.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "
                " ), + innerDiv = div.children()[0]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[0].clientWidth; + } + + div.remove(); + + return (cachedScrollbarWidth = w1 - w2); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), + overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); + return { + width: hasOverflowX ? $.position.scrollbarWidth() : 0, + height: hasOverflowY ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isWindow = $.isWindow( withinElement[0] ); + return { + element: withinElement, + isWindow: isWindow, + offset: withinElement.offset() || { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: isWindow ? withinElement.width() : withinElement.outerWidth(), + height: isWindow ? withinElement.height() : withinElement.outerHeight() + }; + } +}; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + target = $( options.of ), + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[0].preventDefault ) { + // force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + // clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + }); + + // normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each(function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + // if the browser doesn't support fractions, then round for consistent results + if ( !$.support.offsetFractions ) { + position.left = round( position.left ); + position.top = round( position.top ); + } + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem : elem + }); + } + }); + + if ( options.using ) { + // adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + }); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // element is wider than within + if ( data.collisionWidth > outerWidth ) { + // element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; + position.left += overLeft - newOverRight; + // element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + // element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + // too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + // too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + // adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // element is taller than within + if ( data.collisionHeight > outerHeight ) { + // element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; + position.top += overTop - newOverBottom; + // element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + // element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + // too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + // too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + // adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } + else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; + if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { + position.top += myOffset + atOffset + offset; + } + } + else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; + if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +// fraction support test +(function () { + var testElement, testElementParent, testElementStyle, offsetLeft, i, + body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ); + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + $.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px;"; + + offsetLeft = $( div ).offset().left; + $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); +})(); + +}( jQuery ) ); +(function( $, undefined ) { + +$.widget("ui.draggable", $.ui.mouse, { + version: "1.10.0", + widgetEventPrefix: "drag", + options: { + addClasses: true, + appendTo: "parent", + axis: false, + connectToSortable: false, + containment: false, + cursor: "auto", + cursorAt: false, + grid: false, + handle: false, + helper: "original", + iframeFix: false, + opacity: false, + refreshPositions: false, + revert: false, + revertDuration: 500, + scope: "default", + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + snap: false, + snapMode: "both", + snapTolerance: 20, + stack: false, + zIndex: false, + + // callbacks + drag: null, + start: null, + stop: null + }, + _create: function() { + + if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { + this.element[0].style.position = "relative"; + } + if (this.options.addClasses){ + this.element.addClass("ui-draggable"); + } + if (this.options.disabled){ + this.element.addClass("ui-draggable-disabled"); + } + + this._mouseInit(); + + }, + + _destroy: function() { + this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); + this._mouseDestroy(); + }, + + _mouseCapture: function(event) { + + var o = this.options; + + // among others, prevent a drag on a resizable-handle + if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { + return false; + } + + //Quit if we're not on a valid handle + this.handle = this._getHandle(event); + if (!this.handle) { + return false; + } + + $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { + $("
                ") + .css({ + width: this.offsetWidth+"px", height: this.offsetHeight+"px", + position: "absolute", opacity: "0.001", zIndex: 1000 + }) + .css($(this).offset()) + .appendTo("body"); + }); + + return true; + + }, + + _mouseStart: function(event) { + + var o = this.options; + + //Create and append the visible helper + this.helper = this._createHelper(event); + + this.helper.addClass("ui-draggable-dragging"); + + //Cache the helper size + this._cacheHelperProportions(); + + //If ddmanager is used for droppables, set the global draggable + if($.ui.ddmanager) { + $.ui.ddmanager.current = this; + } + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + //Cache the margins of the original element + this._cacheMargins(); + + //Store the helper's css position + this.cssPosition = this.helper.css("position"); + this.scrollParent = this.helper.scrollParent(); + + //The element's absolute position on the page minus margins + this.offset = this.positionAbs = this.element.offset(); + this.offset = { + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; + + $.extend(this.offset, { + click: { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper + }); + + //Generate the original position + this.originalPosition = this.position = this._generatePosition(event); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); + + //Set a containment if given in the options + if(o.containment) { + this._setContainment(); + } + + //Trigger event + callbacks + if(this._trigger("start", event) === false) { + this._clear(); + return false; + } + + //Recache the helper size + this._cacheHelperProportions(); + + //Prepare the droppable offsets + if ($.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(this, event); + } + + + this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position + + //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) + if ( $.ui.ddmanager ) { + $.ui.ddmanager.dragStart(this, event); + } + + return true; + }, + + _mouseDrag: function(event, noPropagation) { + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + //Call plugins and callbacks and use the resulting position if something is returned + if (!noPropagation) { + var ui = this._uiHash(); + if(this._trigger("drag", event, ui) === false) { + this._mouseUp({}); + return false; + } + this.position = ui.position; + } + + if(!this.options.axis || this.options.axis !== "y") { + this.helper[0].style.left = this.position.left+"px"; + } + if(!this.options.axis || this.options.axis !== "x") { + this.helper[0].style.top = this.position.top+"px"; + } + if($.ui.ddmanager) { + $.ui.ddmanager.drag(this, event); + } + + return false; + }, + + _mouseStop: function(event) { + + //If we are using droppables, inform the manager about the drop + var element, + that = this, + elementInDom = false, + dropped = false; + if ($.ui.ddmanager && !this.options.dropBehaviour) { + dropped = $.ui.ddmanager.drop(this, event); + } + + //if a drop comes from outside (a sortable) + if(this.dropped) { + dropped = this.dropped; + this.dropped = false; + } + + //if the original element is no longer in the DOM don't bother to continue (see #8269) + element = this.element[0]; + while ( element && (element = element.parentNode) ) { + if (element === document ) { + elementInDom = true; + } + } + if ( !elementInDom && this.options.helper === "original" ) { + return false; + } + + if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { + $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { + if(that._trigger("stop", event) !== false) { + that._clear(); + } + }); + } else { + if(this._trigger("stop", event) !== false) { + this._clear(); + } + } + + return false; + }, + + _mouseUp: function(event) { + //Remove frame helpers + $("div.ui-draggable-iframeFix").each(function() { + this.parentNode.removeChild(this); + }); + + //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) + if( $.ui.ddmanager ) { + $.ui.ddmanager.dragStop(this, event); + } + + return $.ui.mouse.prototype._mouseUp.call(this, event); + }, + + cancel: function() { + + if(this.helper.is(".ui-draggable-dragging")) { + this._mouseUp({}); + } else { + this._clear(); + } + + return this; + + }, + + _getHandle: function(event) { + + var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; + $(this.options.handle, this.element) + .find("*") + .addBack() + .each(function() { + if(this === event.target) { + handle = true; + } + }); + + return handle; + + }, + + _createHelper: function(event) { + + var o = this.options, + helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); + + if(!helper.parents("body").length) { + helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); + } + + if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { + helper.css("position", "absolute"); + } + + return helper; + + }, + + _adjustOffsetFromHelper: function(obj) { + if (typeof obj === "string") { + obj = obj.split(" "); + } + if ($.isArray(obj)) { + obj = {left: +obj[0], top: +obj[1] || 0}; + } + if ("left" in obj) { + this.offset.click.left = obj.left + this.margins.left; + } + if ("right" in obj) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ("top" in obj) { + this.offset.click.top = obj.top + this.margins.top; + } + if ("bottom" in obj) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } + }, + + _getParentOffset: function() { + + //Get the offsetParent and cache its position + this.offsetParent = this.helper.offsetParent(); + var po = this.offsetParent.offset(); + + // This is a special case where we need to modify a offset calculated on start, since the following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that + // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag + if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); + } + + //This needs to be actually done for all browsers, since pageX/pageY includes this information + //Ugly IE fix + if((this.offsetParent[0] === document.body) || + (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { + po = { top: 0, left: 0 }; + } + + return { + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) + }; + + }, + + _getRelativeOffset: function() { + + if(this.cssPosition === "relative") { + var p = this.element.position(); + return { + top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), + left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() + }; + } else { + return { top: 0, left: 0 }; + } + + }, + + _cacheMargins: function() { + this.margins = { + left: (parseInt(this.element.css("marginLeft"),10) || 0), + top: (parseInt(this.element.css("marginTop"),10) || 0), + right: (parseInt(this.element.css("marginRight"),10) || 0), + bottom: (parseInt(this.element.css("marginBottom"),10) || 0) + }; + }, + + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var over, c, ce, + o = this.options; + + if(o.containment === "parent") { + o.containment = this.helper[0].parentNode; + } + if(o.containment === "document" || o.containment === "window") { + this.containment = [ + o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, + o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, + (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, + (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top + ]; + } + + if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) { + c = $(o.containment); + ce = c[0]; + + if(!ce) { + return; + } + + over = ($(ce).css("overflow") !== "hidden"); + + this.containment = [ + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), + (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, + (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom + ]; + this.relative_container = c; + + } else if(o.containment.constructor === Array) { + this.containment = o.containment; + } + + }, + + _convertPositionTo: function(d, pos) { + + if(!pos) { + pos = this.position; + } + + var mod = d === "absolute" ? 1 : -1, + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + return { + top: ( + pos.top + // The absolute mouse position + this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + ), + left: ( + pos.left + // The absolute mouse position + this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + ) + }; + + }, + + _generatePosition: function(event) { + + var containment, co, top, left, + o = this.options, + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, + scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName), + pageX = event.pageX, + pageY = event.pageY; + + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ + + if(this.originalPosition) { //If we are not dragging yet, we won't check for options + if(this.containment) { + if (this.relative_container){ + co = this.relative_container.offset(); + containment = [ this.containment[0] + co.left, + this.containment[1] + co.top, + this.containment[2] + co.left, + this.containment[3] + co.top ]; + } + else { + containment = this.containment; + } + + if(event.pageX - this.offset.click.left < containment[0]) { + pageX = containment[0] + this.offset.click.left; + } + if(event.pageY - this.offset.click.top < containment[1]) { + pageY = containment[1] + this.offset.click.top; + } + if(event.pageX - this.offset.click.left > containment[2]) { + pageX = containment[2] + this.offset.click.left; + } + if(event.pageY - this.offset.click.top > containment[3]) { + pageY = containment[3] + this.offset.click.top; + } + } + + if(o.grid) { + //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) + top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; + pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; + + left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; + pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; + } + + } + + return { + top: ( + pageY - // The absolute mouse position + this.offset.click.top - // Click offset (relative to the element) + this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top + // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + ), + left: ( + pageX - // The absolute mouse position + this.offset.click.left - // Click offset (relative to the element) + this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left + // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + ) + }; + + }, + + _clear: function() { + this.helper.removeClass("ui-draggable-dragging"); + if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { + this.helper.remove(); + } + this.helper = null; + this.cancelHelperRemoval = false; + }, + + // From now on bulk stuff - mainly helpers + + _trigger: function(type, event, ui) { + ui = ui || this._uiHash(); + $.ui.plugin.call(this, type, [event, ui]); + //The absolute position has to be recalculated after plugins + if(type === "drag") { + this.positionAbs = this._convertPositionTo("absolute"); + } + return $.Widget.prototype._trigger.call(this, type, event, ui); + }, + + plugins: {}, + + _uiHash: function() { + return { + helper: this.helper, + position: this.position, + originalPosition: this.originalPosition, + offset: this.positionAbs + }; + } + +}); + +$.ui.plugin.add("draggable", "connectToSortable", { + start: function(event, ui) { + + var inst = $(this).data("ui-draggable"), o = inst.options, + uiSortable = $.extend({}, ui, { item: inst.element }); + inst.sortables = []; + $(o.connectToSortable).each(function() { + var sortable = $.data(this, "ui-sortable"); + if (sortable && !sortable.options.disabled) { + inst.sortables.push({ + instance: sortable, + shouldRevert: sortable.options.revert + }); + sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). + sortable._trigger("activate", event, uiSortable); + } + }); + + }, + stop: function(event, ui) { + + //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper + var inst = $(this).data("ui-draggable"), + uiSortable = $.extend({}, ui, { item: inst.element }); + + $.each(inst.sortables, function() { + if(this.instance.isOver) { + + this.instance.isOver = 0; + + inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance + this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) + + //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" + if(this.shouldRevert) { + this.instance.options.revert = true; + } + + //Trigger the stop of the sortable + this.instance._mouseStop(event); + + this.instance.options.helper = this.instance.options._helper; + + //If the helper has been the original item, restore properties in the sortable + if(inst.options.helper === "original") { + this.instance.currentItem.css({ top: "auto", left: "auto" }); + } + + } else { + this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance + this.instance._trigger("deactivate", event, uiSortable); + } + + }); + + }, + drag: function(event, ui) { + + var inst = $(this).data("ui-draggable"), that = this; + + $.each(inst.sortables, function() { + + var innermostIntersecting = false, + thisSortable = this; + + //Copy over some variables to allow calling the sortable's native _intersectsWith + this.instance.positionAbs = inst.positionAbs; + this.instance.helperProportions = inst.helperProportions; + this.instance.offset.click = inst.offset.click; + + if(this.instance._intersectsWith(this.instance.containerCache)) { + innermostIntersecting = true; + $.each(inst.sortables, function () { + this.instance.positionAbs = inst.positionAbs; + this.instance.helperProportions = inst.helperProportions; + this.instance.offset.click = inst.offset.click; + if (this !== thisSortable && + this.instance._intersectsWith(this.instance.containerCache) && + $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]) + ) { + innermostIntersecting = false; + } + return innermostIntersecting; + }); + } + + + if(innermostIntersecting) { + //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once + if(!this.instance.isOver) { + + this.instance.isOver = 1; + //Now we fake the start of dragging for the sortable instance, + //by cloning the list group item, appending it to the sortable and using it as inst.currentItem + //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) + this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); + this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it + this.instance.options.helper = function() { return ui.helper[0]; }; + + event.target = this.instance.currentItem[0]; + this.instance._mouseCapture(event, true); + this.instance._mouseStart(event, true, true); + + //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes + this.instance.offset.click.top = inst.offset.click.top; + this.instance.offset.click.left = inst.offset.click.left; + this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; + this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; + + inst._trigger("toSortable", event); + inst.dropped = this.instance.element; //draggable revert needs that + //hack so receive/update callbacks work (mostly) + inst.currentItem = inst.element; + this.instance.fromOutside = inst; + + } + + //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable + if(this.instance.currentItem) { + this.instance._mouseDrag(event); + } + + } else { + + //If it doesn't intersect with the sortable, and it intersected before, + //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval + if(this.instance.isOver) { + + this.instance.isOver = 0; + this.instance.cancelHelperRemoval = true; + + //Prevent reverting on this forced stop + this.instance.options.revert = false; + + // The out event needs to be triggered independently + this.instance._trigger("out", event, this.instance._uiHash(this.instance)); + + this.instance._mouseStop(event, true); + this.instance.options.helper = this.instance.options._helper; + + //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size + this.instance.currentItem.remove(); + if(this.instance.placeholder) { + this.instance.placeholder.remove(); + } + + inst._trigger("fromSortable", event); + inst.dropped = false; //draggable revert needs that + } + + } + + }); + + } +}); + +$.ui.plugin.add("draggable", "cursor", { + start: function() { + var t = $("body"), o = $(this).data("ui-draggable").options; + if (t.css("cursor")) { + o._cursor = t.css("cursor"); + } + t.css("cursor", o.cursor); + }, + stop: function() { + var o = $(this).data("ui-draggable").options; + if (o._cursor) { + $("body").css("cursor", o._cursor); + } + } +}); + +$.ui.plugin.add("draggable", "opacity", { + start: function(event, ui) { + var t = $(ui.helper), o = $(this).data("ui-draggable").options; + if(t.css("opacity")) { + o._opacity = t.css("opacity"); + } + t.css("opacity", o.opacity); + }, + stop: function(event, ui) { + var o = $(this).data("ui-draggable").options; + if(o._opacity) { + $(ui.helper).css("opacity", o._opacity); + } + } +}); + +$.ui.plugin.add("draggable", "scroll", { + start: function() { + var i = $(this).data("ui-draggable"); + if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { + i.overflowOffset = i.scrollParent.offset(); + } + }, + drag: function( event ) { + + var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; + + if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { + + if(!o.axis || o.axis !== "x") { + if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; + } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; + } + } + + if(!o.axis || o.axis !== "y") { + if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; + } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; + } + } + + } else { + + if(!o.axis || o.axis !== "x") { + if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { + scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); + } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { + scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); + } + } + + if(!o.axis || o.axis !== "y") { + if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { + scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); + } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { + scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); + } + } + + } + + if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(i, event); + } + + } +}); + +$.ui.plugin.add("draggable", "snap", { + start: function() { + + var i = $(this).data("ui-draggable"), + o = i.options; + + i.snapElements = []; + + $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { + var $t = $(this), + $o = $t.offset(); + if(this !== i.element[0]) { + i.snapElements.push({ + item: this, + width: $t.outerWidth(), height: $t.outerHeight(), + top: $o.top, left: $o.left + }); + } + }); + + }, + drag: function(event, ui) { + + var ts, bs, ls, rs, l, r, t, b, i, first, + inst = $(this).data("ui-draggable"), + o = inst.options, + d = o.snapTolerance, + x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, + y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; + + for (i = inst.snapElements.length - 1; i >= 0; i--){ + + l = inst.snapElements[i].left; + r = l + inst.snapElements[i].width; + t = inst.snapElements[i].top; + b = t + inst.snapElements[i].height; + + //Yes, I know, this is insane ;) + if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { + if(inst.snapElements[i].snapping) { + (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + } + inst.snapElements[i].snapping = false; + continue; + } + + if(o.snapMode !== "inner") { + ts = Math.abs(t - y2) <= d; + bs = Math.abs(b - y1) <= d; + ls = Math.abs(l - x2) <= d; + rs = Math.abs(r - x1) <= d; + if(ts) { + ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; + } + if(bs) { + ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; + } + if(ls) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; + } + if(rs) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; + } + } + + first = (ts || bs || ls || rs); + + if(o.snapMode !== "outer") { + ts = Math.abs(t - y1) <= d; + bs = Math.abs(b - y2) <= d; + ls = Math.abs(l - x1) <= d; + rs = Math.abs(r - x2) <= d; + if(ts) { + ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; + } + if(bs) { + ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; + } + if(ls) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; + } + if(rs) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; + } + } + + if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { + (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + } + inst.snapElements[i].snapping = (ts || bs || ls || rs || first); + + } + + } +}); + +$.ui.plugin.add("draggable", "stack", { + start: function() { + + var min, + o = $(this).data("ui-draggable").options, + group = $.makeArray($(o.stack)).sort(function(a,b) { + return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); + }); + + if (!group.length) { return; } + + min = parseInt(group[0].style.zIndex, 10) || 0; + $(group).each(function(i) { + this.style.zIndex = min + i; + }); + + this[0].style.zIndex = min + group.length; + + } +}); + +$.ui.plugin.add("draggable", "zIndex", { + start: function(event, ui) { + var t = $(ui.helper), o = $(this).data("ui-draggable").options; + if(t.css("zIndex")) { + o._zIndex = t.css("zIndex"); + } + t.css("zIndex", o.zIndex); + }, + stop: function(event, ui) { + var o = $(this).data("ui-draggable").options; + if(o._zIndex) { + $(ui.helper).css("zIndex", o._zIndex); + } + } +}); + +})(jQuery); +(function( $, undefined ) { + +function isOverAxis( x, reference, size ) { + return ( x > reference ) && ( x < ( reference + size ) ); +} + +$.widget("ui.droppable", { + version: "1.10.0", + widgetEventPrefix: "drop", + options: { + accept: "*", + activeClass: false, + addClasses: true, + greedy: false, + hoverClass: false, + scope: "default", + tolerance: "intersect", + + // callbacks + activate: null, + deactivate: null, + drop: null, + out: null, + over: null + }, + _create: function() { + + var o = this.options, + accept = o.accept; + + this.isover = false; + this.isout = true; + + this.accept = $.isFunction(accept) ? accept : function(d) { + return d.is(accept); + }; + + //Store the droppable's proportions + this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; + + // Add the reference and positions to the manager + $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; + $.ui.ddmanager.droppables[o.scope].push(this); + + (o.addClasses && this.element.addClass("ui-droppable")); + + }, + + _destroy: function() { + var i = 0, + drop = $.ui.ddmanager.droppables[this.options.scope]; + + for ( ; i < drop.length; i++ ) { + if ( drop[i] === this ) { + drop.splice(i, 1); + } + } + + this.element.removeClass("ui-droppable ui-droppable-disabled"); + }, + + _setOption: function(key, value) { + + if(key === "accept") { + this.accept = $.isFunction(value) ? value : function(d) { + return d.is(value); + }; + } + $.Widget.prototype._setOption.apply(this, arguments); + }, + + _activate: function(event) { + var draggable = $.ui.ddmanager.current; + if(this.options.activeClass) { + this.element.addClass(this.options.activeClass); + } + if(draggable){ + this._trigger("activate", event, this.ui(draggable)); + } + }, + + _deactivate: function(event) { + var draggable = $.ui.ddmanager.current; + if(this.options.activeClass) { + this.element.removeClass(this.options.activeClass); + } + if(draggable){ + this._trigger("deactivate", event, this.ui(draggable)); + } + }, + + _over: function(event) { + + var draggable = $.ui.ddmanager.current; + + // Bail if draggable and droppable are same element + if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { + return; + } + + if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + if(this.options.hoverClass) { + this.element.addClass(this.options.hoverClass); + } + this._trigger("over", event, this.ui(draggable)); + } + + }, + + _out: function(event) { + + var draggable = $.ui.ddmanager.current; + + // Bail if draggable and droppable are same element + if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { + return; + } + + if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + if(this.options.hoverClass) { + this.element.removeClass(this.options.hoverClass); + } + this._trigger("out", event, this.ui(draggable)); + } + + }, + + _drop: function(event,custom) { + + var draggable = custom || $.ui.ddmanager.current, + childrenIntersection = false; + + // Bail if draggable and droppable are same element + if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { + return false; + } + + this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { + var inst = $.data(this, "ui-droppable"); + if( + inst.options.greedy && + !inst.options.disabled && + inst.options.scope === draggable.options.scope && + inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && + $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) + ) { childrenIntersection = true; return false; } + }); + if(childrenIntersection) { + return false; + } + + if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + if(this.options.activeClass) { + this.element.removeClass(this.options.activeClass); + } + if(this.options.hoverClass) { + this.element.removeClass(this.options.hoverClass); + } + this._trigger("drop", event, this.ui(draggable)); + return this.element; + } + + return false; + + }, + + ui: function(c) { + return { + draggable: (c.currentItem || c.element), + helper: c.helper, + position: c.position, + offset: c.positionAbs + }; + } + +}); + +$.ui.intersect = function(draggable, droppable, toleranceMode) { + + if (!droppable.offset) { + return false; + } + + var draggableLeft, draggableTop, + x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, + y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, + l = droppable.offset.left, r = l + droppable.proportions.width, + t = droppable.offset.top, b = t + droppable.proportions.height; + + switch (toleranceMode) { + case "fit": + return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); + case "intersect": + return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half + x2 - (draggable.helperProportions.width / 2) < r && // Left Half + t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half + y2 - (draggable.helperProportions.height / 2) < b ); // Top Half + case "pointer": + draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); + draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); + return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); + case "touch": + return ( + (y1 >= t && y1 <= b) || // Top edge touching + (y2 >= t && y2 <= b) || // Bottom edge touching + (y1 < t && y2 > b) // Surrounded vertically + ) && ( + (x1 >= l && x1 <= r) || // Left edge touching + (x2 >= l && x2 <= r) || // Right edge touching + (x1 < l && x2 > r) // Surrounded horizontally + ); + default: + return false; + } + +}; + +/* + This manager tracks offsets of draggables and droppables +*/ +$.ui.ddmanager = { + current: null, + droppables: { "default": [] }, + prepareOffsets: function(t, event) { + + var i, j, + m = $.ui.ddmanager.droppables[t.options.scope] || [], + type = event ? event.type : null, // workaround for #2317 + list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); + + droppablesLoop: for (i = 0; i < m.length; i++) { + + //No disabled and non-accepted + if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { + continue; + } + + // Filter out elements in the current dragged item + for (j=0; j < list.length; j++) { + if(list[j] === m[i].element[0]) { + m[i].proportions.height = 0; + continue droppablesLoop; + } + } + + m[i].visible = m[i].element.css("display") !== "none"; + if(!m[i].visible) { + continue; + } + + //Activate the droppable if used directly from draggables + if(type === "mousedown") { + m[i]._activate.call(m[i], event); + } + + m[i].offset = m[i].element.offset(); + m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; + + } + + }, + drop: function(draggable, event) { + + var dropped = false; + $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { + + if(!this.options) { + return; + } + if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { + dropped = this._drop.call(this, event) || dropped; + } + + if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + this.isout = true; + this.isover = false; + this._deactivate.call(this, event); + } + + }); + return dropped; + + }, + dragStart: function( draggable, event ) { + //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) + draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { + if( !draggable.options.refreshPositions ) { + $.ui.ddmanager.prepareOffsets( draggable, event ); + } + }); + }, + drag: function(draggable, event) { + + //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. + if(draggable.options.refreshPositions) { + $.ui.ddmanager.prepareOffsets(draggable, event); + } + + //Run through all droppables and check their positions based on specific tolerance options + $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { + + if(this.options.disabled || this.greedyChild || !this.visible) { + return; + } + + var parentInstance, scope, parent, + intersects = $.ui.intersect(draggable, this, this.options.tolerance), + c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); + if(!c) { + return; + } + + if (this.options.greedy) { + // find droppable parents with same scope + scope = this.options.scope; + parent = this.element.parents(":data(ui-droppable)").filter(function () { + return $.data(this, "ui-droppable").options.scope === scope; + }); + + if (parent.length) { + parentInstance = $.data(parent[0], "ui-droppable"); + parentInstance.greedyChild = (c === "isover"); + } + } + + // we just moved into a greedy child + if (parentInstance && c === "isover") { + parentInstance.isover = false; + parentInstance.isout = true; + parentInstance._out.call(parentInstance, event); + } + + this[c] = true; + this[c === "isout" ? "isover" : "isout"] = false; + this[c === "isover" ? "_over" : "_out"].call(this, event); + + // we just moved out of a greedy child + if (parentInstance && c === "isout") { + parentInstance.isout = false; + parentInstance.isover = true; + parentInstance._over.call(parentInstance, event); + } + }); + + }, + dragStop: function( draggable, event ) { + draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); + //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) + if( !draggable.options.refreshPositions ) { + $.ui.ddmanager.prepareOffsets( draggable, event ); + } + } +}; + +})(jQuery); +(function( $, undefined ) { + +function num(v) { + return parseInt(v, 10) || 0; +} + +function isNumber(value) { + return !isNaN(parseInt(value, 10)); +} + +$.widget("ui.resizable", $.ui.mouse, { + version: "1.10.0", + widgetEventPrefix: "resize", + options: { + alsoResize: false, + animate: false, + animateDuration: "slow", + animateEasing: "swing", + aspectRatio: false, + autoHide: false, + containment: false, + ghost: false, + grid: false, + handles: "e,s,se", + helper: false, + maxHeight: null, + maxWidth: null, + minHeight: 10, + minWidth: 10, + // See #7960 + zIndex: 90, + + // callbacks + resize: null, + start: null, + stop: null + }, + _create: function() { + + var n, i, handle, axis, hname, + that = this, + o = this.options; + this.element.addClass("ui-resizable"); + + $.extend(this, { + _aspectRatio: !!(o.aspectRatio), + aspectRatio: o.aspectRatio, + originalElement: this.element, + _proportionallyResizeElements: [], + _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null + }); + + //Wrap the element if it cannot hold child nodes + if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { + + //Create a wrapper element and set the wrapper to the new current internal element + this.element.wrap( + $("
                ").css({ + position: this.element.css("position"), + width: this.element.outerWidth(), + height: this.element.outerHeight(), + top: this.element.css("top"), + left: this.element.css("left") + }) + ); + + //Overwrite the original this.element + this.element = this.element.parent().data( + "ui-resizable", this.element.data("ui-resizable") + ); + + this.elementIsWrapper = true; + + //Move margins to the wrapper + this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); + this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); + + //Prevent Safari textarea resize + this.originalResizeStyle = this.originalElement.css("resize"); + this.originalElement.css("resize", "none"); + + //Push the actual element to our proportionallyResize internal array + this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); + + // avoid IE jump (hard set the margin) + this.originalElement.css({ margin: this.originalElement.css("margin") }); + + // fix handlers offset + this._proportionallyResize(); + + } + + this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" }); + if(this.handles.constructor === String) { + + if ( this.handles === "all") { + this.handles = "n,e,s,w,se,sw,ne,nw"; + } + + n = this.handles.split(","); + this.handles = {}; + + for(i = 0; i < n.length; i++) { + + handle = $.trim(n[i]); + hname = "ui-resizable-"+handle; + axis = $("
                "); + + // Apply zIndex to all handles - see #7960 + axis.css({ zIndex: o.zIndex }); + + //TODO : What's going on here? + if ("se" === handle) { + axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); + } + + //Insert into internal handles object and append to element + this.handles[handle] = ".ui-resizable-"+handle; + this.element.append(axis); + } + + } + + this._renderAxis = function(target) { + + var i, axis, padPos, padWrapper; + + target = target || this.element; + + for(i in this.handles) { + + if(this.handles[i].constructor === String) { + this.handles[i] = $(this.handles[i], this.element).show(); + } + + //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) + if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { + + axis = $(this.handles[i], this.element); + + //Checking the correct pad and border + padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); + + //The padding type i have to apply... + padPos = [ "padding", + /ne|nw|n/.test(i) ? "Top" : + /se|sw|s/.test(i) ? "Bottom" : + /^e$/.test(i) ? "Right" : "Left" ].join(""); + + target.css(padPos, padWrapper); + + this._proportionallyResize(); + + } + + //TODO: What's that good for? There's not anything to be executed left + if(!$(this.handles[i]).length) { + continue; + } + } + }; + + //TODO: make renderAxis a prototype function + this._renderAxis(this.element); + + this._handles = $(".ui-resizable-handle", this.element) + .disableSelection(); + + //Matching axis name + this._handles.mouseover(function() { + if (!that.resizing) { + if (this.className) { + axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); + } + //Axis, default = se + that.axis = axis && axis[1] ? axis[1] : "se"; + } + }); + + //If we want to auto hide the elements + if (o.autoHide) { + this._handles.hide(); + $(this.element) + .addClass("ui-resizable-autohide") + .mouseenter(function() { + if (o.disabled) { + return; + } + $(this).removeClass("ui-resizable-autohide"); + that._handles.show(); + }) + .mouseleave(function(){ + if (o.disabled) { + return; + } + if (!that.resizing) { + $(this).addClass("ui-resizable-autohide"); + that._handles.hide(); + } + }); + } + + //Initialize the mouse interaction + this._mouseInit(); + + }, + + _destroy: function() { + + this._mouseDestroy(); + + var wrapper, + _destroy = function(exp) { + $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") + .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); + }; + + //TODO: Unwrap at same DOM position + if (this.elementIsWrapper) { + _destroy(this.element); + wrapper = this.element; + this.originalElement.css({ + position: wrapper.css("position"), + width: wrapper.outerWidth(), + height: wrapper.outerHeight(), + top: wrapper.css("top"), + left: wrapper.css("left") + }).insertAfter( wrapper ); + wrapper.remove(); + } + + this.originalElement.css("resize", this.originalResizeStyle); + _destroy(this.originalElement); + + return this; + }, + + _mouseCapture: function(event) { + var i, handle, + capture = false; + + for (i in this.handles) { + handle = $(this.handles[i])[0]; + if (handle === event.target || $.contains(handle, event.target)) { + capture = true; + } + } + + return !this.options.disabled && capture; + }, + + _mouseStart: function(event) { + + var curleft, curtop, cursor, + o = this.options, + iniPos = this.element.position(), + el = this.element; + + this.resizing = true; + + // bugfix for http://dev.jquery.com/ticket/1749 + if ( (/absolute/).test( el.css("position") ) ) { + el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); + } else if (el.is(".ui-draggable")) { + el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); + } + + this._renderProxy(); + + curleft = num(this.helper.css("left")); + curtop = num(this.helper.css("top")); + + if (o.containment) { + curleft += $(o.containment).scrollLeft() || 0; + curtop += $(o.containment).scrollTop() || 0; + } + + //Store needed variables + this.offset = this.helper.offset(); + this.position = { left: curleft, top: curtop }; + this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; + this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; + this.originalPosition = { left: curleft, top: curtop }; + this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; + this.originalMousePosition = { left: event.pageX, top: event.pageY }; + + //Aspect Ratio + this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); + + cursor = $(".ui-resizable-" + this.axis).css("cursor"); + $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); + + el.addClass("ui-resizable-resizing"); + this._propagate("start", event); + return true; + }, + + _mouseDrag: function(event) { + + //Increase performance, avoid regex + var data, + el = this.helper, props = {}, + smp = this.originalMousePosition, + a = this.axis, + prevTop = this.position.top, + prevLeft = this.position.left, + prevWidth = this.size.width, + prevHeight = this.size.height, + dx = (event.pageX-smp.left)||0, + dy = (event.pageY-smp.top)||0, + trigger = this._change[a]; + + if (!trigger) { + return false; + } + + // Calculate the attrs that will be change + data = trigger.apply(this, [event, dx, dy]); + + // Put this in the mouseDrag handler since the user can start pressing shift while resizing + this._updateVirtualBoundaries(event.shiftKey); + if (this._aspectRatio || event.shiftKey) { + data = this._updateRatio(data, event); + } + + data = this._respectSize(data, event); + + this._updateCache(data); + + // plugins callbacks need to be called first + this._propagate("resize", event); + + if (this.position.top !== prevTop) { + props.top = this.position.top + "px"; + } + if (this.position.left !== prevLeft) { + props.left = this.position.left + "px"; + } + if (this.size.width !== prevWidth) { + props.width = this.size.width + "px"; + } + if (this.size.height !== prevHeight) { + props.height = this.size.height + "px"; + } + el.css(props); + + if (!this._helper && this._proportionallyResizeElements.length) { + this._proportionallyResize(); + } + + // Call the user callback if the element was resized + if ( ! $.isEmptyObject(props) ) { + this._trigger("resize", event, this.ui()); + } + + return false; + }, + + _mouseStop: function(event) { + + this.resizing = false; + var pr, ista, soffseth, soffsetw, s, left, top, + o = this.options, that = this; + + if(this._helper) { + + pr = this._proportionallyResizeElements; + ista = pr.length && (/textarea/i).test(pr[0].nodeName); + soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; + soffsetw = ista ? 0 : that.sizeDiff.width; + + s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; + left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; + top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; + + if (!o.animate) { + this.element.css($.extend(s, { top: top, left: left })); + } + + that.helper.height(that.size.height); + that.helper.width(that.size.width); + + if (this._helper && !o.animate) { + this._proportionallyResize(); + } + } + + $("body").css("cursor", "auto"); + + this.element.removeClass("ui-resizable-resizing"); + + this._propagate("stop", event); + + if (this._helper) { + this.helper.remove(); + } + + return false; + + }, + + _updateVirtualBoundaries: function(forceAspectRatio) { + var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, + o = this.options; + + b = { + minWidth: isNumber(o.minWidth) ? o.minWidth : 0, + maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, + minHeight: isNumber(o.minHeight) ? o.minHeight : 0, + maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity + }; + + if(this._aspectRatio || forceAspectRatio) { + // We want to create an enclosing box whose aspect ration is the requested one + // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension + pMinWidth = b.minHeight * this.aspectRatio; + pMinHeight = b.minWidth / this.aspectRatio; + pMaxWidth = b.maxHeight * this.aspectRatio; + pMaxHeight = b.maxWidth / this.aspectRatio; + + if(pMinWidth > b.minWidth) { + b.minWidth = pMinWidth; + } + if(pMinHeight > b.minHeight) { + b.minHeight = pMinHeight; + } + if(pMaxWidth < b.maxWidth) { + b.maxWidth = pMaxWidth; + } + if(pMaxHeight < b.maxHeight) { + b.maxHeight = pMaxHeight; + } + } + this._vBoundaries = b; + }, + + _updateCache: function(data) { + this.offset = this.helper.offset(); + if (isNumber(data.left)) { + this.position.left = data.left; + } + if (isNumber(data.top)) { + this.position.top = data.top; + } + if (isNumber(data.height)) { + this.size.height = data.height; + } + if (isNumber(data.width)) { + this.size.width = data.width; + } + }, + + _updateRatio: function( data ) { + + var cpos = this.position, + csize = this.size, + a = this.axis; + + if (isNumber(data.height)) { + data.width = (data.height * this.aspectRatio); + } else if (isNumber(data.width)) { + data.height = (data.width / this.aspectRatio); + } + + if (a === "sw") { + data.left = cpos.left + (csize.width - data.width); + data.top = null; + } + if (a === "nw") { + data.top = cpos.top + (csize.height - data.height); + data.left = cpos.left + (csize.width - data.width); + } + + return data; + }, + + _respectSize: function( data ) { + + var o = this._vBoundaries, + a = this.axis, + ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), + isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), + dw = this.originalPosition.left + this.originalSize.width, + dh = this.position.top + this.size.height, + cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); + if (isminw) { + data.width = o.minWidth; + } + if (isminh) { + data.height = o.minHeight; + } + if (ismaxw) { + data.width = o.maxWidth; + } + if (ismaxh) { + data.height = o.maxHeight; + } + + if (isminw && cw) { + data.left = dw - o.minWidth; + } + if (ismaxw && cw) { + data.left = dw - o.maxWidth; + } + if (isminh && ch) { + data.top = dh - o.minHeight; + } + if (ismaxh && ch) { + data.top = dh - o.maxHeight; + } + + // fixing jump error on top/left - bug #2330 + if (!data.width && !data.height && !data.left && data.top) { + data.top = null; + } else if (!data.width && !data.height && !data.top && data.left) { + data.left = null; + } + + return data; + }, + + _proportionallyResize: function() { + + if (!this._proportionallyResizeElements.length) { + return; + } + + var i, j, borders, paddings, prel, + element = this.helper || this.element; + + for ( i=0; i < this._proportionallyResizeElements.length; i++) { + + prel = this._proportionallyResizeElements[i]; + + if (!this.borderDif) { + this.borderDif = []; + borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; + paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; + + for ( j = 0; j < borders.length; j++ ) { + this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); + } + } + + prel.css({ + height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, + width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 + }); + + } + + }, + + _renderProxy: function() { + + var el = this.element, o = this.options; + this.elementOffset = el.offset(); + + if(this._helper) { + + this.helper = this.helper || $("
                "); + + this.helper.addClass(this._helper).css({ + width: this.element.outerWidth() - 1, + height: this.element.outerHeight() - 1, + position: "absolute", + left: this.elementOffset.left +"px", + top: this.elementOffset.top +"px", + zIndex: ++o.zIndex //TODO: Don't modify option + }); + + this.helper + .appendTo("body") + .disableSelection(); + + } else { + this.helper = this.element; + } + + }, + + _change: { + e: function(event, dx) { + return { width: this.originalSize.width + dx }; + }, + w: function(event, dx) { + var cs = this.originalSize, sp = this.originalPosition; + return { left: sp.left + dx, width: cs.width - dx }; + }, + n: function(event, dx, dy) { + var cs = this.originalSize, sp = this.originalPosition; + return { top: sp.top + dy, height: cs.height - dy }; + }, + s: function(event, dx, dy) { + return { height: this.originalSize.height + dy }; + }, + se: function(event, dx, dy) { + return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); + }, + sw: function(event, dx, dy) { + return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); + }, + ne: function(event, dx, dy) { + return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); + }, + nw: function(event, dx, dy) { + return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); + } + }, + + _propagate: function(n, event) { + $.ui.plugin.call(this, n, [event, this.ui()]); + (n !== "resize" && this._trigger(n, event, this.ui())); + }, + + plugins: {}, + + ui: function() { + return { + originalElement: this.originalElement, + element: this.element, + helper: this.helper, + position: this.position, + size: this.size, + originalSize: this.originalSize, + originalPosition: this.originalPosition + }; + } + +}); + +/* + * Resizable Extensions + */ + +$.ui.plugin.add("resizable", "animate", { + + stop: function( event ) { + var that = $(this).data("ui-resizable"), + o = that.options, + pr = that._proportionallyResizeElements, + ista = pr.length && (/textarea/i).test(pr[0].nodeName), + soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width, + style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, + left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, + top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; + + that.element.animate( + $.extend(style, top && left ? { top: top, left: left } : {}), { + duration: o.animateDuration, + easing: o.animateEasing, + step: function() { + + var data = { + width: parseInt(that.element.css("width"), 10), + height: parseInt(that.element.css("height"), 10), + top: parseInt(that.element.css("top"), 10), + left: parseInt(that.element.css("left"), 10) + }; + + if (pr && pr.length) { + $(pr[0]).css({ width: data.width, height: data.height }); + } + + // propagating resize, and updating values for each animation step + that._updateCache(data); + that._propagate("resize", event); + + } + } + ); + } + +}); + +$.ui.plugin.add("resizable", "containment", { + + start: function() { + var element, p, co, ch, cw, width, height, + that = $(this).data("ui-resizable"), + o = that.options, + el = that.element, + oc = o.containment, + ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; + + if (!ce) { + return; + } + + that.containerElement = $(ce); + + if (/document/.test(oc) || oc === document) { + that.containerOffset = { left: 0, top: 0 }; + that.containerPosition = { left: 0, top: 0 }; + + that.parentData = { + element: $(document), left: 0, top: 0, + width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight + }; + } + + // i'm a node, so compute top, left, right, bottom + else { + element = $(ce); + p = []; + $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); + + that.containerOffset = element.offset(); + that.containerPosition = element.position(); + that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; + + co = that.containerOffset; + ch = that.containerSize.height; + cw = that.containerSize.width; + width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); + height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); + + that.parentData = { + element: ce, left: co.left, top: co.top, width: width, height: height + }; + } + }, + + resize: function( event ) { + var woset, hoset, isParent, isOffsetRelative, + that = $(this).data("ui-resizable"), + o = that.options, + co = that.containerOffset, cp = that.position, + pRatio = that._aspectRatio || event.shiftKey, + cop = { top:0, left:0 }, ce = that.containerElement; + + if (ce[0] !== document && (/static/).test(ce.css("position"))) { + cop = co; + } + + if (cp.left < (that._helper ? co.left : 0)) { + that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); + if (pRatio) { + that.size.height = that.size.width / that.aspectRatio; + } + that.position.left = o.helper ? co.left : 0; + } + + if (cp.top < (that._helper ? co.top : 0)) { + that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); + if (pRatio) { + that.size.width = that.size.height * that.aspectRatio; + } + that.position.top = that._helper ? co.top : 0; + } + + that.offset.left = that.parentData.left+that.position.left; + that.offset.top = that.parentData.top+that.position.top; + + woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); + hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); + + isParent = that.containerElement.get(0) === that.element.parent().get(0); + isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); + + if(isParent && isOffsetRelative) { + woset -= that.parentData.left; + } + + if (woset + that.size.width >= that.parentData.width) { + that.size.width = that.parentData.width - woset; + if (pRatio) { + that.size.height = that.size.width / that.aspectRatio; + } + } + + if (hoset + that.size.height >= that.parentData.height) { + that.size.height = that.parentData.height - hoset; + if (pRatio) { + that.size.width = that.size.height * that.aspectRatio; + } + } + }, + + stop: function(){ + var that = $(this).data("ui-resizable"), + o = that.options, + co = that.containerOffset, + cop = that.containerPosition, + ce = that.containerElement, + helper = $(that.helper), + ho = helper.offset(), + w = helper.outerWidth() - that.sizeDiff.width, + h = helper.outerHeight() - that.sizeDiff.height; + + if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); + } + + if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); + } + + } +}); + +$.ui.plugin.add("resizable", "alsoResize", { + + start: function () { + var that = $(this).data("ui-resizable"), + o = that.options, + _store = function (exp) { + $(exp).each(function() { + var el = $(this); + el.data("ui-resizable-alsoresize", { + width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), + left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) + }); + }); + }; + + if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { + if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } + else { $.each(o.alsoResize, function (exp) { _store(exp); }); } + }else{ + _store(o.alsoResize); + } + }, + + resize: function (event, ui) { + var that = $(this).data("ui-resizable"), + o = that.options, + os = that.originalSize, + op = that.originalPosition, + delta = { + height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, + top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 + }, + + _alsoResize = function (exp, c) { + $(exp).each(function() { + var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, + css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; + + $.each(css, function (i, prop) { + var sum = (start[prop]||0) + (delta[prop]||0); + if (sum && sum >= 0) { + style[prop] = sum || null; + } + }); + + el.css(style); + }); + }; + + if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { + $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); + }else{ + _alsoResize(o.alsoResize); + } + }, + + stop: function () { + $(this).removeData("resizable-alsoresize"); + } +}); + +$.ui.plugin.add("resizable", "ghost", { + + start: function() { + + var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; + + that.ghost = that.originalElement.clone(); + that.ghost + .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) + .addClass("ui-resizable-ghost") + .addClass(typeof o.ghost === "string" ? o.ghost : ""); + + that.ghost.appendTo(that.helper); + + }, + + resize: function(){ + var that = $(this).data("ui-resizable"); + if (that.ghost) { + that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); + } + }, + + stop: function() { + var that = $(this).data("ui-resizable"); + if (that.ghost && that.helper) { + that.helper.get(0).removeChild(that.ghost.get(0)); + } + } + +}); + +$.ui.plugin.add("resizable", "grid", { + + resize: function() { + var that = $(this).data("ui-resizable"), + o = that.options, + cs = that.size, + os = that.originalSize, + op = that.originalPosition, + a = that.axis, + grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, + gridX = (grid[0]||1), + gridY = (grid[1]||1), + ox = Math.round((cs.width - os.width) / gridX) * gridX, + oy = Math.round((cs.height - os.height) / gridY) * gridY, + newWidth = os.width + ox, + newHeight = os.height + oy, + isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), + isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), + isMinWidth = o.minWidth && (o.minWidth > newWidth), + isMinHeight = o.minHeight && (o.minHeight > newHeight); + + o.grid = grid; + + if (isMinWidth) { + newWidth = newWidth + gridX; + } + if (isMinHeight) { + newHeight = newHeight + gridY; + } + if (isMaxWidth) { + newWidth = newWidth - gridX; + } + if (isMaxHeight) { + newHeight = newHeight - gridY; + } + + if (/^(se|s|e)$/.test(a)) { + that.size.width = newWidth; + that.size.height = newHeight; + } else if (/^(ne)$/.test(a)) { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.top = op.top - oy; + } else if (/^(sw)$/.test(a)) { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.left = op.left - ox; + } else { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.top = op.top - oy; + that.position.left = op.left - ox; + } + } + +}); + +})(jQuery); +(function( $, undefined ) { + +$.widget("ui.selectable", $.ui.mouse, { + version: "1.10.0", + options: { + appendTo: "body", + autoRefresh: true, + distance: 0, + filter: "*", + tolerance: "touch", + + // callbacks + selected: null, + selecting: null, + start: null, + stop: null, + unselected: null, + unselecting: null + }, + _create: function() { + var selectees, + that = this; + + this.element.addClass("ui-selectable"); + + this.dragged = false; + + // cache selectee children based on filter + this.refresh = function() { + selectees = $(that.options.filter, that.element[0]); + selectees.addClass("ui-selectee"); + selectees.each(function() { + var $this = $(this), + pos = $this.offset(); + $.data(this, "selectable-item", { + element: this, + $element: $this, + left: pos.left, + top: pos.top, + right: pos.left + $this.outerWidth(), + bottom: pos.top + $this.outerHeight(), + startselected: false, + selected: $this.hasClass("ui-selected"), + selecting: $this.hasClass("ui-selecting"), + unselecting: $this.hasClass("ui-unselecting") + }); + }); + }; + this.refresh(); + + this.selectees = selectees.addClass("ui-selectee"); + + this._mouseInit(); + + this.helper = $("
                "); + }, + + _destroy: function() { + this.selectees + .removeClass("ui-selectee") + .removeData("selectable-item"); + this.element + .removeClass("ui-selectable ui-selectable-disabled"); + this._mouseDestroy(); + }, + + _mouseStart: function(event) { + var that = this, + options = this.options; + + this.opos = [event.pageX, event.pageY]; + + if (this.options.disabled) { + return; + } + + this.selectees = $(options.filter, this.element[0]); + + this._trigger("start", event); + + $(options.appendTo).append(this.helper); + // position helper (lasso) + this.helper.css({ + "left": event.pageX, + "top": event.pageY, + "width": 0, + "height": 0 + }); + + if (options.autoRefresh) { + this.refresh(); + } + + this.selectees.filter(".ui-selected").each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.startselected = true; + if (!event.metaKey && !event.ctrlKey) { + selectee.$element.removeClass("ui-selected"); + selectee.selected = false; + selectee.$element.addClass("ui-unselecting"); + selectee.unselecting = true; + // selectable UNSELECTING callback + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + }); + + $(event.target).parents().addBack().each(function() { + var doSelect, + selectee = $.data(this, "selectable-item"); + if (selectee) { + doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); + selectee.$element + .removeClass(doSelect ? "ui-unselecting" : "ui-selected") + .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); + selectee.unselecting = !doSelect; + selectee.selecting = doSelect; + selectee.selected = doSelect; + // selectable (UN)SELECTING callback + if (doSelect) { + that._trigger("selecting", event, { + selecting: selectee.element + }); + } else { + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + return false; + } + }); + + }, + + _mouseDrag: function(event) { + + this.dragged = true; + + if (this.options.disabled) { + return; + } + + var tmp, + that = this, + options = this.options, + x1 = this.opos[0], + y1 = this.opos[1], + x2 = event.pageX, + y2 = event.pageY; + + if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } + if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } + this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); + + this.selectees.each(function() { + var selectee = $.data(this, "selectable-item"), + hit = false; + + //prevent helper from being selected if appendTo: selectable + if (!selectee || selectee.element === that.element[0]) { + return; + } + + if (options.tolerance === "touch") { + hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); + } else if (options.tolerance === "fit") { + hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); + } + + if (hit) { + // SELECT + if (selectee.selected) { + selectee.$element.removeClass("ui-selected"); + selectee.selected = false; + } + if (selectee.unselecting) { + selectee.$element.removeClass("ui-unselecting"); + selectee.unselecting = false; + } + if (!selectee.selecting) { + selectee.$element.addClass("ui-selecting"); + selectee.selecting = true; + // selectable SELECTING callback + that._trigger("selecting", event, { + selecting: selectee.element + }); + } + } else { + // UNSELECT + if (selectee.selecting) { + if ((event.metaKey || event.ctrlKey) && selectee.startselected) { + selectee.$element.removeClass("ui-selecting"); + selectee.selecting = false; + selectee.$element.addClass("ui-selected"); + selectee.selected = true; + } else { + selectee.$element.removeClass("ui-selecting"); + selectee.selecting = false; + if (selectee.startselected) { + selectee.$element.addClass("ui-unselecting"); + selectee.unselecting = true; + } + // selectable UNSELECTING callback + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + if (selectee.selected) { + if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { + selectee.$element.removeClass("ui-selected"); + selectee.selected = false; + + selectee.$element.addClass("ui-unselecting"); + selectee.unselecting = true; + // selectable UNSELECTING callback + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + } + }); + + return false; + }, + + _mouseStop: function(event) { + var that = this; + + this.dragged = false; + + $(".ui-unselecting", this.element[0]).each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.$element.removeClass("ui-unselecting"); + selectee.unselecting = false; + selectee.startselected = false; + that._trigger("unselected", event, { + unselected: selectee.element + }); + }); + $(".ui-selecting", this.element[0]).each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); + selectee.selecting = false; + selectee.selected = true; + selectee.startselected = true; + that._trigger("selected", event, { + selected: selectee.element + }); + }); + this._trigger("stop", event); + + this.helper.remove(); + + return false; + } + +}); + +})(jQuery); +(function( $, undefined ) { + +/*jshint loopfunc: true */ + +function isOverAxis( x, reference, size ) { + return ( x > reference ) && ( x < ( reference + size ) ); +} + +$.widget("ui.sortable", $.ui.mouse, { + version: "1.10.0", + widgetEventPrefix: "sort", + ready: false, + options: { + appendTo: "parent", + axis: false, + connectWith: false, + containment: false, + cursor: "auto", + cursorAt: false, + dropOnEmpty: true, + forcePlaceholderSize: false, + forceHelperSize: false, + grid: false, + handle: false, + helper: "original", + items: "> *", + opacity: false, + placeholder: false, + revert: false, + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + scope: "default", + tolerance: "intersect", + zIndex: 1000, + + // callbacks + activate: null, + beforeStop: null, + change: null, + deactivate: null, + out: null, + over: null, + receive: null, + remove: null, + sort: null, + start: null, + stop: null, + update: null + }, + _create: function() { + + var o = this.options; + this.containerCache = {}; + this.element.addClass("ui-sortable"); + + //Get the items + this.refresh(); + + //Let's determine if the items are being displayed horizontally + this.floating = this.items.length ? o.axis === "x" || (/left|right/).test(this.items[0].item.css("float")) || (/inline|table-cell/).test(this.items[0].item.css("display")) : false; + + //Let's determine the parent's offset + this.offset = this.element.offset(); + + //Initialize mouse events for interaction + this._mouseInit(); + + //We're ready to go + this.ready = true; + + }, + + _destroy: function() { + this.element + .removeClass("ui-sortable ui-sortable-disabled"); + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) { + this.items[i].item.removeData(this.widgetName + "-item"); + } + + return this; + }, + + _setOption: function(key, value){ + if ( key === "disabled" ) { + this.options[ key ] = value; + + this.widget().toggleClass( "ui-sortable-disabled", !!value ); + } else { + // Don't call widget base _setOption for disable as it adds ui-state-disabled class + $.Widget.prototype._setOption.apply(this, arguments); + } + }, + + _mouseCapture: function(event, overrideHandle) { + var currentItem = null, + validHandle = false, + that = this; + + if (this.reverting) { + return false; + } + + if(this.options.disabled || this.options.type === "static") { + return false; + } + + //We have to refresh the items data once first + this._refreshItems(event); + + //Find out if the clicked node (or one of its parents) is a actual item in this.items + $(event.target).parents().each(function() { + if($.data(this, that.widgetName + "-item") === that) { + currentItem = $(this); + return false; + } + }); + if($.data(event.target, that.widgetName + "-item") === that) { + currentItem = $(event.target); + } + + if(!currentItem) { + return false; + } + if(this.options.handle && !overrideHandle) { + $(this.options.handle, currentItem).find("*").addBack().each(function() { + if(this === event.target) { + validHandle = true; + } + }); + if(!validHandle) { + return false; + } + } + + this.currentItem = currentItem; + this._removeCurrentsFromItems(); + return true; + + }, + + _mouseStart: function(event, overrideHandle, noActivation) { + + var i, + o = this.options; + + this.currentContainer = this; + + //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture + this.refreshPositions(); + + //Create and append the visible helper + this.helper = this._createHelper(event); + + //Cache the helper size + this._cacheHelperProportions(); + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + //Cache the margins of the original element + this._cacheMargins(); + + //Get the next scrolling parent + this.scrollParent = this.helper.scrollParent(); + + //The element's absolute position on the page minus margins + this.offset = this.currentItem.offset(); + this.offset = { + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; + + $.extend(this.offset, { + click: { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper + }); + + // Only after we got the offset, we can change the helper's position to absolute + // TODO: Still need to figure out a way to make relative sorting possible + this.helper.css("position", "absolute"); + this.cssPosition = this.helper.css("position"); + + //Generate the original position + this.originalPosition = this._generatePosition(event); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); + + //Cache the former DOM position + this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; + + //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way + if(this.helper[0] !== this.currentItem[0]) { + this.currentItem.hide(); + } + + //Create the placeholder + this._createPlaceholder(); + + //Set a containment if given in the options + if(o.containment) { + this._setContainment(); + } + + if(o.cursor) { // cursor option + if ($("body").css("cursor")) { + this._storedCursor = $("body").css("cursor"); + } + $("body").css("cursor", o.cursor); + } + + if(o.opacity) { // opacity option + if (this.helper.css("opacity")) { + this._storedOpacity = this.helper.css("opacity"); + } + this.helper.css("opacity", o.opacity); + } + + if(o.zIndex) { // zIndex option + if (this.helper.css("zIndex")) { + this._storedZIndex = this.helper.css("zIndex"); + } + this.helper.css("zIndex", o.zIndex); + } + + //Prepare scrolling + if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { + this.overflowOffset = this.scrollParent.offset(); + } + + //Call callbacks + this._trigger("start", event, this._uiHash()); + + //Recache the helper size + if(!this._preserveHelperProportions) { + this._cacheHelperProportions(); + } + + + //Post "activate" events to possible containers + if( !noActivation ) { + for ( i = this.containers.length - 1; i >= 0; i-- ) { + this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); + } + } + + //Prepare possible droppables + if($.ui.ddmanager) { + $.ui.ddmanager.current = this; + } + + if ($.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(this, event); + } + + this.dragging = true; + + this.helper.addClass("ui-sortable-helper"); + this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position + return true; + + }, + + _mouseDrag: function(event) { + var i, item, itemElement, intersection, + o = this.options, + scrolled = false; + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + if (!this.lastPositionAbs) { + this.lastPositionAbs = this.positionAbs; + } + + //Do scrolling + if(this.options.scroll) { + if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { + + if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { + this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; + } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { + this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; + } + + if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { + this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; + } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { + this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; + } + + } else { + + if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { + scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); + } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { + scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); + } + + if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { + scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); + } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { + scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); + } + + } + + if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(this, event); + } + } + + //Regenerate the absolute position used for position checks + this.positionAbs = this._convertPositionTo("absolute"); + + //Set the helper position + if(!this.options.axis || this.options.axis !== "y") { + this.helper[0].style.left = this.position.left+"px"; + } + if(!this.options.axis || this.options.axis !== "x") { + this.helper[0].style.top = this.position.top+"px"; + } + + //Rearrange + for (i = this.items.length - 1; i >= 0; i--) { + + //Cache variables and intersection, continue if no intersection + item = this.items[i]; + itemElement = item.item[0]; + intersection = this._intersectsWithPointer(item); + if (!intersection) { + continue; + } + + // Only put the placeholder inside the current Container, skip all + // items form other containers. This works because when moving + // an item from one container to another the + // currentContainer is switched before the placeholder is moved. + // + // Without this moving items in "sub-sortables" can cause the placeholder to jitter + // beetween the outer and inner container. + if (item.instance !== this.currentContainer) { + continue; + } + + // cannot intersect with itself + // no useless actions that have been done before + // no action if the item moved is the parent of the item checked + if (itemElement !== this.currentItem[0] && + this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && + !$.contains(this.placeholder[0], itemElement) && + (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) + ) { + + this.direction = intersection === 1 ? "down" : "up"; + + if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { + this._rearrange(event, item); + } else { + break; + } + + this._trigger("change", event, this._uiHash()); + break; + } + } + + //Post events to containers + this._contactContainers(event); + + //Interconnect with droppables + if($.ui.ddmanager) { + $.ui.ddmanager.drag(this, event); + } + + //Call callbacks + this._trigger("sort", event, this._uiHash()); + + this.lastPositionAbs = this.positionAbs; + return false; + + }, + + _mouseStop: function(event, noPropagation) { + + if(!event) { + return; + } + + //If we are using droppables, inform the manager about the drop + if ($.ui.ddmanager && !this.options.dropBehaviour) { + $.ui.ddmanager.drop(this, event); + } + + if(this.options.revert) { + var that = this, + cur = this.placeholder.offset(); + + this.reverting = true; + + $(this.helper).animate({ + left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft), + top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop) + }, parseInt(this.options.revert, 10) || 500, function() { + that._clear(event); + }); + } else { + this._clear(event, noPropagation); + } + + return false; + + }, + + cancel: function() { + + if(this.dragging) { + + this._mouseUp({ target: null }); + + if(this.options.helper === "original") { + this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); + } else { + this.currentItem.show(); + } + + //Post deactivating events to containers + for (var i = this.containers.length - 1; i >= 0; i--){ + this.containers[i]._trigger("deactivate", null, this._uiHash(this)); + if(this.containers[i].containerCache.over) { + this.containers[i]._trigger("out", null, this._uiHash(this)); + this.containers[i].containerCache.over = 0; + } + } + + } + + if (this.placeholder) { + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! + if(this.placeholder[0].parentNode) { + this.placeholder[0].parentNode.removeChild(this.placeholder[0]); + } + if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { + this.helper.remove(); + } + + $.extend(this, { + helper: null, + dragging: false, + reverting: false, + _noFinalSort: null + }); + + if(this.domPosition.prev) { + $(this.domPosition.prev).after(this.currentItem); + } else { + $(this.domPosition.parent).prepend(this.currentItem); + } + } + + return this; + + }, + + serialize: function(o) { + + var items = this._getItemsAsjQuery(o && o.connected), + str = []; + o = o || {}; + + $(items).each(function() { + var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); + if (res) { + str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); + } + }); + + if(!str.length && o.key) { + str.push(o.key + "="); + } + + return str.join("&"); + + }, + + toArray: function(o) { + + var items = this._getItemsAsjQuery(o && o.connected), + ret = []; + + o = o || {}; + + items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); + return ret; + + }, + + /* Be careful with the following core functions */ + _intersectsWith: function(item) { + + var x1 = this.positionAbs.left, + x2 = x1 + this.helperProportions.width, + y1 = this.positionAbs.top, + y2 = y1 + this.helperProportions.height, + l = item.left, + r = l + item.width, + t = item.top, + b = t + item.height, + dyClick = this.offset.click.top, + dxClick = this.offset.click.left, + isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; + + if ( this.options.tolerance === "pointer" || + this.options.forcePointerForContainers || + (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) + ) { + return isOverElement; + } else { + + return (l < x1 + (this.helperProportions.width / 2) && // Right Half + x2 - (this.helperProportions.width / 2) < r && // Left Half + t < y1 + (this.helperProportions.height / 2) && // Bottom Half + y2 - (this.helperProportions.height / 2) < b ); // Top Half + + } + }, + + _intersectsWithPointer: function(item) { + + var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), + isOverElement = isOverElementHeight && isOverElementWidth, + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + if (!isOverElement) { + return false; + } + + return this.floating ? + ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) + : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); + + }, + + _intersectsWithSides: function(item) { + + var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), + isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + if (this.floating && horizontalDirection) { + return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); + } else { + return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); + } + + }, + + _getDragVerticalDirection: function() { + var delta = this.positionAbs.top - this.lastPositionAbs.top; + return delta !== 0 && (delta > 0 ? "down" : "up"); + }, + + _getDragHorizontalDirection: function() { + var delta = this.positionAbs.left - this.lastPositionAbs.left; + return delta !== 0 && (delta > 0 ? "right" : "left"); + }, + + refresh: function(event) { + this._refreshItems(event); + this.refreshPositions(); + return this; + }, + + _connectWith: function() { + var options = this.options; + return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; + }, + + _getItemsAsjQuery: function(connected) { + + var i, j, cur, inst, + items = [], + queries = [], + connectWith = this._connectWith(); + + if(connectWith && connected) { + for (i = connectWith.length - 1; i >= 0; i--){ + cur = $(connectWith[i]); + for ( j = cur.length - 1; j >= 0; j--){ + inst = $.data(cur[j], this.widgetFullName); + if(inst && inst !== this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); + } + } + } + } + + queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]); + + for (i = queries.length - 1; i >= 0; i--){ + queries[i][0].each(function() { + items.push(this); + }); + } + + return $(items); + + }, + + _removeCurrentsFromItems: function() { + + var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); + + this.items = $.grep(this.items, function (item) { + for (var j=0; j < list.length; j++) { + if(list[j] === item.item[0]) { + return false; + } + } + return true; + }); + + }, + + _refreshItems: function(event) { + + this.items = []; + this.containers = [this]; + + var i, j, cur, inst, targetData, _queries, item, queriesLength, + items = this.items, + queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], + connectWith = this._connectWith(); + + if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down + for (i = connectWith.length - 1; i >= 0; i--){ + cur = $(connectWith[i]); + for (j = cur.length - 1; j >= 0; j--){ + inst = $.data(cur[j], this.widgetFullName); + if(inst && inst !== this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); + this.containers.push(inst); + } + } + } + } + + for (i = queries.length - 1; i >= 0; i--) { + targetData = queries[i][1]; + _queries = queries[i][0]; + + for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { + item = $(_queries[j]); + + item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) + + items.push({ + item: item, + instance: targetData, + width: 0, height: 0, + left: 0, top: 0 + }); + } + } + + }, + + refreshPositions: function(fast) { + + //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change + if(this.offsetParent && this.helper) { + this.offset.parent = this._getParentOffset(); + } + + var i, item, t, p; + + for (i = this.items.length - 1; i >= 0; i--){ + item = this.items[i]; + + //We ignore calculating positions of all connected containers when we're not over them + if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { + continue; + } + + t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; + + if (!fast) { + item.width = t.outerWidth(); + item.height = t.outerHeight(); + } + + p = t.offset(); + item.left = p.left; + item.top = p.top; + } + + if(this.options.custom && this.options.custom.refreshContainers) { + this.options.custom.refreshContainers.call(this); + } else { + for (i = this.containers.length - 1; i >= 0; i--){ + p = this.containers[i].element.offset(); + this.containers[i].containerCache.left = p.left; + this.containers[i].containerCache.top = p.top; + this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); + this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); + } + } + + return this; + }, + + _createPlaceholder: function(that) { + that = that || this; + var className, + o = that.options; + + if(!o.placeholder || o.placeholder.constructor === String) { + className = o.placeholder; + o.placeholder = { + element: function() { + + var el = $(document.createElement(that.currentItem[0].nodeName)) + .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") + .removeClass("ui-sortable-helper")[0]; + + if(!className) { + el.style.visibility = "hidden"; + } + + return el; + }, + update: function(container, p) { + + // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that + // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified + if(className && !o.forcePlaceholderSize) { + return; + } + + //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item + if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } + if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } + } + }; + } + + //Create the placeholder + that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); + + //Append it after the actual current item + that.currentItem.after(that.placeholder); + + //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) + o.placeholder.update(that, that.placeholder); + + }, + + _contactContainers: function(event) { + var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, + innermostContainer = null, + innermostIndex = null; + + // get innermost container that intersects with item + for (i = this.containers.length - 1; i >= 0; i--) { + + // never consider a container that's located within the item itself + if($.contains(this.currentItem[0], this.containers[i].element[0])) { + continue; + } + + if(this._intersectsWith(this.containers[i].containerCache)) { + + // if we've already found a container and it's more "inner" than this, then continue + if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { + continue; + } + + innermostContainer = this.containers[i]; + innermostIndex = i; + + } else { + // container doesn't intersect. trigger "out" event if necessary + if(this.containers[i].containerCache.over) { + this.containers[i]._trigger("out", event, this._uiHash(this)); + this.containers[i].containerCache.over = 0; + } + } + + } + + // if no intersecting containers found, return + if(!innermostContainer) { + return; + } + + // move the item into the container if it's not there already + if(this.containers.length === 1) { + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } else { + + //When entering a new container, we will find the item with the least distance and append our item near it + dist = 10000; + itemWithLeastDistance = null; + posProperty = this.containers[innermostIndex].floating ? "left" : "top"; + sizeProperty = this.containers[innermostIndex].floating ? "width" : "height"; + base = this.positionAbs[posProperty] + this.offset.click[posProperty]; + for (j = this.items.length - 1; j >= 0; j--) { + if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { + continue; + } + if(this.items[j].item[0] === this.currentItem[0]) { + continue; + } + cur = this.items[j].item.offset()[posProperty]; + nearBottom = false; + if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ + nearBottom = true; + cur += this.items[j][sizeProperty]; + } + + if(Math.abs(cur - base) < dist) { + dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; + this.direction = nearBottom ? "up": "down"; + } + } + + //Check if dropOnEmpty is enabled + if(!itemWithLeastDistance && !this.options.dropOnEmpty) { + return; + } + + this.currentContainer = this.containers[innermostIndex]; + itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); + this._trigger("change", event, this._uiHash()); + this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); + + //Update the placeholder + this.options.placeholder.update(this.currentContainer, this.placeholder); + + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } + + + }, + + _createHelper: function(event) { + + var o = this.options, + helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); + + //Add the helper to the DOM if that didn't happen already + if(!helper.parents("body").length) { + $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); + } + + if(helper[0] === this.currentItem[0]) { + this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; + } + + if(!helper[0].style.width || o.forceHelperSize) { + helper.width(this.currentItem.width()); + } + if(!helper[0].style.height || o.forceHelperSize) { + helper.height(this.currentItem.height()); + } + + return helper; + + }, + + _adjustOffsetFromHelper: function(obj) { + if (typeof obj === "string") { + obj = obj.split(" "); + } + if ($.isArray(obj)) { + obj = {left: +obj[0], top: +obj[1] || 0}; + } + if ("left" in obj) { + this.offset.click.left = obj.left + this.margins.left; + } + if ("right" in obj) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ("top" in obj) { + this.offset.click.top = obj.top + this.margins.top; + } + if ("bottom" in obj) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } + }, + + _getParentOffset: function() { + + + //Get the offsetParent and cache its position + this.offsetParent = this.helper.offsetParent(); + var po = this.offsetParent.offset(); + + // This is a special case where we need to modify a offset calculated on start, since the following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that + // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag + if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); + } + + // This needs to be actually done for all browsers, since pageX/pageY includes this information + // with an ugly IE fix + if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { + po = { top: 0, left: 0 }; + } + + return { + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) + }; + + }, + + _getRelativeOffset: function() { + + if(this.cssPosition === "relative") { + var p = this.currentItem.position(); + return { + top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), + left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() + }; + } else { + return { top: 0, left: 0 }; + } + + }, + + _cacheMargins: function() { + this.margins = { + left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), + top: (parseInt(this.currentItem.css("marginTop"),10) || 0) + }; + }, + + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var ce, co, over, + o = this.options; + if(o.containment === "parent") { + o.containment = this.helper[0].parentNode; + } + if(o.containment === "document" || o.containment === "window") { + this.containment = [ + 0 - this.offset.relative.left - this.offset.parent.left, + 0 - this.offset.relative.top - this.offset.parent.top, + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top + ]; + } + + if(!(/^(document|window|parent)$/).test(o.containment)) { + ce = $(o.containment)[0]; + co = $(o.containment).offset(); + over = ($(ce).css("overflow") !== "hidden"); + + this.containment = [ + co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, + co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, + co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, + co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top + ]; + } + + }, + + _convertPositionTo: function(d, pos) { + + if(!pos) { + pos = this.position; + } + var mod = d === "absolute" ? 1 : -1, + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, + scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + return { + top: ( + pos.top + // The absolute mouse position + this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + ), + left: ( + pos.left + // The absolute mouse position + this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + ) + }; + + }, + + _generatePosition: function(event) { + + var top, left, + o = this.options, + pageX = event.pageX, + pageY = event.pageY, + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + // This is another very weird special case that only happens for relative elements: + // 1. If the css position is relative + // 2. and the scroll parent is the document or similar to the offset parent + // we have to refresh the relative offset during the scroll so there are no jumps + if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { + this.offset.relative = this._getRelativeOffset(); + } + + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ + + if(this.originalPosition) { //If we are not dragging yet, we won't check for options + + if(this.containment) { + if(event.pageX - this.offset.click.left < this.containment[0]) { + pageX = this.containment[0] + this.offset.click.left; + } + if(event.pageY - this.offset.click.top < this.containment[1]) { + pageY = this.containment[1] + this.offset.click.top; + } + if(event.pageX - this.offset.click.left > this.containment[2]) { + pageX = this.containment[2] + this.offset.click.left; + } + if(event.pageY - this.offset.click.top > this.containment[3]) { + pageY = this.containment[3] + this.offset.click.top; + } + } + + if(o.grid) { + top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; + pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; + + left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; + pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; + } + + } + + return { + top: ( + pageY - // The absolute mouse position + this.offset.click.top - // Click offset (relative to the element) + this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top + // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + ), + left: ( + pageX - // The absolute mouse position + this.offset.click.left - // Click offset (relative to the element) + this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left + // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + ) + }; + + }, + + _rearrange: function(event, i, a, hardRefresh) { + + a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); + + //Various things done here to improve the performance: + // 1. we create a setTimeout, that calls refreshPositions + // 2. on the instance, we have a counter variable, that get's higher after every append + // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same + // 4. this lets only the last addition to the timeout stack through + this.counter = this.counter ? ++this.counter : 1; + var counter = this.counter; + + this._delay(function() { + if(counter === this.counter) { + this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove + } + }); + + }, + + _clear: function(event, noPropagation) { + + this.reverting = false; + // We delay all events that have to be triggered to after the point where the placeholder has been removed and + // everything else normalized again + var i, + delayedTriggers = []; + + // We first have to update the dom position of the actual currentItem + // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) + if(!this._noFinalSort && this.currentItem.parent().length) { + this.placeholder.before(this.currentItem); + } + this._noFinalSort = null; + + if(this.helper[0] === this.currentItem[0]) { + for(i in this._storedCSS) { + if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { + this._storedCSS[i] = ""; + } + } + this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); + } else { + this.currentItem.show(); + } + + if(this.fromOutside && !noPropagation) { + delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); + } + if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { + delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed + } + + // Check if the items Container has Changed and trigger appropriate + // events. + if (this !== this.currentContainer) { + if(!noPropagation) { + delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); + delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + } + } + + + //Post events to containers + for (i = this.containers.length - 1; i >= 0; i--){ + if(!noPropagation) { + delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); + } + if(this.containers[i].containerCache.over) { + delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); + this.containers[i].containerCache.over = 0; + } + } + + //Do what was originally in plugins + if(this._storedCursor) { + $("body").css("cursor", this._storedCursor); + } + if(this._storedOpacity) { + this.helper.css("opacity", this._storedOpacity); + } + if(this._storedZIndex) { + this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); + } + + this.dragging = false; + if(this.cancelHelperRemoval) { + if(!noPropagation) { + this._trigger("beforeStop", event, this._uiHash()); + for (i=0; i < delayedTriggers.length; i++) { + delayedTriggers[i].call(this, event); + } //Trigger all delayed events + this._trigger("stop", event, this._uiHash()); + } + + this.fromOutside = false; + return false; + } + + if(!noPropagation) { + this._trigger("beforeStop", event, this._uiHash()); + } + + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! + this.placeholder[0].parentNode.removeChild(this.placeholder[0]); + + if(this.helper[0] !== this.currentItem[0]) { + this.helper.remove(); + } + this.helper = null; + + if(!noPropagation) { + for (i=0; i < delayedTriggers.length; i++) { + delayedTriggers[i].call(this, event); + } //Trigger all delayed events + this._trigger("stop", event, this._uiHash()); + } + + this.fromOutside = false; + return true; + + }, + + _trigger: function() { + if ($.Widget.prototype._trigger.apply(this, arguments) === false) { + this.cancel(); + } + }, + + _uiHash: function(_inst) { + var inst = _inst || this; + return { + helper: inst.helper, + placeholder: inst.placeholder || $([]), + position: inst.position, + originalPosition: inst.originalPosition, + offset: inst.positionAbs, + item: inst.currentItem, + sender: _inst ? _inst.element : null + }; + } + +}); + +})(jQuery); +(function( $, undefined ) { + +var uid = 0, + hideProps = {}, + showProps = {}; + +hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = + hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; +showProps.height = showProps.paddingTop = showProps.paddingBottom = + showProps.borderTopWidth = showProps.borderBottomWidth = "show"; + +$.widget( "ui.accordion", { + version: "1.10.0", + options: { + active: 0, + animate: {}, + collapsible: false, + event: "click", + header: "> li > :first-child,> :not(li):even", + heightStyle: "auto", + icons: { + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" + }, + + // callbacks + activate: null, + beforeActivate: null + }, + + _create: function() { + var options = this.options; + this.prevShow = this.prevHide = $(); + this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) + // ARIA + .attr( "role", "tablist" ); + + // don't allow collapsible: false and active: false / null + if ( !options.collapsible && (options.active === false || options.active == null) ) { + options.active = 0; + } + + this._processPanels(); + // handle negative values + if ( options.active < 0 ) { + options.active += this.headers.length; + } + this._refresh(); + }, + + _getCreateEventData: function() { + return { + header: this.active, + content: !this.active.length ? $() : this.active.next() + }; + }, + + _createIcons: function() { + var icons = this.options.icons; + if ( icons ) { + $( "" ) + .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) + .prependTo( this.headers ); + this.active.children( ".ui-accordion-header-icon" ) + .removeClass( icons.header ) + .addClass( icons.activeHeader ); + this.headers.addClass( "ui-accordion-icons" ); + } + }, + + _destroyIcons: function() { + this.headers + .removeClass( "ui-accordion-icons" ) + .children( ".ui-accordion-header-icon" ) + .remove(); + }, + + _destroy: function() { + var contents; + + // clean up main element + this.element + .removeClass( "ui-accordion ui-widget ui-helper-reset" ) + .removeAttr( "role" ); + + // clean up headers + this.headers + .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeAttr( "role" ) + .removeAttr( "aria-selected" ) + .removeAttr( "aria-controls" ) + .removeAttr( "tabIndex" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + this._destroyIcons(); + + // clean up content panels + contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-labelledby" ) + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + if ( this.options.heightStyle !== "content" ) { + contents.css( "height", "" ); + } + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "event" ) { + if ( this.options.event ) { + this._off( this.headers, this.options.event ); + } + this._setupEvents( value ); + } + + this._super( key, value ); + + // setting collapsible: false while collapsed; open first panel + if ( key === "collapsible" && !value && this.options.active === false ) { + this._activate( 0 ); + } + + if ( key === "icons" ) { + this._destroyIcons(); + if ( value ) { + this._createIcons(); + } + } + + // #5332 - opacity doesn't cascade to positioned elements in IE + // so we need to add the disabled class to the headers and panels + if ( key === "disabled" ) { + this.headers.add( this.headers.next() ) + .toggleClass( "ui-state-disabled", !!value ); + } + }, + + _keydown: function( event ) { + /*jshint maxcomplexity:15*/ + if ( event.altKey || event.ctrlKey ) { + return; + } + + var keyCode = $.ui.keyCode, + length = this.headers.length, + currentIndex = this.headers.index( event.target ), + toFocus = false; + + switch ( event.keyCode ) { + case keyCode.RIGHT: + case keyCode.DOWN: + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; + break; + case keyCode.LEFT: + case keyCode.UP: + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; + break; + case keyCode.SPACE: + case keyCode.ENTER: + this._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; + } + + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); + toFocus.focus(); + event.preventDefault(); + } + }, + + _panelKeyDown : function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().focus(); + } + }, + + refresh: function() { + var options = this.options; + this._processPanels(); + + // was collapsed or no panel + if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { + options.active = false; + this.active = $(); + // active false only when collapsible is true + } if ( options.active === false ) { + this._activate( 0 ); + // was active, but active panel is gone + } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + // all remaining panel are disabled + if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { + options.active = false; + this.active = $(); + // activate previous panel + } else { + this._activate( Math.max( 0, options.active - 1 ) ); + } + // was active, active panel still exists + } else { + // make sure active index is correct + options.active = this.headers.index( this.active ); + } + + this._destroyIcons(); + + this._refresh(); + }, + + _processPanels: function() { + this.headers = this.element.find( this.options.header ) + .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); + + this.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) + .filter(":not(.ui-accordion-content-active)") + .hide(); + }, + + _refresh: function() { + var maxHeight, + options = this.options, + heightStyle = options.heightStyle, + parent = this.element.parent(), + accordionId = this.accordionId = "ui-accordion-" + + (this.element.attr( "id" ) || ++uid); + + this.active = this._findActive( options.active ) + .addClass( "ui-accordion-header-active ui-state-active" ) + .toggleClass( "ui-corner-all ui-corner-top" ); + this.active.next() + .addClass( "ui-accordion-content-active" ) + .show(); + + this.headers + .attr( "role", "tab" ) + .each(function( i ) { + var header = $( this ), + headerId = header.attr( "id" ), + panel = header.next(), + panelId = panel.attr( "id" ); + if ( !headerId ) { + headerId = accordionId + "-header-" + i; + header.attr( "id", headerId ); + } + if ( !panelId ) { + panelId = accordionId + "-panel-" + i; + panel.attr( "id", panelId ); + } + header.attr( "aria-controls", panelId ); + panel.attr( "aria-labelledby", headerId ); + }) + .next() + .attr( "role", "tabpanel" ); + + this.headers + .not( this.active ) + .attr({ + "aria-selected": "false", + tabIndex: -1 + }) + .next() + .attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }) + .hide(); + + // make sure at least one header is in the tab order + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active.attr({ + "aria-selected": "true", + tabIndex: 0 + }) + .next() + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }); + } + + this._createIcons(); + + this._setupEvents( options.event ); + + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + this.element.siblings( ":visible" ).each(function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + }); + + this.headers.each(function() { + maxHeight -= $( this ).outerHeight( true ); + }); + + this.headers.next() + .each(function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + }) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.headers.next() + .each(function() { + maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); + }) + .height( maxHeight ); + } + }, + + _activate: function( index ) { + var active = this._findActive( index )[ 0 ]; + + // trying to activate the already active panel + if ( active === this.active[ 0 ] ) { + return; + } + + // trying to collapse, simulate a click on the currently active header + active = active || this.active[ 0 ]; + + this._eventHandler({ + target: active, + currentTarget: active, + preventDefault: $.noop + }); + }, + + _findActive: function( selector ) { + return typeof selector === "number" ? this.headers.eq( selector ) : $(); + }, + + _setupEvents: function( event ) { + var events = { + keydown: "_keydown" + }; + if ( event ) { + $.each( event.split(" "), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + }); + } + + this._off( this.headers.add( this.headers.next() ) ); + this._on( this.headers, events ); + this._on( this.headers.next(), { keydown: "_panelKeyDown" }); + this._hoverable( this.headers ); + this._focusable( this.headers ); + }, + + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + clicked = $( event.currentTarget ), + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : clicked.next(), + toHide = active.next(), + eventData = { + oldHeader: active, + oldPanel: toHide, + newHeader: collapsing ? $() : clicked, + newPanel: toShow + }; + + event.preventDefault(); + + if ( + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.headers.index( clicked ); + + // when the call to ._toggle() comes after the class changes + // it causes a very odd bug in IE 8 (see #6720) + this.active = clickedIsActive ? $() : clicked; + this._toggle( eventData ); + + // switch classes + // corner classes on the previously active header stay after the animation + active.removeClass( "ui-accordion-header-active ui-state-active" ); + if ( options.icons ) { + active.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.activeHeader ) + .addClass( options.icons.header ); + } + + if ( !clickedIsActive ) { + clicked + .removeClass( "ui-corner-all" ) + .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); + if ( options.icons ) { + clicked.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.header ) + .addClass( options.icons.activeHeader ); + } + + clicked + .next() + .addClass( "ui-accordion-content-active" ); + } + }, + + _toggle: function( data ) { + var toShow = data.newPanel, + toHide = this.prevShow.length ? this.prevShow : data.oldPanel; + + // handle activating a panel during the animation for another activation + this.prevShow.add( this.prevHide ).stop( true, true ); + this.prevShow = toShow; + this.prevHide = toHide; + + if ( this.options.animate ) { + this._animate( toShow, toHide, data ); + } else { + toHide.hide(); + toShow.show(); + this._toggleComplete( data ); + } + + toHide.attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }); + toHide.prev().attr( "aria-selected", "false" ); + // if we're switching panels, remove the old header from the tab order + // if we're opening from collapsed state, remove the previous header from the tab order + // if we're collapsing, then keep the collapsing header in the tab order + if ( toShow.length && toHide.length ) { + toHide.prev().attr( "tabIndex", -1 ); + } else if ( toShow.length ) { + this.headers.filter(function() { + return $( this ).attr( "tabIndex" ) === 0; + }) + .attr( "tabIndex", -1 ); + } + + toShow + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }) + .prev() + .attr({ + "aria-selected": "true", + tabIndex: 0 + }); + }, + + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + down = toShow.length && + ( !toHide.length || ( toShow.index() < toHide.index() ) ), + animate = this.options.animate || {}, + options = down && animate.down || animate, + complete = function() { + that._toggleComplete( data ); + }; + + if ( typeof options === "number" ) { + duration = options; + } + if ( typeof options === "string" ) { + easing = options; + } + // fall back from options to animation in case of partial down settings + easing = easing || options.easing || animate.easing; + duration = duration || options.duration || animate.duration; + + if ( !toHide.length ) { + return toShow.animate( showProps, duration, easing, complete ); + } + if ( !toShow.length ) { + return toHide.animate( hideProps, duration, easing, complete ); + } + + total = toShow.show().outerHeight(); + toHide.animate( hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); + } + }); + toShow + .hide() + .animate( showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + adjust += fx.now; + } else if ( that.options.heightStyle !== "content" ) { + fx.now = Math.round( total - toHide.outerHeight() - adjust ); + adjust = 0; + } + } + }); + }, + + _toggleComplete: function( data ) { + var toHide = data.oldPanel; + + toHide + .removeClass( "ui-accordion-content-active" ) + .prev() + .removeClass( "ui-corner-top" ) + .addClass( "ui-corner-all" ); + + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[0].className = toHide.parent()[0].className; + } + + this._trigger( "activate", null, data ); + } +}); + +})( jQuery ); +(function( $, undefined ) { + +// used to prevent race conditions with remote data sources +var requestIndex = 0; + +$.widget( "ui.autocomplete", { + version: "1.10.0", + defaultElement: "", + options: { + appendTo: null, + autoFocus: false, + delay: 300, + minLength: 1, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null, + + // callbacks + change: null, + close: null, + focus: null, + open: null, + response: null, + search: null, + select: null + }, + + pending: 0, + + _create: function() { + // Some browsers only repeat keydown events, not keypress events, + // so we use the suppressKeyPress flag to determine if we've already + // handled the keydown event. #7269 + // Unfortunately the code for & in keypress is the same as the up arrow, + // so we use the suppressKeyPressRepeat flag to avoid handling keypress + // events when we know the keydown event was used to modify the + // search term. #7799 + var suppressKeyPress, suppressKeyPressRepeat, suppressInput; + + this.isMultiLine = this._isMultiLine(); + this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; + this.isNewMenu = true; + + this.element + .addClass( "ui-autocomplete-input" ) + .attr( "autocomplete", "off" ); + + this._on( this.element, { + keydown: function( event ) { + /*jshint maxcomplexity:15*/ + if ( this.element.prop( "readOnly" ) ) { + suppressKeyPress = true; + suppressInput = true; + suppressKeyPressRepeat = true; + return; + } + + suppressKeyPress = false; + suppressInput = false; + suppressKeyPressRepeat = false; + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + suppressKeyPress = true; + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + suppressKeyPress = true; + this._move( "nextPage", event ); + break; + case keyCode.UP: + suppressKeyPress = true; + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + suppressKeyPress = true; + this._keyEvent( "next", event ); + break; + case keyCode.ENTER: + case keyCode.NUMPAD_ENTER: + // when menu is open and has focus + if ( this.menu.active ) { + // #6055 - Opera still allows the keypress to occur + // which causes forms to submit + suppressKeyPress = true; + event.preventDefault(); + this.menu.select( event ); + } + break; + case keyCode.TAB: + if ( this.menu.active ) { + this.menu.select( event ); + } + break; + case keyCode.ESCAPE: + if ( this.menu.element.is( ":visible" ) ) { + this._value( this.term ); + this.close( event ); + // Different browsers have different default behavior for escape + // Single press can mean undo or clear + // Double press in IE means clear the whole form + event.preventDefault(); + } + break; + default: + suppressKeyPressRepeat = true; + // search timeout should be triggered before the input value is changed + this._searchTimeout( event ); + break; + } + }, + keypress: function( event ) { + if ( suppressKeyPress ) { + suppressKeyPress = false; + event.preventDefault(); + return; + } + if ( suppressKeyPressRepeat ) { + return; + } + + // replicate some key handlers to allow them to repeat in Firefox and Opera + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + this._move( "nextPage", event ); + break; + case keyCode.UP: + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + this._keyEvent( "next", event ); + break; + } + }, + input: function( event ) { + if ( suppressInput ) { + suppressInput = false; + event.preventDefault(); + return; + } + this._searchTimeout( event ); + }, + focus: function() { + this.selectedItem = null; + this.previous = this._value(); + }, + blur: function( event ) { + if ( this.cancelBlur ) { + delete this.cancelBlur; + return; + } + + clearTimeout( this.searching ); + this.close( event ); + this._change( event ); + } + }); + + this._initSource(); + this.menu = $( "
                ").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&& -c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a
                ").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(b.range==="min"||b.range==="max"?" ui-slider-range-"+b.range:""))}for(var j=c.length;j"); -this.handles=c.add(d(e.join("")).appendTo(a.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(g){g.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur();else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(g){d(this).data("index.ui-slider-handle", -g)});this.handles.keydown(function(g){var k=true,l=d(this).data("index.ui-slider-handle"),i,h,m;if(!a.options.disabled){switch(g.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:k=false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");i=a._start(g,l);if(i===false)return}break}m=a.options.step;i=a.options.values&&a.options.values.length? -(h=a.values(l)):(h=a.value());switch(g.keyCode){case d.ui.keyCode.HOME:h=a._valueMin();break;case d.ui.keyCode.END:h=a._valueMax();break;case d.ui.keyCode.PAGE_UP:h=a._trimAlignValue(i+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(i-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(i===a._valueMax())return;h=a._trimAlignValue(i+m);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(i===a._valueMin())return;h=a._trimAlignValue(i- -m);break}a._slide(g,l,h);return k}}).keyup(function(g){var k=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(g,k);a._change(g,k);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy(); -return this},_mouseCapture:function(a){var b=this.options,c,f,e,j,g;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:a.pageX,y:a.pageY});f=this._valueMax()-this._valueMin()+1;j=this;this.handles.each(function(k){var l=Math.abs(c-j.values(k));if(f>l){f=l;e=d(this);g=k}});if(b.range===true&&this.values(1)===b.min){g+=1;e=d(this.handles[g])}if(this._start(a,g)===false)return false; -this._mouseSliding=true;j._handleIndex=g;e.addClass("ui-state-active").focus();b=e.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-e.width()/2,top:a.pageY-b.top-e.height()/2-(parseInt(e.css("borderTopWidth"),10)||0)-(parseInt(e.css("borderBottomWidth"),10)||0)+(parseInt(e.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(a,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(a){var b= -this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b;if(this.orientation==="horizontal"){b= -this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b); -c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var f;if(this.options.values&&this.options.values.length){f=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>f||b===1&&c1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}else if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;f=arguments[0];for(e=0;e=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a= -this.options.range,b=this.options,c=this,f=!this._animateOff?b.animate:false,e,j={},g,k,l,i;if(this.options.values&&this.options.values.length)this.handles.each(function(h){e=(c.values(h)-c._valueMin())/(c._valueMax()-c._valueMin())*100;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";d(this).stop(1,1)[f?"animate":"css"](j,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(h===0)c.range.stop(1,1)[f?"animate":"css"]({left:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({width:e- -g+"%"},{queue:false,duration:b.animate})}else{if(h===0)c.range.stop(1,1)[f?"animate":"css"]({bottom:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({height:e-g+"%"},{queue:false,duration:b.animate})}g=e});else{k=this.value();l=this._valueMin();i=this._valueMax();e=i!==l?(k-l)/(i-l)*100:0;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[f?"animate":"css"](j,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[f?"animate":"css"]({width:e+"%"}, -b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[f?"animate":"css"]({width:100-e+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[f?"animate":"css"]({height:e+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[f?"animate":"css"]({height:100-e+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.16"})})(jQuery); -;/* - * jQuery UI Tabs 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
                ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
              • #{label}
              • "},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&& -e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= -d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]|| -(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); -this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected= -this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); -if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); -this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+ -g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal", -function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")}; -this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected= --1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; -d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e= -d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b, -e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]); -j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove(); -if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null, -this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this}, -load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c, -"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, -url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.16"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k
                '))}function N(a){return a.bind("mouseout", -function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(d.datepicker._isDisabledDatepicker(J.inline?a.parent()[0]:J.input[0])||!b.length)){b.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); -b.addClass("ui-state-hover");b.hasClass("ui-datepicker-prev")&&b.addClass("ui-datepicker-prev-hover");b.hasClass("ui-datepicker-next")&&b.addClass("ui-datepicker-next-hover")}})}function H(a,b){d.extend(a,b);for(var c in b)if(b[c]==null||b[c]==C)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.16"}});var B=(new Date).getTime(),J;d.extend(M.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv}, -setDefaults:function(a){H(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g, -"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:N(d('
                '))}},_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker", -function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b);b.settings.disabled&&this._disableDatepicker(a)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&b.append.remove();if(c){b.append=d(''+c+"");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c== -"focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('').addClass(this._triggerClass).html(f==""?c:d("").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker(): -d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;gh){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a, -b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),true);this._updateDatepicker(b);this._updateAlternate(b);b.settings.disabled&&this._disableDatepicker(a);b.dpDiv.css("display","block")}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+= -1;this._dialogInput=d('');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}H(a.settings,e||{});b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/ -2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b= -d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e= -a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().removeClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a, -"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().addClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f== -a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input", -a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);if(d.datepicker._curInst&&d.datepicker._curInst!=b){d.datepicker._datepickerShowing&&d.datepicker._triggerOnClose(d.datepicker._curInst);d.datepicker._curInst.dpDiv.stop(true,true)}var c=d.datepicker._get(b,"beforeShow");c=c?c.apply(a,[a,b]):{};if(c!==false){H(b.settings,c);b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value= -"";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b); -c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.datepicker._datepickerShowing= -true;d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}}},_updateDatepicker:function(a){this.maxRows=4;var b=d.datepicker._getBorders(a.dpDiv);J=a;a.dpDiv.empty().append(this._generateHTML(a));var c=a.dpDiv.find("iframe.ui-datepicker-cover");c.length&&c.css({left:-b[0],top:-b[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}); -a.dpDiv.find("."+this._dayOverClass+" a").mouseover();b=this._getNumberOfMonths(a);c=b[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");c>1&&a.dpDiv.addClass("ui-datepicker-multi-"+c).css("width",17*c+"em");a.dpDiv[(b[0]!=1||b[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&& -!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var e=a.yearshtml;setTimeout(function(){e===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);e=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(), -h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b= -this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");if(b)b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b); -this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();d.datepicker._triggerOnClose(b);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")}, -_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"): -0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e["selected"+(c=="M"? -"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a); -this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField"); -if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"? -b.toString():b+"";if(b=="")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=A+1-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,j-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=j||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd", -COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames: -null)||this._defaults.monthNames;var i=function(o){(o=k+1 -12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&& -a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay? -new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&nn;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a)); -n=this._canAdjustMonth(a,-1,m,g)?''+n+"":f?"":''+n+"";var s=this._get(a,"nextText");s=!h?s:this.formatDate(s,this._daylightSavingAdjust(new Date(m, -g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?''+s+"":f?"":''+s+"";j=this._get(a,"currentText");s=this._get(a,"gotoCurrent")&& -a.currentDay?u:b;j=!h?j:this.formatDate(j,s,this._getFormatConfig(a));h=!a.inline?'":"";e=e?'
                '+(c?h:"")+(this._isInRange(a,s)?'":"")+(c?"":h)+"
                ":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");s=this._get(a,"dayNames");this._get(a,"dayNamesShort");var q=this._get(a,"dayNamesMin"),A=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),D=this._get(a,"showOtherMonths"),K=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var E=this._getDefaultDate(a),w="",x=0;x1)switch(G){case 0:y+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:y+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:y+=" ui-datepicker-group-middle";t="";break}y+='">'}y+='
                '+(/all|left/.test(t)&& -x==0?c?f:n:"")+(/all|right/.test(t)&&x==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,x>0||G>0,A,v)+'
                ';var z=j?'":"";for(t=0;t<7;t++){var r=(t+h)%7;z+="=5?' class="ui-datepicker-week-end"':"")+'>'+q[r]+""}y+=z+"";z=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay, -z);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;z=Math.ceil((t+z)/7);this.maxRows=z=l?this.maxRows>z?this.maxRows:z:z;r=this._daylightSavingAdjust(new Date(m,g,1-t));for(var Q=0;Q";var R=!j?"":'";for(t=0;t<7;t++){var I=p?p.apply(a.input?a.input[0]:null,[r]):[true,""],F=r.getMonth()!=g,L=F&&!K||!I[0]||k&&ro;R+='";r.setDate(r.getDate()+1);r=this._daylightSavingAdjust(r)}y+=R+""}g++;if(g>11){g=0;m++}y+="
                '+this._get(a,"weekHeader")+"
                '+this._get(a,"calculateWeek")(r)+""+(F&&!D?" ":L?''+ -r.getDate()+"":''+r.getDate()+"")+"
                "+(l?"
                "+(i[0]>0&&G==i[1]-1?'
                ':""):"");O+=y}w+=O}w+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'': -"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
                ',o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&&l)?" ":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b, -e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
                ";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c=="Y"?b:0),f=a.drawMonth+ -(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");if(b)b.apply(a.input? -a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);c=this._daylightSavingAdjust(new Date(c, -e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a, -"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=function(a){if(!this.length)return this; -if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));return this.each(function(){typeof a== -"string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.16";window["DP_jQuery_"+B]=d})(jQuery); -;/* - * jQuery UI Progressbar 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
                ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); -this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* -this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.16"})})(jQuery); -;/* - * jQuery UI Effects 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/ - */ -jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], -16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, -a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= -a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", -"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, -0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, -211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, -d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})}; -f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this, -[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.16",save:function(c,a){for(var b=0;b
                ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}), -d=document.activeElement;c.wrap(b);if(c[0]===d||f.contains(c[0],d))f(d).focus();b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(e,g){a[g]=c.css(g);if(isNaN(parseInt(a[g],10)))a[g]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){var a,b=document.activeElement; -if(c.parent().is(".ui-effects-wrapper")){a=c.parent().replaceWith(c);if(c[0]===b||f.contains(c[0],b))f(b).focus();return a}return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)}); -return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this, -arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/ -2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b, -d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c, -a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b, -d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h
                ").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ -e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); -;/* - * jQuery UI Effects Fade 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fade - * - * Depends: - * jquery.effects.core.js - */ -(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); -;/* - * jQuery UI Effects Fold 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fold - * - * Depends: - * jquery.effects.core.js - */ -(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], -10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); -;/* - * jQuery UI Effects Highlight 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Highlight - * - * Depends: - * jquery.effects.core.js - */ -(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& -this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); -;/* - * jQuery UI Effects Pulsate 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Pulsate - * - * Depends: - * jquery.effects.core.js - */ -(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c
                ').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); -b.dequeue()})})}})(jQuery); -; \ No newline at end of file diff --git a/lib/base.php b/lib/base.php index c4057cee6e..3bd998de3a 100644 --- a/lib/base.php +++ b/lib/base.php @@ -268,7 +268,7 @@ class OC { // Add the stuff we need always OC_Util::addScript("jquery-1.7.2.min"); - OC_Util::addScript("jquery-ui-1.8.16.custom.min"); + OC_Util::addScript("jquery-ui-1.10.0.custom"); OC_Util::addScript("jquery-showpassword"); OC_Util::addScript("jquery.infieldlabel"); OC_Util::addScript("jquery-tipsy"); @@ -282,7 +282,7 @@ class OC OC_Util::addStyle("styles"); OC_Util::addStyle("multiselect"); - OC_Util::addStyle("jquery-ui-1.8.16.custom"); + OC_Util::addStyle("jquery-ui-1.10.0.custom"); OC_Util::addStyle("jquery-tipsy"); OC_Util::addScript("oc-requesttoken"); } From 0517465f4d2d4ebfebfee66cc4c816495a7ebf7a Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 23 Jan 2013 13:42:52 +0100 Subject: [PATCH 247/315] Allow admins to change the CSP policy in the config file --- config/config.sample.php | 3 +++ lib/template.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/config/config.sample.php b/config/config.sample.php index dafb536fa6..18b7532e8f 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -104,6 +104,9 @@ $CONFIG = array( /* Lifetime of the remember login cookie, default is 15 days */ "remember_login_cookie_lifetime" => 60*60*24*15, +/* Custom CSP policy, changing this will overwrite the standard policy */ +"custom_csp_policy" => "default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; frame-src *", + /* The directory where the user data is stored, default to data in the owncloud * directory. The sqlite database is also stored here, when sqlite is used. */ diff --git a/lib/template.php b/lib/template.php index 632268b002..96ca2c8afb 100644 --- a/lib/template.php +++ b/lib/template.php @@ -191,7 +191,7 @@ class OC_Template{ header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE // Content Security Policy - $policy = 'default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; frame-src *'; + $policy = OC_Config::getValue('custom_csp_policy', 'default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; frame-src *'); header('Content-Security-Policy:'.$policy); // Standard header('X-WebKit-CSP:'.$policy); // Older webkit browsers header('X-Content-Security-Policy:'.$policy); // Mozilla + Internet Explorer From 293e7bdcf0b9769a1aaa240b5d61bc20e3673d78 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 23 Jan 2013 13:44:43 +0100 Subject: [PATCH 248/315] Notice about changing the standard policy --- lib/template.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/template.php b/lib/template.php index 96ca2c8afb..a545d91f3c 100644 --- a/lib/template.php +++ b/lib/template.php @@ -191,6 +191,7 @@ class OC_Template{ header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE // Content Security Policy + // If you change the standard policy, please also change it in config.sample.php $policy = OC_Config::getValue('custom_csp_policy', 'default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; frame-src *'); header('Content-Security-Policy:'.$policy); // Standard header('X-WebKit-CSP:'.$policy); // Older webkit browsers From 3ff32eba2563aa0cce99e6c409cab34a04420dc1 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Thu, 24 Jan 2013 00:07:38 +0100 Subject: [PATCH 249/315] [tx-robot] updated from transifex --- apps/files/l10n/hu_HU.php | 1 + apps/files/l10n/zh_TW.php | 1 + apps/files_encryption/l10n/cs_CZ.php | 11 ++++ apps/files_encryption/l10n/el.php | 2 + apps/files_encryption/l10n/it.php | 9 +++ apps/files_encryption/l10n/ja_JP.php | 11 ++++ apps/files_encryption/l10n/pt_PT.php | 11 ++++ apps/files_encryption/l10n/th_TH.php | 11 ++++ apps/files_sharing/l10n/sr.php | 3 + core/l10n/sr.php | 8 ++- l10n/cs_CZ/files_encryption.po | 30 +++++----- l10n/el/files_encryption.po | 11 ++-- l10n/hu_HU/files.po | 9 +-- l10n/it/files_encryption.po | 26 ++++----- l10n/ja_JP/files_encryption.po | 29 +++++----- l10n/pt_PT/files_encryption.po | 29 +++++----- l10n/sr/core.po | 86 ++++++++++++++-------------- l10n/sr/files_sharing.po | 18 +++--- l10n/sr/lib.po | 12 ++-- l10n/templates/core.pot | 2 +- l10n/templates/files.pot | 2 +- l10n/templates/files_encryption.pot | 2 +- l10n/templates/files_external.pot | 2 +- l10n/templates/files_sharing.pot | 2 +- l10n/templates/files_versions.pot | 2 +- l10n/templates/lib.pot | 2 +- l10n/templates/settings.pot | 2 +- l10n/templates/user_ldap.pot | 2 +- l10n/templates/user_webdavauth.pot | 2 +- l10n/th_TH/files_encryption.po | 30 +++++----- l10n/zh_TW/files.po | 9 +-- l10n/zh_TW/lib.po | 23 ++++---- lib/l10n/sr.php | 1 + lib/l10n/zh_TW.php | 13 +++-- 34 files changed, 244 insertions(+), 170 deletions(-) create mode 100644 apps/files_sharing/l10n/sr.php diff --git a/apps/files/l10n/hu_HU.php b/apps/files/l10n/hu_HU.php index 57cc0a8630..21797809b6 100644 --- a/apps/files/l10n/hu_HU.php +++ b/apps/files/l10n/hu_HU.php @@ -29,6 +29,7 @@ "'.' is an invalid file name." => "'.' fájlnév érvénytelen.", "File name cannot be empty." => "A fájlnév nem lehet semmi.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Érvénytelen elnevezés. Ezek a karakterek nem használhatók: '\\', '/', '<', '>', ':', '\"', '|', '?' és '*'", +"Your download is being prepared. This might take some time if the files are big." => "Készül a letöltendő állomány. Ez eltarthat egy ideig, ha nagyok a fájlok.", "Unable to upload your file as it is a directory or has 0 bytes" => "Nem tölthető fel, mert mappa volt, vagy 0 byte méretű", "Upload Error" => "Feltöltési hiba", "Close" => "Bezárás", diff --git a/apps/files/l10n/zh_TW.php b/apps/files/l10n/zh_TW.php index 61f8c28828..2bf15af1c4 100644 --- a/apps/files/l10n/zh_TW.php +++ b/apps/files/l10n/zh_TW.php @@ -29,6 +29,7 @@ "'.' is an invalid file name." => "'.' 是不合法的檔名。", "File name cannot be empty." => "檔名不能為空。", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "檔名不合法,不允許 '\\', '/', '<', '>', ':', '\"', '|', '?' 和 '*' 。", +"Your download is being prepared. This might take some time if the files are big." => "正在準備您的下載,若您的檔案較大,將會需要更多時間。", "Unable to upload your file as it is a directory or has 0 bytes" => "無法上傳您的檔案因為它可能是一個目錄或檔案大小為0", "Upload Error" => "上傳發生錯誤", "Close" => "關閉", diff --git a/apps/files_encryption/l10n/cs_CZ.php b/apps/files_encryption/l10n/cs_CZ.php index 90b1243f1f..5948a9b82e 100644 --- a/apps/files_encryption/l10n/cs_CZ.php +++ b/apps/files_encryption/l10n/cs_CZ.php @@ -1,4 +1,15 @@ "Prosím přejděte na svého klienta ownCloud a nastavte šifrovací heslo pro dokončení konverze.", +"switched to client side encryption" => "přepnuto na šifrování na straně klienta", +"Change encryption password to login password" => "Změnit šifrovací heslo na přihlašovací", +"Please check your passwords and try again." => "Zkontrolujte, prosím, své heslo a zkuste to znovu.", +"Could not change your file encryption password to your login password" => "Nelze změnit šifrovací heslo na přihlašovací.", +"Choose encryption mode:" => "Vyberte režim šifrování:", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Šifrování na straně klienta (nejbezpečnější ale neumožňuje vám přistupovat k souborům z webového rozhraní)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Šifrování na straně serveru (umožňuje vám přistupovat k souborům pomocí webového rozhraní i aplikací)", +"None (no encryption at all)" => "Žádný (vůbec žádné šifrování)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Důležité: jak si jednou vyberete režim šifrování nelze jej opětovně změnit", +"User specific (let the user decide)" => "Definován uživatelem (umožní uživateli si vybrat)", "Encryption" => "Šifrování", "Exclude the following file types from encryption" => "Při šifrování vynechat následující typy souborů", "None" => "Žádné" diff --git a/apps/files_encryption/l10n/el.php b/apps/files_encryption/l10n/el.php index 70e65a5237..cbf65b5cfa 100644 --- a/apps/files_encryption/l10n/el.php +++ b/apps/files_encryption/l10n/el.php @@ -1,4 +1,6 @@ "Παρακαλώ ελέγξτε το συνθηματικό σας και προσπαθήστε ξανά.", +"Choose encryption mode:" => "Επιλογή κατάστασης κρυπτογράφησης:", "Encryption" => "Κρυπτογράφηση", "Exclude the following file types from encryption" => "Εξαίρεση των παρακάτω τύπων αρχείων από την κρυπτογράφηση", "None" => "Καμία" diff --git a/apps/files_encryption/l10n/it.php b/apps/files_encryption/l10n/it.php index d7e68a66e9..de62f0508f 100644 --- a/apps/files_encryption/l10n/it.php +++ b/apps/files_encryption/l10n/it.php @@ -1,4 +1,13 @@ "Passa al tuo client ownCloud e cambia la password di cifratura per completare la conversione.", +"switched to client side encryption" => "passato alla cifratura lato client", +"Please check your passwords and try again." => "Controlla la password e prova ancora.", +"Choose encryption mode:" => "Scegli la modalità di cifratura.", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Cifratura lato client (più sicura ma rende impossibile accedere ai propri dati dall'interfaccia web)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Cifratura lato server (ti consente di accedere ai tuoi file dall'interfaccia web e dal client desktop)", +"None (no encryption at all)" => "Nessuna (senza alcuna cifratura)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Importante: una volta selezionata la modalità di cifratura non sarà possibile tornare indietro", +"User specific (let the user decide)" => "Specificato dall'utente (lascia decidere all'utente)", "Encryption" => "Cifratura", "Exclude the following file types from encryption" => "Escludi i seguenti tipi di file dalla cifratura", "None" => "Nessuna" diff --git a/apps/files_encryption/l10n/ja_JP.php b/apps/files_encryption/l10n/ja_JP.php index bd630c1d71..4100908e00 100644 --- a/apps/files_encryption/l10n/ja_JP.php +++ b/apps/files_encryption/l10n/ja_JP.php @@ -1,4 +1,15 @@ "変換を完了するために、ownCloud クライアントに切り替えて、暗号化パスワードを変更してください。", +"switched to client side encryption" => "クライアントサイドの暗号化に切り替えました", +"Change encryption password to login password" => "暗号化パスワードをログインパスワードに変更", +"Please check your passwords and try again." => "パスワードを確認してもう一度行なってください。", +"Could not change your file encryption password to your login password" => "ファイル暗号化パスワードをログインパスワードに変更できませんでした。", +"Choose encryption mode:" => "暗号化モードを選択:", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "クライアントサイドの暗号化(最もセキュアですが、WEBインターフェースからデータにアクセスできなくなります)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "サーバサイド暗号化(WEBインターフェースおよびデスクトップクライアントからファイルにアクセスすることができます)", +"None (no encryption at all)" => "暗号化無し(何も暗号化しません)", +"Important: Once you selected an encryption mode there is no way to change it back" => "重要: 一度暗号化を選択してしまうと、もとに戻す方法はありません", +"User specific (let the user decide)" => "ユーザ指定(ユーザが選べるようにする)", "Encryption" => "暗号化", "Exclude the following file types from encryption" => "暗号化から除外するファイルタイプ", "None" => "なし" diff --git a/apps/files_encryption/l10n/pt_PT.php b/apps/files_encryption/l10n/pt_PT.php index 5634184a3b..b6eedcdc50 100644 --- a/apps/files_encryption/l10n/pt_PT.php +++ b/apps/files_encryption/l10n/pt_PT.php @@ -1,4 +1,15 @@ "Por favor, use o seu cliente de sincronização do ownCloud e altere a sua password de encriptação para concluír a conversão.", +"switched to client side encryption" => "Alterado para encriptação do lado do cliente", +"Change encryption password to login password" => "Alterar a password de encriptação para a password de login", +"Please check your passwords and try again." => "Por favor verifique as suas paswords e tente de novo.", +"Could not change your file encryption password to your login password" => "Não foi possível alterar a password de encriptação de ficheiros para a sua password de login", +"Choose encryption mode:" => "Escolha o método de encriptação", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Encriptação do lado do cliente (mais seguro mas torna possível o acesso aos dados através do interface web)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Encriptação do lado do servidor (permite o acesso aos seus ficheiros através do interface web e do cliente de sincronização)", +"None (no encryption at all)" => "Nenhuma (sem encriptação)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Importante: Uma vez escolhido o modo de encriptação, não existe maneira de o alterar!", +"User specific (let the user decide)" => "Escolhido pelo utilizador", "Encryption" => "Encriptação", "Exclude the following file types from encryption" => "Excluir da encriptação os seguintes tipo de ficheiros", "None" => "Nenhum" diff --git a/apps/files_encryption/l10n/th_TH.php b/apps/files_encryption/l10n/th_TH.php index 65fcd80685..f8c19456ab 100644 --- a/apps/files_encryption/l10n/th_TH.php +++ b/apps/files_encryption/l10n/th_TH.php @@ -1,4 +1,15 @@ "กรุณาสลับไปที่โปรแกรมไคลเอนต์ ownCloud ของคุณ แล้วเปลี่ยนรหัสผ่านสำหรับการเข้ารหัสเพื่อแปลงข้อมูลให้เสร็จสมบูรณ์", +"switched to client side encryption" => "สลับไปใช้การเข้ารหัสจากโปรแกรมไคลเอนต์", +"Change encryption password to login password" => "เปลี่ยนรหัสผ่านสำหรับเข้ารหัสไปเป็นรหัสผ่านสำหรับการเข้าสู่ระบบ", +"Please check your passwords and try again." => "กรุณาตรวจสอบรหัสผ่านของคุณแล้วลองใหม่อีกครั้ง", +"Could not change your file encryption password to your login password" => "ไม่สามารถเปลี่ยนรหัสผ่านสำหรับการเข้ารหัสไฟล์ของคุณไปเป็นรหัสผ่านสำหรับการเข้าสู่ระบบของคุณได้", +"Choose encryption mode:" => "เลือกรูปแบบการเข้ารหัส:", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "การเข้ารหัสด้วยโปรแกรมไคลเอนต์ (ปลอดภัยที่สุด แต่จะทำให้คุณไม่สามารถเข้าถึงข้อมูลต่างๆจากหน้าจอเว็บไซต์ได้)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "การเข้ารหัสจากทางฝั่งเซิร์ฟเวอร์ (อนุญาตให้คุณเข้าถึงไฟล์ของคุณจากหน้าจอเว็บไซต์ และโปรแกรมไคลเอนต์จากเครื่องเดสก์ท็อปได้)", +"None (no encryption at all)" => "ไม่ต้อง (ไม่มีการเข้ารหัสเลย)", +"Important: Once you selected an encryption mode there is no way to change it back" => "ข้อความสำคัญ: หลังจากที่คุณได้เลือกรูปแบบการเข้ารหัสแล้ว จะไม่สามารถเปลี่ยนกลับมาใหม่ได้อีก", +"User specific (let the user decide)" => "ให้ผู้ใช้งานเลือกเอง (ปล่อยให้ผู้ใช้งานตัดสินใจเอง)", "Encryption" => "การเข้ารหัส", "Exclude the following file types from encryption" => "ไม่ต้องรวมชนิดของไฟล์ดังต่อไปนี้จากการเข้ารหัส", "None" => "ไม่ต้อง" diff --git a/apps/files_sharing/l10n/sr.php b/apps/files_sharing/l10n/sr.php new file mode 100644 index 0000000000..7a922b8900 --- /dev/null +++ b/apps/files_sharing/l10n/sr.php @@ -0,0 +1,3 @@ + "Пошаљи" +); diff --git a/core/l10n/sr.php b/core/l10n/sr.php index 6b64d1957e..e55ad9250a 100644 --- a/core/l10n/sr.php +++ b/core/l10n/sr.php @@ -1,4 +1,6 @@ "Корисник %s дели са вама датотеку", +"User %s shared a folder with you" => "Корисник %s дели са вама директоријум", "Category type not provided." => "Врста категорије није унет.", "No category to add?" => "Додати још неку категорију?", "This category already exists: " => "Категорија већ постоји:", @@ -39,6 +41,7 @@ "Share with link" => "Подели линк", "Password protect" => "Заштићено лозинком", "Password" => "Лозинка", +"Send" => "Пошаљи", "Set expiration date" => "Постави датум истека", "Expiration date" => "Датум истека", "Share via email:" => "Подели поштом:", @@ -55,6 +58,8 @@ "Password protected" => "Заштићено лозинком", "Error unsetting expiration date" => "Грешка код поништавања датума истека", "Error setting expiration date" => "Грешка код постављања датума истека", +"Sending ..." => "Шаљем...", +"Email sent" => "Порука је послата", "ownCloud password reset" => "Поништавање лозинке за ownCloud", "Use the following link to reset your password: {link}" => "Овом везом ресетујте своју лозинку: {link}", "You will receive a link to reset your password via Email." => "Добићете везу за ресетовање лозинке путем е-поште.", @@ -118,5 +123,6 @@ "remember" => "упамти", "Log in" => "Пријава", "prev" => "претходно", -"next" => "следеће" +"next" => "следеће", +"Updating ownCloud to version %s, this may take a while." => "Надоградња ownCloud-а на верзију %s, сачекајте тренутак." ); diff --git a/l10n/cs_CZ/files_encryption.po b/l10n/cs_CZ/files_encryption.po index 4421784cb4..c26a7ff012 100644 --- a/l10n/cs_CZ/files_encryption.po +++ b/l10n/cs_CZ/files_encryption.po @@ -4,14 +4,14 @@ # # Translators: # Martin , 2012. -# Tomáš Chvátal , 2012. +# Tomáš Chvátal , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 20:21+0000\n" +"Last-Translator: Tomáš Chvátal \n" "Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/owncloud/language/cs_CZ/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,53 +23,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Prosím přejděte na svého klienta ownCloud a nastavte šifrovací heslo pro dokončení konverze." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "přepnuto na šifrování na straně klienta" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Změnit šifrovací heslo na přihlašovací" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Zkontrolujte, prosím, své heslo a zkuste to znovu." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Nelze změnit šifrovací heslo na přihlašovací." #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Vyberte režim šifrování:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Šifrování na straně klienta (nejbezpečnější ale neumožňuje vám přistupovat k souborům z webového rozhraní)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Šifrování na straně serveru (umožňuje vám přistupovat k souborům pomocí webového rozhraní i aplikací)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Žádný (vůbec žádné šifrování)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Důležité: jak si jednou vyberete režim šifrování nelze jej opětovně změnit" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Definován uživatelem (umožní uživateli si vybrat)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/el/files_encryption.po b/l10n/el/files_encryption.po index 2ece2edcaf..db198521dc 100644 --- a/l10n/el/files_encryption.po +++ b/l10n/el/files_encryption.po @@ -4,13 +4,14 @@ # # Translators: # Efstathios Iosifidis , 2012. +# Efstathios Iosifidis , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-22 23:23+0000\n" +"Last-Translator: Efstathios Iosifidis \n" "Language-Team: Greek (http://www.transifex.com/projects/p/owncloud/language/el/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -34,7 +35,7 @@ msgstr "" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Παρακαλώ ελέγξτε το συνθηματικό σας και προσπαθήστε ξανά." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" @@ -42,7 +43,7 @@ msgstr "" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Επιλογή κατάστασης κρυπτογράφησης:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" diff --git a/l10n/hu_HU/files.po b/l10n/hu_HU/files.po index 99731539f8..98235f04ca 100644 --- a/l10n/hu_HU/files.po +++ b/l10n/hu_HU/files.po @@ -6,15 +6,16 @@ # Adam Toth , 2012. # , 2013. # , 2013. +# Laszlo Tornoci , 2013. # , 2011. # Peter Borsa , 2011. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 21:24+0000\n" +"Last-Translator: Laszlo Tornoci \n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -154,7 +155,7 @@ msgstr "Érvénytelen elnevezés. Ezek a karakterek nem használhatók: '\\', '/ msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "Készül a letöltendő állomány. Ez eltarthat egy ideig, ha nagyok a fájlok." #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/it/files_encryption.po b/l10n/it/files_encryption.po index 06ffe73b73..98ad3bf462 100644 --- a/l10n/it/files_encryption.po +++ b/l10n/it/files_encryption.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# Vincenzo Reale , 2012. +# Vincenzo Reale , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 14:21+0000\n" +"Last-Translator: Vincenzo Reale \n" "Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,11 +22,11 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Passa al tuo client ownCloud e cambia la password di cifratura per completare la conversione." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "passato alla cifratura lato client" #: js/settings-personal.js:21 msgid "Change encryption password to login password" @@ -34,7 +34,7 @@ msgstr "" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Controlla la password e prova ancora." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" @@ -42,33 +42,33 @@ msgstr "" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Scegli la modalità di cifratura." #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Cifratura lato client (più sicura ma rende impossibile accedere ai propri dati dall'interfaccia web)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Cifratura lato server (ti consente di accedere ai tuoi file dall'interfaccia web e dal client desktop)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Nessuna (senza alcuna cifratura)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Importante: una volta selezionata la modalità di cifratura non sarà possibile tornare indietro" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Specificato dall'utente (lascia decidere all'utente)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/ja_JP/files_encryption.po b/l10n/ja_JP/files_encryption.po index 99e1f305cb..2c42c90205 100644 --- a/l10n/ja_JP/files_encryption.po +++ b/l10n/ja_JP/files_encryption.po @@ -4,13 +4,14 @@ # # Translators: # Daisuke Deguchi , 2012. +# Daisuke Deguchi , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 03:07+0000\n" +"Last-Translator: Daisuke Deguchi \n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,53 +23,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "変換を完了するために、ownCloud クライアントに切り替えて、暗号化パスワードを変更してください。" #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "クライアントサイドの暗号化に切り替えました" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "暗号化パスワードをログインパスワードに変更" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "パスワードを確認してもう一度行なってください。" #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "ファイル暗号化パスワードをログインパスワードに変更できませんでした。" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "暗号化モードを選択:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "クライアントサイドの暗号化(最もセキュアですが、WEBインターフェースからデータにアクセスできなくなります)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "サーバサイド暗号化(WEBインターフェースおよびデスクトップクライアントからファイルにアクセスすることができます)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "暗号化無し(何も暗号化しません)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "重要: 一度暗号化を選択してしまうと、もとに戻す方法はありません" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "ユーザ指定(ユーザが選べるようにする)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/pt_PT/files_encryption.po b/l10n/pt_PT/files_encryption.po index 08eeb3d7e7..0ae4844da6 100644 --- a/l10n/pt_PT/files_encryption.po +++ b/l10n/pt_PT/files_encryption.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Daniel Pinto , 2013. # Duarte Velez Grilo , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 01:09+0000\n" +"Last-Translator: Mouxy \n" "Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/owncloud/language/pt_PT/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,53 +23,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Por favor, use o seu cliente de sincronização do ownCloud e altere a sua password de encriptação para concluír a conversão." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "Alterado para encriptação do lado do cliente" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Alterar a password de encriptação para a password de login" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Por favor verifique as suas paswords e tente de novo." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Não foi possível alterar a password de encriptação de ficheiros para a sua password de login" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Escolha o método de encriptação" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Encriptação do lado do cliente (mais seguro mas torna possível o acesso aos dados através do interface web)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Encriptação do lado do servidor (permite o acesso aos seus ficheiros através do interface web e do cliente de sincronização)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Nenhuma (sem encriptação)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Importante: Uma vez escolhido o modo de encriptação, não existe maneira de o alterar!" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Escolhido pelo utilizador" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/sr/core.po b/l10n/sr/core.po index b40e7317a4..720d77429f 100644 --- a/l10n/sr/core.po +++ b/l10n/sr/core.po @@ -3,16 +3,16 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# Ivan Petrović , 2012. +# Ivan Petrović , 2012-2013. # , 2012. # Slobodan Terzić , 2011, 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:03+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 08:26+0000\n" +"Last-Translator: Ivan Petrović \n" "Language-Team: Serbian (http://www.transifex.com/projects/p/owncloud/language/sr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,12 +23,12 @@ msgstr "" #: ajax/share.php:84 #, php-format msgid "User %s shared a file with you" -msgstr "" +msgstr "Корисник %s дели са вама датотеку" #: ajax/share.php:86 #, php-format msgid "User %s shared a folder with you" -msgstr "" +msgstr "Корисник %s дели са вама директоријум" #: ajax/share.php:88 #, php-format @@ -86,55 +86,55 @@ msgstr "Грешка приликом уклањања %s из омиљених" msgid "Settings" msgstr "Подешавања" -#: js/js.js:711 +#: js/js.js:706 msgid "seconds ago" msgstr "пре неколико секунди" -#: js/js.js:712 +#: js/js.js:707 msgid "1 minute ago" msgstr "пре 1 минут" -#: js/js.js:713 +#: js/js.js:708 msgid "{minutes} minutes ago" msgstr "пре {minutes} минута" -#: js/js.js:714 +#: js/js.js:709 msgid "1 hour ago" msgstr "Пре једног сата" -#: js/js.js:715 +#: js/js.js:710 msgid "{hours} hours ago" msgstr "Пре {hours} сата (сати)" -#: js/js.js:716 +#: js/js.js:711 msgid "today" msgstr "данас" -#: js/js.js:717 +#: js/js.js:712 msgid "yesterday" msgstr "јуче" -#: js/js.js:718 +#: js/js.js:713 msgid "{days} days ago" msgstr "пре {days} дана" -#: js/js.js:719 +#: js/js.js:714 msgid "last month" msgstr "прошлог месеца" -#: js/js.js:720 +#: js/js.js:715 msgid "{months} months ago" msgstr "Пре {months} месеца (месеци)" -#: js/js.js:721 +#: js/js.js:716 msgid "months ago" msgstr "месеци раније" -#: js/js.js:722 +#: js/js.js:717 msgid "last year" msgstr "прошле године" -#: js/js.js:723 +#: js/js.js:718 msgid "years ago" msgstr "година раније" @@ -219,7 +219,7 @@ msgstr "" #: js/share.js:173 msgid "Send" -msgstr "" +msgstr "Пошаљи" #: js/share.js:177 msgid "Set expiration date" @@ -287,11 +287,11 @@ msgstr "Грешка код постављања датума истека" #: js/share.js:581 msgid "Sending ..." -msgstr "" +msgstr "Шаљем..." #: js/share.js:592 msgid "Email sent" -msgstr "" +msgstr "Порука је послата" #: lostpassword/controller.php:47 msgid "ownCloud password reset" @@ -444,83 +444,83 @@ msgstr "Домаћин базе" msgid "Finish setup" msgstr "Заврши подешавање" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Sunday" msgstr "Недеља" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Monday" msgstr "Понедељак" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Tuesday" msgstr "Уторак" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Wednesday" msgstr "Среда" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Thursday" msgstr "Четвртак" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Friday" msgstr "Петак" -#: templates/layout.guest.php:16 templates/layout.user.php:17 +#: templates/layout.guest.php:15 templates/layout.user.php:17 msgid "Saturday" msgstr "Субота" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "January" msgstr "Јануар" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "February" msgstr "Фебруар" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "March" msgstr "Март" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "April" msgstr "Април" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "May" msgstr "Мај" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "June" msgstr "Јун" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "July" msgstr "Јул" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "August" msgstr "Август" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "September" msgstr "Септембар" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "October" msgstr "Октобар" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "November" msgstr "Новембар" -#: templates/layout.guest.php:17 templates/layout.user.php:18 +#: templates/layout.guest.php:16 templates/layout.user.php:18 msgid "December" msgstr "Децембар" -#: templates/layout.guest.php:42 +#: templates/layout.guest.php:41 msgid "web services under your control" msgstr "веб сервиси под контролом" @@ -565,4 +565,4 @@ msgstr "следеће" #: templates/update.php:3 #, php-format msgid "Updating ownCloud to version %s, this may take a while." -msgstr "" +msgstr "Надоградња ownCloud-а на верзију %s, сачекајте тренутак." diff --git a/l10n/sr/files_sharing.po b/l10n/sr/files_sharing.po index 36c9d0ac46..345fb947c1 100644 --- a/l10n/sr/files_sharing.po +++ b/l10n/sr/files_sharing.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-09-22 01:14+0200\n" -"PO-Revision-Date: 2012-09-21 23:15+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 08:30+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Serbian (http://www.transifex.com/projects/p/owncloud/language/sr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,26 +23,26 @@ msgstr "" #: templates/authenticate.php:6 msgid "Submit" -msgstr "" +msgstr "Пошаљи" -#: templates/public.php:9 +#: templates/public.php:17 #, php-format msgid "%s shared the folder %s with you" msgstr "" -#: templates/public.php:11 +#: templates/public.php:19 #, php-format msgid "%s shared the file %s with you" msgstr "" -#: templates/public.php:14 templates/public.php:30 +#: templates/public.php:22 templates/public.php:38 msgid "Download" msgstr "" -#: templates/public.php:29 +#: templates/public.php:37 msgid "No preview available for" msgstr "" -#: templates/public.php:37 +#: templates/public.php:43 msgid "web services under your control" msgstr "" diff --git a/l10n/sr/lib.po b/l10n/sr/lib.po index d6456f9db1..3b899eb022 100644 --- a/l10n/sr/lib.po +++ b/l10n/sr/lib.po @@ -3,15 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# Ivan Petrović , 2012. +# Ivan Petrović , 2012-2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 08:24+0000\n" +"Last-Translator: Ivan Petrović \n" "Language-Team: Serbian (http://www.transifex.com/projects/p/owncloud/language/sr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -59,9 +59,9 @@ msgstr "Назад на датотеке" msgid "Selected files too large to generate zip file." msgstr "Изабране датотеке су превелике да бисте направили ZIP датотеку." -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "није одређено" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot index 753402f214..972ace2da7 100644 --- a/l10n/templates/core.pot +++ b/l10n/templates/core.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files.pot b/l10n/templates/files.pot index 535c86fc44..4e2eb92673 100644 --- a/l10n/templates/files.pot +++ b/l10n/templates/files.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_encryption.pot b/l10n/templates/files_encryption.pot index b0174b4df0..43ecb33b16 100644 --- a/l10n/templates/files_encryption.pot +++ b/l10n/templates/files_encryption.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_external.pot b/l10n/templates/files_external.pot index 0b141e370d..fadf6a450a 100644 --- a/l10n/templates/files_external.pot +++ b/l10n/templates/files_external.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_sharing.pot b/l10n/templates/files_sharing.pot index 5291a185d3..a6236dbce7 100644 --- a/l10n/templates/files_sharing.pot +++ b/l10n/templates/files_sharing.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_versions.pot b/l10n/templates/files_versions.pot index 0fd775d551..2b8a051d31 100644 --- a/l10n/templates/files_versions.pot +++ b/l10n/templates/files_versions.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/lib.pot b/l10n/templates/lib.pot index d9c2c44387..829f4a30b7 100644 --- a/l10n/templates/lib.pot +++ b/l10n/templates/lib.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot index 89ce02d393..893a5ea219 100644 --- a/l10n/templates/settings.pot +++ b/l10n/templates/settings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/user_ldap.pot b/l10n/templates/user_ldap.pot index 03c8c9e73c..a6b7c1cae5 100644 --- a/l10n/templates/user_ldap.pot +++ b/l10n/templates/user_ldap.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/user_webdavauth.pot b/l10n/templates/user_webdavauth.pot index 63897bf14b..82fcbf1276 100644 --- a/l10n/templates/user_webdavauth.pot +++ b/l10n/templates/user_webdavauth.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/th_TH/files_encryption.po b/l10n/th_TH/files_encryption.po index 747fd64f1a..e76ad6347f 100644 --- a/l10n/th_TH/files_encryption.po +++ b/l10n/th_TH/files_encryption.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# AriesAnywhere Anywhere , 2012. +# AriesAnywhere Anywhere , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 15:03+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,53 +22,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "กรุณาสลับไปที่โปรแกรมไคลเอนต์ ownCloud ของคุณ แล้วเปลี่ยนรหัสผ่านสำหรับการเข้ารหัสเพื่อแปลงข้อมูลให้เสร็จสมบูรณ์" #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "สลับไปใช้การเข้ารหัสจากโปรแกรมไคลเอนต์" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "เปลี่ยนรหัสผ่านสำหรับเข้ารหัสไปเป็นรหัสผ่านสำหรับการเข้าสู่ระบบ" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "กรุณาตรวจสอบรหัสผ่านของคุณแล้วลองใหม่อีกครั้ง" #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "ไม่สามารถเปลี่ยนรหัสผ่านสำหรับการเข้ารหัสไฟล์ของคุณไปเป็นรหัสผ่านสำหรับการเข้าสู่ระบบของคุณได้" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "เลือกรูปแบบการเข้ารหัส:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "การเข้ารหัสด้วยโปรแกรมไคลเอนต์ (ปลอดภัยที่สุด แต่จะทำให้คุณไม่สามารถเข้าถึงข้อมูลต่างๆจากหน้าจอเว็บไซต์ได้)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "การเข้ารหัสจากทางฝั่งเซิร์ฟเวอร์ (อนุญาตให้คุณเข้าถึงไฟล์ของคุณจากหน้าจอเว็บไซต์ และโปรแกรมไคลเอนต์จากเครื่องเดสก์ท็อปได้)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "ไม่ต้อง (ไม่มีการเข้ารหัสเลย)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "ข้อความสำคัญ: หลังจากที่คุณได้เลือกรูปแบบการเข้ารหัสแล้ว จะไม่สามารถเปลี่ยนกลับมาใหม่ได้อีก" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "ให้ผู้ใช้งานเลือกเอง (ปล่อยให้ผู้ใช้งานตัดสินใจเอง)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/zh_TW/files.po b/l10n/zh_TW/files.po index baa21b71fb..e4122552c2 100644 --- a/l10n/zh_TW/files.po +++ b/l10n/zh_TW/files.po @@ -7,14 +7,15 @@ # , 2012. # Eddy Chang , 2012. # , 2013. +# Pellaeon Lin , 2013. # ywang , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 10:05+0000\n" +"Last-Translator: pellaeon \n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/owncloud/language/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -154,7 +155,7 @@ msgstr "檔名不合法,不允許 '\\', '/', '<', '>', ':', '\"', '|', '?' 和 msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "正在準備您的下載,若您的檔案較大,將會需要更多時間。" #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/zh_TW/lib.po b/l10n/zh_TW/lib.po index 3e708c8a28..8a76773c07 100644 --- a/l10n/zh_TW/lib.po +++ b/l10n/zh_TW/lib.po @@ -3,6 +3,7 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Pellaeon Lin , 2013. # , 2012. # , 2012. # ywang , 2012. @@ -10,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"PO-Revision-Date: 2013-01-23 10:07+0000\n" +"Last-Translator: pellaeon \n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/owncloud/language/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -60,9 +61,9 @@ msgstr "回到檔案列表" msgid "Selected files too large to generate zip file." msgstr "選擇的檔案太大以致於無法產生壓縮檔" -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "無法判斷" #: json.php:28 msgid "Application is not enabled" @@ -74,7 +75,7 @@ msgstr "認證錯誤" #: json.php:51 msgid "Token expired. Please reload page." -msgstr "Token 過期. 請重新整理頁面" +msgstr "Token 過期,請重新整理頁面。" #: search/provider/file.php:17 search/provider/file.php:35 msgid "Files" @@ -103,12 +104,12 @@ msgstr "%d 分鐘前" #: template.php:116 msgid "1 hour ago" -msgstr "1小時之前" +msgstr "1 小時之前" #: template.php:117 #, php-format msgid "%d hours ago" -msgstr "%d小時之前" +msgstr "%d 小時之前" #: template.php:118 msgid "today" @@ -130,7 +131,7 @@ msgstr "上個月" #: template.php:122 #, php-format msgid "%d months ago" -msgstr "%d個月之前" +msgstr "%d 個月之前" #: template.php:123 msgid "last year" @@ -143,7 +144,7 @@ msgstr "幾年前" #: updater.php:75 #, php-format msgid "%s is available. Get more information" -msgstr "%s 已經可用. 取得 更多資訊" +msgstr "%s 已經可用。取得 更多資訊" #: updater.php:77 msgid "up to date" @@ -156,4 +157,4 @@ msgstr "檢查更新已停用" #: vcategories.php:188 vcategories.php:249 #, php-format msgid "Could not find category \"%s\"" -msgstr "找不到分類-\"%s\"" +msgstr "找不到分類:\"%s\"" diff --git a/lib/l10n/sr.php b/lib/l10n/sr.php index 2ae7400ba7..34ae89a621 100644 --- a/lib/l10n/sr.php +++ b/lib/l10n/sr.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "Датотеке морате преузимати једну по једну.", "Back to Files" => "Назад на датотеке", "Selected files too large to generate zip file." => "Изабране датотеке су превелике да бисте направили ZIP датотеку.", +"couldn't be determined" => "није одређено", "Application is not enabled" => "Апликација није омогућена", "Authentication error" => "Грешка при провери идентитета", "Token expired. Please reload page." => "Жетон је истекао. Поново учитајте страницу.", diff --git a/lib/l10n/zh_TW.php b/lib/l10n/zh_TW.php index 4dbf89c2e0..62ab8fedd5 100644 --- a/lib/l10n/zh_TW.php +++ b/lib/l10n/zh_TW.php @@ -9,26 +9,27 @@ "Files need to be downloaded one by one." => "檔案需要逐一下載", "Back to Files" => "回到檔案列表", "Selected files too large to generate zip file." => "選擇的檔案太大以致於無法產生壓縮檔", +"couldn't be determined" => "無法判斷", "Application is not enabled" => "應用程式未啟用", "Authentication error" => "認證錯誤", -"Token expired. Please reload page." => "Token 過期. 請重新整理頁面", +"Token expired. Please reload page." => "Token 過期,請重新整理頁面。", "Files" => "檔案", "Text" => "文字", "Images" => "圖片", "seconds ago" => "幾秒前", "1 minute ago" => "1 分鐘前", "%d minutes ago" => "%d 分鐘前", -"1 hour ago" => "1小時之前", -"%d hours ago" => "%d小時之前", +"1 hour ago" => "1 小時之前", +"%d hours ago" => "%d 小時之前", "today" => "今天", "yesterday" => "昨天", "%d days ago" => "%d 天前", "last month" => "上個月", -"%d months ago" => "%d個月之前", +"%d months ago" => "%d 個月之前", "last year" => "去年", "years ago" => "幾年前", -"%s is available. Get more information" => "%s 已經可用. 取得 更多資訊", +"%s is available. Get more information" => "%s 已經可用。取得 更多資訊", "up to date" => "最新的", "updates check is disabled" => "檢查更新已停用", -"Could not find category \"%s\"" => "找不到分類-\"%s\"" +"Could not find category \"%s\"" => "找不到分類:\"%s\"" ); From 8f9d3cd01d9cf253b88ac360c291bf361514742a Mon Sep 17 00:00:00 2001 From: Tom Needham Date: Wed, 23 Jan 2013 23:39:29 +0000 Subject: [PATCH 250/315] Code style update --- lib/api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api.php b/lib/api.php index 7722c74448..64b2f0fe9c 100644 --- a/lib/api.php +++ b/lib/api.php @@ -90,7 +90,7 @@ class OC_API { if(self::isAuthorised(self::$actions[$name])) { if(is_callable(self::$actions[$name]['action'])) { $response = call_user_func(self::$actions[$name]['action'], $parameters); - if(!($response instanceof OC_OCS_Result)){ + if(!($response instanceof OC_OCS_Result)) { $response = new OC_OCS_Result(null, 996, 'Internal Server Error'); } } else { From d16574f0702d7bafa35b27ed8961580ad0a671ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Thu, 24 Jan 2013 13:07:59 +0100 Subject: [PATCH 251/315] new branch which introduces display names first commit with some infrastructure code --- lib/public/user.php | 10 +++++++++- lib/user.php | 41 ++++++++++++++++++++++++++++++++++++++++- lib/user/backend.php | 11 +++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/public/user.php b/lib/public/user.php index 204d8e4c0f..2d22bdd96c 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -51,7 +51,15 @@ class User { public static function getUsers($search = '', $limit = null, $offset = null) { return \OC_USER::getUsers(); } - + + /** + * @brief get the user display name of the user currently logged in. + * @return string display name + */ + public static function getDisplayName() { + return \OC_USER::getDisplayName(); + } + /** * @brief Check if the user is logged in * @returns true/false diff --git a/lib/user.php b/lib/user.php index fd0ed6ecd3..d6d47293cb 100644 --- a/lib/user.php +++ b/lib/user.php @@ -251,6 +251,7 @@ class OC_User { if($uid && $enabled) { session_regenerate_id(true); self::setUserId($uid); + self::setDisplayName($uid); OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>$password )); return true; } @@ -264,6 +265,31 @@ class OC_User { public static function setUserId($uid) { $_SESSION['user_id'] = $uid; } + + /** + * @brief Sets user display name for session + */ + private static function setDisplayName($uid) { + $_SESSION['display_name'] = self::determineDisplayName($uid); + } + + /** + * @brief get display name + * @param $uid The username + * @returns string display name or uid if no display name is defined + * + */ + private static function determineDisplayName( $uid ) { + foreach(self::$_usedBackends as $backend) { + if($backend->implementsActions(OC_USER_BACKEND_GET_DISPLAYNAME)) { + $result=$backend->getDisplayName( $uid ); + if($result) { + return $result; + } + } + } + return $uid; + } /** * @brief Logs the current user out and kills all the session data @@ -319,7 +345,20 @@ class OC_User { return false; } } - + + /** + * @brief get the display name of the user currently logged in. + * @return string uid or false + */ + public static function getDisplayName() { + if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ) { + return $_SESSION['display_name']; + } + else{ + return false; + } + } + /** * @brief Autogenerate a password * @returns string diff --git a/lib/user/backend.php b/lib/user/backend.php index 2a95db9369..47c92f5fe7 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -35,6 +35,7 @@ define('OC_USER_BACKEND_CREATE_USER', 0x000001); define('OC_USER_BACKEND_SET_PASSWORD', 0x000010); define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100); define('OC_USER_BACKEND_GET_HOME', 0x001000); +define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x010000); /** @@ -50,6 +51,7 @@ abstract class OC_User_Backend implements OC_User_Interface { OC_USER_BACKEND_SET_PASSWORD => 'setPassword', OC_USER_BACKEND_CHECK_PASSWORD => 'checkPassword', OC_USER_BACKEND_GET_HOME => 'getHome', + OC_USER_BACKEND_GET_DISPLAYNAME => 'getDisplayName', ); /** @@ -120,4 +122,13 @@ abstract class OC_User_Backend implements OC_User_Interface { public function getHome($uid) { return false; } + + /** + * @brief get display name of the user + * @param $uid user ID of the user + * @return display name + */ + public function getDisplayName($uid) { + return $uid; + } } From 2fee1208eff1911ffcdbba24ea1e8543ed6ec26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Thu, 24 Jan 2013 15:49:23 +0100 Subject: [PATCH 252/315] add display name to title instead if login-ID --- core/templates/layout.user.php | 2 +- lib/user.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index a16d2c9e55..fb63200123 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -1,7 +1,7 @@ - <?php echo isset($_['application']) && !empty($_['application'])?$_['application'].' | ':'' ?>ownCloud <?php echo OC_User::getUser()?' ('.OC_User::getUser().') ':'' ?> + <?php echo isset($_['application']) && !empty($_['application'])?$_['application'].' | ':'' ?>ownCloud <?php echo OC_User::getDisplayName()?' ('.OC_User::getDisplayName().') ':'' ?> diff --git a/lib/user.php b/lib/user.php index d6d47293cb..f9c8f48568 100644 --- a/lib/user.php +++ b/lib/user.php @@ -351,7 +351,7 @@ class OC_User { * @return string uid or false */ public static function getDisplayName() { - if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ) { + if( isset($_SESSION['display_name']) AND $_SESSION['display_name'] ) { return $_SESSION['display_name']; } else{ From ef88ceba8c1108aad6a4f437206f205c60fda870 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 24 Jan 2013 16:47:17 +0100 Subject: [PATCH 253/315] drop SimpleTest compatibility --- apps/files_encryption/test/crypt.php | 20 +++++----- apps/files_encryption/test/proxy.php | 24 ++++++------ apps/files_encryption/test/stream.php | 22 +++++------ apps/files_encryption/test/util.php | 2 +- apps/files_external/tests/ftp.php | 8 ++-- apps/user_ldap/tests/group_ldap.php | 2 +- tests/bootstrap.php | 19 --------- tests/lib/archive.php | 36 ++++++++--------- tests/lib/cache.php | 10 ++--- tests/lib/db.php | 40 +++++++++---------- tests/lib/dbschema.php | 2 +- tests/lib/filestorage.php | 50 ++++++++++++------------ tests/lib/filesystem.php | 42 ++++++++++---------- tests/lib/geo.php | 2 +- tests/lib/group.php | 56 +++++++++++++-------------- tests/lib/group/backend.php | 20 +++++----- tests/lib/helper.php | 2 +- tests/lib/share/share.php | 2 +- tests/lib/streamwrappers.php | 10 ++--- tests/lib/template.php | 10 ++--- tests/lib/user/backend.php | 8 ++-- tests/lib/util.php | 2 +- tests/lib/vcategories.php | 22 +++++------ 23 files changed, 196 insertions(+), 215 deletions(-) diff --git a/apps/files_encryption/test/crypt.php b/apps/files_encryption/test/crypt.php index 5a7820dc9d..19c10ab0ab 100755 --- a/apps/files_encryption/test/crypt.php +++ b/apps/files_encryption/test/crypt.php @@ -609,42 +609,42 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { // $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key); // $decrypted=rtrim($decrypted, "\0"); // $this->assertNotEquals($encrypted,$source); -// $this->assertEqual($decrypted,$source); +// $this->assertEquals($decrypted,$source); // // $chunk=substr($source,0,8192); // $encrypted=OC_Encryption\Crypt::encrypt($chunk,$key); -// $this->assertEqual(strlen($chunk),strlen($encrypted)); +// $this->assertEquals(strlen($chunk),strlen($encrypted)); // $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key); // $decrypted=rtrim($decrypted, "\0"); -// $this->assertEqual($decrypted,$chunk); +// $this->assertEquals($decrypted,$chunk); // // $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key); // $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key); // $this->assertNotEquals($encrypted,$source); -// $this->assertEqual($decrypted,$source); +// $this->assertEquals($decrypted,$source); // // $tmpFileEncrypted=OCP\Files::tmpFile(); // OC_Encryption\Crypt::encryptfile($file,$tmpFileEncrypted,$key); // $encrypted=file_get_contents($tmpFileEncrypted); // $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key); // $this->assertNotEquals($encrypted,$source); -// $this->assertEqual($decrypted,$source); +// $this->assertEquals($decrypted,$source); // // $tmpFileDecrypted=OCP\Files::tmpFile(); // OC_Encryption\Crypt::decryptfile($tmpFileEncrypted,$tmpFileDecrypted,$key); // $decrypted=file_get_contents($tmpFileDecrypted); -// $this->assertEqual($decrypted,$source); +// $this->assertEquals($decrypted,$source); // // $file=OC::$SERVERROOT.'/core/img/weather-clear.png'; // $source=file_get_contents($file); //binary file // $encrypted=OC_Encryption\Crypt::encrypt($source,$key); // $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key); // $decrypted=rtrim($decrypted, "\0"); -// $this->assertEqual($decrypted,$source); +// $this->assertEquals($decrypted,$source); // // $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key); // $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key); -// $this->assertEqual($decrypted,$source); +// $this->assertEquals($decrypted,$source); // // } // @@ -657,11 +657,11 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase { // $decrypted=OC_Encryption\Crypt::decrypt($encrypted,$key); // // $decrypted=rtrim($decrypted, "\0"); -// $this->assertEqual($decrypted,$source); +// $this->assertEquals($decrypted,$source); // // $encrypted=OC_Encryption\Crypt::blockEncrypt($source,$key); // $decrypted=OC_Encryption\Crypt::blockDecrypt($encrypted,$key,strlen($source)); -// $this->assertEqual($decrypted,$source); +// $this->assertEquals($decrypted,$source); // } } diff --git a/apps/files_encryption/test/proxy.php b/apps/files_encryption/test/proxy.php index 51e77100ba..709730f760 100644 --- a/apps/files_encryption/test/proxy.php +++ b/apps/files_encryption/test/proxy.php @@ -109,7 +109,7 @@ // // } -// class Test_CryptProxy extends UnitTestCase { +// class Test_CryptProxy extends PHPUnit_Framework_TestCase { // private $oldConfig; // private $oldKey; // @@ -161,9 +161,9 @@ // OC_FileProxy::$enabled=true; // // $fromFile=OC_Filesystem::file_get_contents('/file'); -// $this->assertNotEqual($original,$stored); -// $this->assertEqual(strlen($original),strlen($fromFile)); -// $this->assertEqual($original,$fromFile); +// $this->assertNotEquals($original,$stored); +// $this->assertEquals(strlen($original),strlen($fromFile)); +// $this->assertEquals($original,$fromFile); // // } // @@ -181,12 +181,12 @@ // $stored=$rootView->file_get_contents($userDir.'/file'); // OC_FileProxy::$enabled=true; // -// $this->assertNotEqual($original,$stored); +// $this->assertNotEquals($original,$stored); // $fromFile=$rootView->file_get_contents($userDir.'/file'); -// $this->assertEqual($original,$fromFile); +// $this->assertEquals($original,$fromFile); // // $fromFile=$view->file_get_contents('files/file'); -// $this->assertEqual($original,$fromFile); +// $this->assertEquals($original,$fromFile); // } // // public function testBinary(){ @@ -200,9 +200,9 @@ // OC_FileProxy::$enabled=true; // // $fromFile=OC_Filesystem::file_get_contents('/file'); -// $this->assertNotEqual($original,$stored); -// $this->assertEqual(strlen($original),strlen($fromFile)); -// $this->assertEqual($original,$fromFile); +// $this->assertNotEquals($original,$stored); +// $this->assertEquals(strlen($original),strlen($fromFile)); +// $this->assertEquals($original,$fromFile); // // $file=__DIR__.'/zeros'; // $original=file_get_contents($file); @@ -214,7 +214,7 @@ // OC_FileProxy::$enabled=true; // // $fromFile=OC_Filesystem::file_get_contents('/file'); -// $this->assertNotEqual($original,$stored); -// $this->assertEqual(strlen($original),strlen($fromFile)); +// $this->assertNotEquals($original,$stored); +// $this->assertEquals(strlen($original),strlen($fromFile)); // } // } diff --git a/apps/files_encryption/test/stream.php b/apps/files_encryption/test/stream.php index 4211cab310..ba82ac80ea 100644 --- a/apps/files_encryption/test/stream.php +++ b/apps/files_encryption/test/stream.php @@ -117,7 +117,7 @@ // // // // fclose( $stream ); // // -// // $this->assertEqual( 'foobar', $data ); +// // $this->assertEquals( 'foobar', $data ); // // // // // // $file = OC::$SERVERROOT.'/3rdparty/MDB2.php'; @@ -139,15 +139,15 @@ // // // // $original = file_get_contents( $file ); // // -// // $this->assertEqual( strlen( $original ), strlen( $data ) ); +// // $this->assertEquals( strlen( $original ), strlen( $data ) ); // // -// // $this->assertEqual( $original, $data ); +// // $this->assertEquals( $original, $data ); // // // // } // // } // -// // class Test_CryptStream extends UnitTestCase { +// // class Test_CryptStream extends PHPUnit_Framework_TestCase { // // private $tmpFiles=array(); // // // // function testStream(){ @@ -158,7 +158,7 @@ // // $stream=$this->getStream('test1','r',strlen('foobar')); // // $data=fread($stream,6); // // fclose($stream); -// // $this->assertEqual('foobar',$data); +// // $this->assertEquals('foobar',$data); // // // // $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; // // $source=fopen($file,'r'); @@ -170,8 +170,8 @@ // // $stream=$this->getStream('test2','r',filesize($file)); // // $data=stream_get_contents($stream); // // $original=file_get_contents($file); -// // $this->assertEqual(strlen($original),strlen($data)); -// // $this->assertEqual($original,$data); +// // $this->assertEquals(strlen($original),strlen($data)); +// // $this->assertEquals($original,$data); // // } // // // // /** @@ -207,8 +207,8 @@ // // $stream=$this->getStream('test','r',strlen($source)); // // $data=stream_get_contents($stream); // // fclose($stream); -// // $this->assertEqual(strlen($data),strlen($source)); -// // $this->assertEqual($source,$data); +// // $this->assertEquals(strlen($data),strlen($source)); +// // $this->assertEquals($source,$data); // // // // $file=__DIR__.'/zeros'; // // $source=file_get_contents($file); @@ -220,7 +220,7 @@ // // $stream=$this->getStream('test2','r',strlen($source)); // // $data=stream_get_contents($stream); // // fclose($stream); -// // $this->assertEqual(strlen($data),strlen($source)); -// // $this->assertEqual($source,$data); +// // $this->assertEquals(strlen($data),strlen($source)); +// // $this->assertEquals($source,$data); // // } // // } diff --git a/apps/files_encryption/test/util.php b/apps/files_encryption/test/util.php index 016787fbfb..a299ec67f5 100755 --- a/apps/files_encryption/test/util.php +++ b/apps/files_encryption/test/util.php @@ -203,7 +203,7 @@ class Test_Enc_Util extends \PHPUnit_Framework_TestCase { // // $decrypted = $c->legacyDecrypt( $encrypted, $c->legacyKey ); // -// $this->assertEqual( $decrypted, $this->data ); +// $this->assertEquals( $decrypted, $this->data ); // // } diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php index d0404b5f34..91e4589ed1 100644 --- a/apps/files_external/tests/ftp.php +++ b/apps/files_external/tests/ftp.php @@ -32,18 +32,18 @@ class Test_Filestorage_FTP extends Test_FileStorage { 'root' => '/', 'secure' => false ); $instance = new OC_Filestorage_FTP($config); - $this->assertEqual('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); + $this->assertEquals('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = true; $instance = new OC_Filestorage_FTP($config); - $this->assertEqual('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); + $this->assertEquals('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = 'false'; $instance = new OC_Filestorage_FTP($config); - $this->assertEqual('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); + $this->assertEquals('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = 'true'; $instance = new OC_Filestorage_FTP($config); - $this->assertEqual('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); + $this->assertEquals('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); } } diff --git a/apps/user_ldap/tests/group_ldap.php b/apps/user_ldap/tests/group_ldap.php index f99902d32f..ae635597b7 100644 --- a/apps/user_ldap/tests/group_ldap.php +++ b/apps/user_ldap/tests/group_ldap.php @@ -20,7 +20,7 @@ * */ -class Test_Group_Ldap extends UnitTestCase { +class Test_Group_Ldap extends PHPUnit_Framework_TestCase { function setUp() { OC_Group::clearBackends(); } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 115a15883a..b97161ee6e 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -8,24 +8,5 @@ if(!class_exists('PHPUnit_Framework_TestCase')) { require_once('PHPUnit/Autoload.php'); } -//SimpleTest compatibility -abstract class UnitTestCase extends PHPUnit_Framework_TestCase{ - function assertEqual($expected, $actual, $string='') { - $this->assertEquals($expected, $actual, $string); - } - - function assertNotEqual($expected, $actual, $string='') { - $this->assertNotEquals($expected, $actual, $string); - } - - static function assertTrue($actual, $string='') { - parent::assertTrue((bool)$actual, $string); - } - - static function assertFalse($actual, $string='') { - parent::assertFalse((bool)$actual, $string); - } -} - OC_Hook::clear(); OC_Log::$enabled = false; diff --git a/tests/lib/archive.php b/tests/lib/archive.php index cd2ca6630a..be5cc897a6 100644 --- a/tests/lib/archive.php +++ b/tests/lib/archive.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -abstract class Test_Archive extends UnitTestCase { +abstract class Test_Archive extends PHPUnit_Framework_TestCase { /** * @var OC_Archive */ @@ -27,7 +27,7 @@ abstract class Test_Archive extends UnitTestCase { $this->instance=$this->getExisting(); $allFiles=$this->instance->getFiles(); $expected=array('lorem.txt','logo-wide.png','dir/', 'dir/lorem.txt'); - $this->assertEqual(4, count($allFiles), 'only found '.count($allFiles).' out of 4 expected files'); + $this->assertEquals(4, count($allFiles), 'only found '.count($allFiles).' out of 4 expected files'); foreach($expected as $file) { $this->assertContains($file, $allFiles, 'cant find '. $file . ' in archive'); $this->assertTrue($this->instance->fileExists($file), 'file '.$file.' does not exist in archive'); @@ -36,14 +36,14 @@ abstract class Test_Archive extends UnitTestCase { $rootContent=$this->instance->getFolder(''); $expected=array('lorem.txt','logo-wide.png', 'dir/'); - $this->assertEqual(3, count($rootContent)); + $this->assertEquals(3, count($rootContent)); foreach($expected as $file) { $this->assertContains($file, $rootContent, 'cant find '. $file . ' in archive'); } $dirContent=$this->instance->getFolder('dir/'); $expected=array('lorem.txt'); - $this->assertEqual(1, count($dirContent)); + $this->assertEquals(1, count($dirContent)); foreach($expected as $file) { $this->assertContains($file, $dirContent, 'cant find '. $file . ' in archive'); } @@ -53,36 +53,36 @@ abstract class Test_Archive extends UnitTestCase { $this->instance=$this->getExisting(); $dir=OC::$SERVERROOT.'/tests/data'; $textFile=$dir.'/lorem.txt'; - $this->assertEqual(file_get_contents($textFile), $this->instance->getFile('lorem.txt')); + $this->assertEquals(file_get_contents($textFile), $this->instance->getFile('lorem.txt')); $tmpFile=OCP\Files::tmpFile('.txt'); $this->instance->extractFile('lorem.txt', $tmpFile); - $this->assertEqual(file_get_contents($textFile), file_get_contents($tmpFile)); + $this->assertEquals(file_get_contents($textFile), file_get_contents($tmpFile)); } public function testWrite() { $dir=OC::$SERVERROOT.'/tests/data'; $textFile=$dir.'/lorem.txt'; $this->instance=$this->getNew(); - $this->assertEqual(0, count($this->instance->getFiles())); + $this->assertEquals(0, count($this->instance->getFiles())); $this->instance->addFile('lorem.txt', $textFile); - $this->assertEqual(1, count($this->instance->getFiles())); + $this->assertEquals(1, count($this->instance->getFiles())); $this->assertTrue($this->instance->fileExists('lorem.txt')); $this->assertFalse($this->instance->fileExists('lorem.txt/')); - $this->assertEqual(file_get_contents($textFile), $this->instance->getFile('lorem.txt')); + $this->assertEquals(file_get_contents($textFile), $this->instance->getFile('lorem.txt')); $this->instance->addFile('lorem.txt', 'foobar'); - $this->assertEqual('foobar', $this->instance->getFile('lorem.txt')); + $this->assertEquals('foobar', $this->instance->getFile('lorem.txt')); } public function testReadStream() { $dir=OC::$SERVERROOT.'/tests/data'; $this->instance=$this->getExisting(); $fh=$this->instance->getStream('lorem.txt', 'r'); - $this->assertTrue($fh); + $this->assertTrue((bool)$fh); $content=fread($fh, $this->instance->filesize('lorem.txt')); fclose($fh); - $this->assertEqual(file_get_contents($dir.'/lorem.txt'), $content); + $this->assertEquals(file_get_contents($dir.'/lorem.txt'), $content); } public function testWriteStream() { $dir=OC::$SERVERROOT.'/tests/data'; @@ -93,7 +93,7 @@ abstract class Test_Archive extends UnitTestCase { fclose($source); fclose($fh); $this->assertTrue($this->instance->fileExists('lorem.txt')); - $this->assertEqual(file_get_contents($dir.'/lorem.txt'), $this->instance->getFile('lorem.txt')); + $this->assertEquals(file_get_contents($dir.'/lorem.txt'), $this->instance->getFile('lorem.txt')); } public function testFolder() { $this->instance=$this->getNew(); @@ -111,10 +111,10 @@ abstract class Test_Archive extends UnitTestCase { $this->instance=$this->getExisting(); $tmpDir=OCP\Files::tmpFolder(); $this->instance->extract($tmpDir); - $this->assertEqual(true, file_exists($tmpDir.'lorem.txt')); - $this->assertEqual(true, file_exists($tmpDir.'dir/lorem.txt')); - $this->assertEqual(true, file_exists($tmpDir.'logo-wide.png')); - $this->assertEqual(file_get_contents($dir.'/lorem.txt'), file_get_contents($tmpDir.'lorem.txt')); + $this->assertEquals(true, file_exists($tmpDir.'lorem.txt')); + $this->assertEquals(true, file_exists($tmpDir.'dir/lorem.txt')); + $this->assertEquals(true, file_exists($tmpDir.'logo-wide.png')); + $this->assertEquals(file_get_contents($dir.'/lorem.txt'), file_get_contents($tmpDir.'lorem.txt')); OCP\Files::rmdirr($tmpDir); } public function testMoveRemove() { @@ -126,7 +126,7 @@ abstract class Test_Archive extends UnitTestCase { $this->instance->rename('lorem.txt', 'target.txt'); $this->assertTrue($this->instance->fileExists('target.txt')); $this->assertFalse($this->instance->fileExists('lorem.txt')); - $this->assertEqual(file_get_contents($textFile), $this->instance->getFile('target.txt')); + $this->assertEquals(file_get_contents($textFile), $this->instance->getFile('target.txt')); $this->instance->remove('target.txt'); $this->assertFalse($this->instance->fileExists('target.txt')); } diff --git a/tests/lib/cache.php b/tests/lib/cache.php index 1a1287ff13..3dcf39f7d6 100644 --- a/tests/lib/cache.php +++ b/tests/lib/cache.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -abstract class Test_Cache extends UnitTestCase { +abstract class Test_Cache extends PHPUnit_Framework_TestCase { /** * @var OC_Cache cache; */ @@ -26,19 +26,19 @@ abstract class Test_Cache extends UnitTestCase { $this->instance->set('value1', $value); $this->assertTrue($this->instance->hasKey('value1')); $received=$this->instance->get('value1'); - $this->assertEqual($value, $received, 'Value recieved from cache not equal to the original'); + $this->assertEquals($value, $received, 'Value recieved from cache not equal to the original'); $value='ipsum lorum'; $this->instance->set('value1', $value); $received=$this->instance->get('value1'); - $this->assertEqual($value, $received, 'Value not overwritten by second set'); + $this->assertEquals($value, $received, 'Value not overwritten by second set'); $value2='foobar'; $this->instance->set('value2', $value2); $received2=$this->instance->get('value2'); $this->assertTrue($this->instance->hasKey('value1')); $this->assertTrue($this->instance->hasKey('value2')); - $this->assertEqual($value, $received, 'Value changed while setting other variable'); - $this->assertEqual($value2, $received2, 'Second value not equal to original'); + $this->assertEquals($value, $received, 'Value changed while setting other variable'); + $this->assertEquals($value2, $received2, 'Second value not equal to original'); $this->assertFalse($this->instance->hasKey('not_set')); $this->assertNull($this->instance->get('not_set'), 'Unset value not equal to null'); diff --git a/tests/lib/db.php b/tests/lib/db.php index c2eb38dae8..440f3fb6bf 100644 --- a/tests/lib/db.php +++ b/tests/lib/db.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -class Test_DB extends UnitTestCase { +class Test_DB extends PHPUnit_Framework_TestCase { protected $backupGlobals = FALSE; protected static $schema_file = 'static://test_db_scheme'; @@ -35,18 +35,18 @@ class Test_DB extends UnitTestCase { public function testQuotes() { $query = OC_DB::prepare('SELECT `fullname` FROM *PREFIX*'.$this->table2.' WHERE `uri` = ?'); $result = $query->execute(array('uri_1')); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $row = $result->fetchRow(); $this->assertFalse($row); $query = OC_DB::prepare('INSERT INTO *PREFIX*'.$this->table2.' (`fullname`,`uri`) VALUES (?,?)'); $result = $query->execute(array('fullname test', 'uri_1')); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $query = OC_DB::prepare('SELECT `fullname`,`uri` FROM *PREFIX*'.$this->table2.' WHERE `uri` = ?'); $result = $query->execute(array('uri_1')); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $row = $result->fetchRow(); $this->assertArrayHasKey('fullname', $row); - $this->assertEqual($row['fullname'], 'fullname test'); + $this->assertEquals($row['fullname'], 'fullname test'); $row = $result->fetchRow(); $this->assertFalse($row); } @@ -54,19 +54,19 @@ class Test_DB extends UnitTestCase { public function testNOW() { $query = OC_DB::prepare('INSERT INTO *PREFIX*'.$this->table2.' (`fullname`,`uri`) VALUES (NOW(),?)'); $result = $query->execute(array('uri_2')); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $query = OC_DB::prepare('SELECT `fullname`,`uri` FROM *PREFIX*'.$this->table2.' WHERE `uri` = ?'); $result = $query->execute(array('uri_2')); - $this->assertTrue($result); + $this->assertTrue((bool)$result); } public function testUNIX_TIMESTAMP() { $query = OC_DB::prepare('INSERT INTO *PREFIX*'.$this->table2.' (`fullname`,`uri`) VALUES (UNIX_TIMESTAMP(),?)'); $result = $query->execute(array('uri_3')); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $query = OC_DB::prepare('SELECT `fullname`,`uri` FROM *PREFIX*'.$this->table2.' WHERE `uri` = ?'); $result = $query->execute(array('uri_3')); - $this->assertTrue($result); + $this->assertTrue((bool)$result); } public function testinsertIfNotExist() { @@ -85,13 +85,13 @@ class Test_DB extends UnitTestCase { 'type' => $entry['type'], 'category' => $entry['category'], )); - $this->assertTrue($result); + $this->assertTrue((bool)$result); } $query = OC_DB::prepare('SELECT * FROM *PREFIX*'.$this->table3); $result = $query->execute(); - $this->assertTrue($result); - $this->assertEqual('4', $result->numRows()); + $this->assertTrue((bool)$result); + $this->assertEquals('4', $result->numRows()); } public function testinsertIfNotExistDontOverwrite() { @@ -102,14 +102,14 @@ class Test_DB extends UnitTestCase { // Normal test to have same known data inserted. $query = OC_DB::prepare('INSERT INTO *PREFIX*'.$this->table2.' (`fullname`, `uri`, `carddata`) VALUES (?, ?, ?)'); $result = $query->execute(array($fullname, $uri, $carddata)); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $query = OC_DB::prepare('SELECT `fullname`, `uri`, `carddata` FROM *PREFIX*'.$this->table2.' WHERE `uri` = ?'); $result = $query->execute(array($uri)); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $row = $result->fetchRow(); $this->assertArrayHasKey('carddata', $row); - $this->assertEqual($carddata, $row['carddata']); - $this->assertEqual('1', $result->numRows()); + $this->assertEquals($carddata, $row['carddata']); + $this->assertEquals('1', $result->numRows()); // Try to insert a new row $result = OC_DB::insertIfNotExist('*PREFIX*'.$this->table2, @@ -117,17 +117,17 @@ class Test_DB extends UnitTestCase { 'fullname' => $fullname, 'uri' => $uri, )); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $query = OC_DB::prepare('SELECT `fullname`, `uri`, `carddata` FROM *PREFIX*'.$this->table2.' WHERE `uri` = ?'); $result = $query->execute(array($uri)); - $this->assertTrue($result); + $this->assertTrue((bool)$result); $row = $result->fetchRow(); $this->assertArrayHasKey('carddata', $row); // Test that previously inserted data isn't overwritten - $this->assertEqual($carddata, $row['carddata']); + $this->assertEquals($carddata, $row['carddata']); // And that a new row hasn't been inserted. - $this->assertEqual('1', $result->numRows()); + $this->assertEquals('1', $result->numRows()); } } diff --git a/tests/lib/dbschema.php b/tests/lib/dbschema.php index cd408160af..fb60ce7dbb 100644 --- a/tests/lib/dbschema.php +++ b/tests/lib/dbschema.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -class Test_DBSchema extends UnitTestCase { +class Test_DBSchema extends PHPUnit_Framework_TestCase { protected static $schema_file = 'static://test_db_scheme'; protected static $schema_file2 = 'static://test_db_scheme2'; protected $test_prefix; diff --git a/tests/lib/filestorage.php b/tests/lib/filestorage.php index e82a6f54e3..c408efb754 100644 --- a/tests/lib/filestorage.php +++ b/tests/lib/filestorage.php @@ -20,7 +20,7 @@ * */ -abstract class Test_FileStorage extends UnitTestCase { +abstract class Test_FileStorage extends PHPUnit_Framework_TestCase { /** * @var OC_Filestorage instance */ @@ -34,7 +34,7 @@ abstract class Test_FileStorage extends UnitTestCase { $this->assertTrue($this->instance->isReadable('/'), 'Root folder is not readable'); $this->assertTrue($this->instance->is_dir('/'), 'Root folder is not a directory'); $this->assertFalse($this->instance->is_file('/'), 'Root folder is a file'); - $this->assertEqual('dir', $this->instance->filetype('/')); + $this->assertEquals('dir', $this->instance->filetype('/')); //without this, any further testing would be useless, not an acutal requirement for filestorage though $this->assertTrue($this->instance->isUpdatable('/'), 'Root folder is not writable'); @@ -48,8 +48,8 @@ abstract class Test_FileStorage extends UnitTestCase { $this->assertTrue($this->instance->file_exists('/folder')); $this->assertTrue($this->instance->is_dir('/folder')); $this->assertFalse($this->instance->is_file('/folder')); - $this->assertEqual('dir', $this->instance->filetype('/folder')); - $this->assertEqual(0, $this->instance->filesize('/folder')); + $this->assertEquals('dir', $this->instance->filetype('/folder')); + $this->assertEquals(0, $this->instance->filesize('/folder')); $this->assertTrue($this->instance->isReadable('/folder')); $this->assertTrue($this->instance->isUpdatable('/folder')); @@ -60,7 +60,7 @@ abstract class Test_FileStorage extends UnitTestCase { $content[] = $file; } } - $this->assertEqual(array('folder'), $content); + $this->assertEquals(array('folder'), $content); $this->assertFalse($this->instance->mkdir('/folder')); //cant create existing folders $this->assertTrue($this->instance->rmdir('/folder')); @@ -76,7 +76,7 @@ abstract class Test_FileStorage extends UnitTestCase { $content[] = $file; } } - $this->assertEqual(array(), $content); + $this->assertEquals(array(), $content); } /** @@ -89,31 +89,31 @@ abstract class Test_FileStorage extends UnitTestCase { //fill a file with string data $this->instance->file_put_contents('/lorem.txt', $sourceText); $this->assertFalse($this->instance->is_dir('/lorem.txt')); - $this->assertEqual($sourceText, $this->instance->file_get_contents('/lorem.txt'), 'data returned from file_get_contents is not equal to the source data'); + $this->assertEquals($sourceText, $this->instance->file_get_contents('/lorem.txt'), 'data returned from file_get_contents is not equal to the source data'); //empty the file $this->instance->file_put_contents('/lorem.txt', ''); - $this->assertEqual('', $this->instance->file_get_contents('/lorem.txt'), 'file not emptied'); + $this->assertEquals('', $this->instance->file_get_contents('/lorem.txt'), 'file not emptied'); } /** * test various known mimetypes */ public function testMimeType() { - $this->assertEqual('httpd/unix-directory', $this->instance->getMimeType('/')); - $this->assertEqual(false, $this->instance->getMimeType('/non/existing/file')); + $this->assertEquals('httpd/unix-directory', $this->instance->getMimeType('/')); + $this->assertEquals(false, $this->instance->getMimeType('/non/existing/file')); $textFile = OC::$SERVERROOT . '/tests/data/lorem.txt'; $this->instance->file_put_contents('/lorem.txt', file_get_contents($textFile, 'r')); - $this->assertEqual('text/plain', $this->instance->getMimeType('/lorem.txt')); + $this->assertEquals('text/plain', $this->instance->getMimeType('/lorem.txt')); $pngFile = OC::$SERVERROOT . '/tests/data/logo-wide.png'; $this->instance->file_put_contents('/logo-wide.png', file_get_contents($pngFile, 'r')); - $this->assertEqual('image/png', $this->instance->getMimeType('/logo-wide.png')); + $this->assertEquals('image/png', $this->instance->getMimeType('/logo-wide.png')); $svgFile = OC::$SERVERROOT . '/tests/data/logo-wide.svg'; $this->instance->file_put_contents('/logo-wide.svg', file_get_contents($svgFile, 'r')); - $this->assertEqual('image/svg+xml', $this->instance->getMimeType('/logo-wide.svg')); + $this->assertEquals('image/svg+xml', $this->instance->getMimeType('/logo-wide.svg')); } public function testCopyAndMove() { @@ -121,12 +121,12 @@ abstract class Test_FileStorage extends UnitTestCase { $this->instance->file_put_contents('/source.txt', file_get_contents($textFile)); $this->instance->copy('/source.txt', '/target.txt'); $this->assertTrue($this->instance->file_exists('/target.txt')); - $this->assertEqual($this->instance->file_get_contents('/source.txt'), $this->instance->file_get_contents('/target.txt')); + $this->assertEquals($this->instance->file_get_contents('/source.txt'), $this->instance->file_get_contents('/target.txt')); $this->instance->rename('/source.txt', '/target2.txt'); $this->assertTrue($this->instance->file_exists('/target2.txt')); $this->assertFalse($this->instance->file_exists('/source.txt')); - $this->assertEqual(file_get_contents($textFile), $this->instance->file_get_contents('/target.txt')); + $this->assertEquals(file_get_contents($textFile), $this->instance->file_get_contents('/target.txt')); } public function testLocal() { @@ -134,7 +134,7 @@ abstract class Test_FileStorage extends UnitTestCase { $this->instance->file_put_contents('/lorem.txt', file_get_contents($textFile)); $localFile = $this->instance->getLocalFile('/lorem.txt'); $this->assertTrue(file_exists($localFile)); - $this->assertEqual(file_get_contents($localFile), file_get_contents($textFile)); + $this->assertEquals(file_get_contents($localFile), file_get_contents($textFile)); $this->instance->mkdir('/folder'); $this->instance->file_put_contents('/folder/lorem.txt', file_get_contents($textFile)); @@ -145,9 +145,9 @@ abstract class Test_FileStorage extends UnitTestCase { $this->assertTrue(is_dir($localFolder)); $this->assertTrue(file_exists($localFolder . '/lorem.txt')); - $this->assertEqual(file_get_contents($localFolder . '/lorem.txt'), file_get_contents($textFile)); - $this->assertEqual(file_get_contents($localFolder . '/bar.txt'), 'asd'); - $this->assertEqual(file_get_contents($localFolder . '/recursive/file.txt'), 'foo'); + $this->assertEquals(file_get_contents($localFolder . '/lorem.txt'), file_get_contents($textFile)); + $this->assertEquals(file_get_contents($localFolder . '/bar.txt'), 'asd'); + $this->assertEquals(file_get_contents($localFolder . '/recursive/file.txt'), 'foo'); } public function testStat() { @@ -162,12 +162,12 @@ abstract class Test_FileStorage extends UnitTestCase { $this->assertTrue(($ctimeStart - 1) <= $mTime); $this->assertTrue($mTime <= ($ctimeEnd + 1)); - $this->assertEqual(filesize($textFile), $this->instance->filesize('/lorem.txt')); + $this->assertEquals(filesize($textFile), $this->instance->filesize('/lorem.txt')); $stat = $this->instance->stat('/lorem.txt'); //only size and mtime are requered in the result - $this->assertEqual($stat['size'], $this->instance->filesize('/lorem.txt')); - $this->assertEqual($stat['mtime'], $mTime); + $this->assertEquals($stat['size'], $this->instance->filesize('/lorem.txt')); + $this->assertEquals($stat['mtime'], $mTime); $mtimeStart = time(); $supportsTouch = $this->instance->touch('/lorem.txt'); @@ -181,7 +181,7 @@ abstract class Test_FileStorage extends UnitTestCase { if ($this->instance->touch('/lorem.txt', 100) !== false) { $mTime = $this->instance->filemtime('/lorem.txt'); - $this->assertEqual($mTime, 100); + $this->assertEquals($mTime, 100); } } @@ -207,7 +207,7 @@ abstract class Test_FileStorage extends UnitTestCase { $svgFile = OC::$SERVERROOT . '/tests/data/logo-wide.svg'; $this->instance->file_put_contents('/logo-wide.svg', file_get_contents($svgFile, 'r')); $result = $this->instance->search('logo'); - $this->assertEqual(2, count($result)); + $this->assertEquals(2, count($result)); $this->assertContains('/logo-wide.svg', $result); $this->assertContains('/logo-wide.png', $result); } @@ -229,6 +229,6 @@ abstract class Test_FileStorage extends UnitTestCase { $fh = $this->instance->fopen('foo', 'r'); $content = stream_get_contents($fh); - $this->assertEqual(file_get_contents($textFile), $content); + $this->assertEquals(file_get_contents($textFile), $content); } } diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index 5cced4946d..ee31ef4364 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -20,7 +20,7 @@ * */ -class Test_Filesystem extends UnitTestCase { +class Test_Filesystem extends PHPUnit_Framework_TestCase { /** * @var array tmpDirs */ @@ -47,28 +47,28 @@ class Test_Filesystem extends UnitTestCase { public function testMount() { OC_Filesystem::mount('OC_Filestorage_Local', self::getStorageData(), '/'); - $this->assertEqual('/', OC_Filesystem::getMountPoint('/')); - $this->assertEqual('/', OC_Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('', OC_Filesystem::getInternalPath('/')); - $this->assertEqual('some/folder', OC_Filesystem::getInternalPath('/some/folder')); + $this->assertEquals('/', OC_Filesystem::getMountPoint('/')); + $this->assertEquals('/', OC_Filesystem::getMountPoint('/some/folder')); + $this->assertEquals('', OC_Filesystem::getInternalPath('/')); + $this->assertEquals('some/folder', OC_Filesystem::getInternalPath('/some/folder')); OC_Filesystem::mount('OC_Filestorage_Local', self::getStorageData(), '/some'); - $this->assertEqual('/', OC_Filesystem::getMountPoint('/')); - $this->assertEqual('/some/', OC_Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('/some/', OC_Filesystem::getMountPoint('/some/')); - $this->assertEqual('/', OC_Filesystem::getMountPoint('/some')); - $this->assertEqual('folder', OC_Filesystem::getInternalPath('/some/folder')); + $this->assertEquals('/', OC_Filesystem::getMountPoint('/')); + $this->assertEquals('/some/', OC_Filesystem::getMountPoint('/some/folder')); + $this->assertEquals('/some/', OC_Filesystem::getMountPoint('/some/')); + $this->assertEquals('/', OC_Filesystem::getMountPoint('/some')); + $this->assertEquals('folder', OC_Filesystem::getInternalPath('/some/folder')); } public function testNormalize() { - $this->assertEqual('/path', OC_Filesystem::normalizePath('/path/')); - $this->assertEqual('/path/', OC_Filesystem::normalizePath('/path/', false)); - $this->assertEqual('/path', OC_Filesystem::normalizePath('path')); - $this->assertEqual('/path', OC_Filesystem::normalizePath('\path')); - $this->assertEqual('/foo/bar', OC_Filesystem::normalizePath('/foo//bar/')); - $this->assertEqual('/foo/bar', OC_Filesystem::normalizePath('/foo////bar')); + $this->assertEquals('/path', OC_Filesystem::normalizePath('/path/')); + $this->assertEquals('/path/', OC_Filesystem::normalizePath('/path/', false)); + $this->assertEquals('/path', OC_Filesystem::normalizePath('path')); + $this->assertEquals('/path', OC_Filesystem::normalizePath('\path')); + $this->assertEquals('/foo/bar', OC_Filesystem::normalizePath('/foo//bar/')); + $this->assertEquals('/foo/bar', OC_Filesystem::normalizePath('/foo////bar')); if (class_exists('Normalizer')) { - $this->assertEqual("/foo/bar\xC3\xBC", OC_Filesystem::normalizePath("/foo/baru\xCC\x88")); + $this->assertEquals("/foo/bar\xC3\xBC", OC_Filesystem::normalizePath("/foo/baru\xCC\x88")); } } @@ -100,10 +100,10 @@ class Test_Filesystem extends UnitTestCase { $rootView->mkdir('/' . $user); $rootView->mkdir('/' . $user . '/files'); - $this->assertFalse($rootView->file_put_contents('/.htaccess', 'foo')); - $this->assertFalse(OC_Filesystem::file_put_contents('/.htaccess', 'foo')); + $this->assertFalse((bool)$rootView->file_put_contents('/.htaccess', 'foo')); + $this->assertFalse((bool)OC_Filesystem::file_put_contents('/.htaccess', 'foo')); $fh = fopen(__FILE__, 'r'); - $this->assertFalse(OC_Filesystem::file_put_contents('/.htaccess', $fh)); + $this->assertFalse((bool)OC_Filesystem::file_put_contents('/.htaccess', $fh)); } public function testHooks() { @@ -134,6 +134,6 @@ class Test_Filesystem extends UnitTestCase { public function dummyHook($arguments) { $path = $arguments['path']; - $this->assertEqual($path, OC_Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized + $this->assertEquals($path, OC_Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized } } diff --git a/tests/lib/geo.php b/tests/lib/geo.php index d4951ee79e..82e6160868 100644 --- a/tests/lib/geo.php +++ b/tests/lib/geo.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -class Test_Geo extends UnitTestCase { +class Test_Geo extends PHPUnit_Framework_TestCase { function testTimezone() { $result = OC_Geo::timezone(3, 3); $expected = 'Africa/Porto-Novo'; diff --git a/tests/lib/group.php b/tests/lib/group.php index 28264b0f16..9128bd7ddc 100644 --- a/tests/lib/group.php +++ b/tests/lib/group.php @@ -22,7 +22,7 @@ * */ -class Test_Group extends UnitTestCase { +class Test_Group extends PHPUnit_Framework_TestCase { function setUp() { OC_Group::clearBackends(); } @@ -43,24 +43,24 @@ class Test_Group extends UnitTestCase { $this->assertFalse(OC_Group::inGroup($user1, $group2)); $this->assertFalse(OC_Group::inGroup($user2, $group2)); - $this->assertTrue(OC_Group::addToGroup($user1, $group1)); + $this->assertTrue((bool)OC_Group::addToGroup($user1, $group1)); $this->assertTrue(OC_Group::inGroup($user1, $group1)); $this->assertFalse(OC_Group::inGroup($user2, $group1)); $this->assertFalse(OC_Group::inGroup($user1, $group2)); $this->assertFalse(OC_Group::inGroup($user2, $group2)); - $this->assertFalse(OC_Group::addToGroup($user1, $group1)); + $this->assertFalse((bool)OC_Group::addToGroup($user1, $group1)); - $this->assertEqual(array($user1), OC_Group::usersInGroup($group1)); - $this->assertEqual(array(), OC_Group::usersInGroup($group2)); + $this->assertEquals(array($user1), OC_Group::usersInGroup($group1)); + $this->assertEquals(array(), OC_Group::usersInGroup($group2)); - $this->assertEqual(array($group1), OC_Group::getUserGroups($user1)); - $this->assertEqual(array(), OC_Group::getUserGroups($user2)); + $this->assertEquals(array($group1), OC_Group::getUserGroups($user1)); + $this->assertEquals(array(), OC_Group::getUserGroups($user2)); OC_Group::deleteGroup($group1); - $this->assertEqual(array(), OC_Group::getUserGroups($user1)); - $this->assertEqual(array(), OC_Group::usersInGroup($group1)); + $this->assertEquals(array(), OC_Group::getUserGroups($user1)); + $this->assertEquals(array(), OC_Group::usersInGroup($group1)); $this->assertFalse(OC_Group::inGroup($user1, $group1)); } @@ -69,7 +69,7 @@ class Test_Group extends UnitTestCase { OC_Group::useBackend(new OC_Group_Dummy()); $emptyGroup = null; - $this->assertEqual(false, OC_Group::createGroup($emptyGroup)); + $this->assertEquals(false, OC_Group::createGroup($emptyGroup)); } @@ -80,8 +80,8 @@ class Test_Group extends UnitTestCase { $groupCopy = $group; - $this->assertEqual(false, OC_Group::createGroup($groupCopy)); - $this->assertEqual(array($group), OC_Group::getGroups()); + $this->assertEquals(false, OC_Group::createGroup($groupCopy)); + $this->assertEquals(array($group), OC_Group::getGroups()); } @@ -90,8 +90,8 @@ class Test_Group extends UnitTestCase { $adminGroup = 'admin'; OC_Group::createGroup($adminGroup); - $this->assertEqual(false, OC_Group::deleteGroup($adminGroup)); - $this->assertEqual(array($adminGroup), OC_Group::getGroups()); + $this->assertEquals(false, OC_Group::deleteGroup($adminGroup)); + $this->assertEquals(array($adminGroup), OC_Group::getGroups()); } @@ -100,8 +100,8 @@ class Test_Group extends UnitTestCase { $groupNonExistent = 'notExistent'; $user = uniqid(); - $this->assertEqual(false, OC_Group::addToGroup($user, $groupNonExistent)); - $this->assertEqual(array(), OC_Group::getGroups()); + $this->assertEquals(false, OC_Group::addToGroup($user, $groupNonExistent)); + $this->assertEquals(array(), OC_Group::getGroups()); } @@ -122,7 +122,7 @@ class Test_Group extends UnitTestCase { OC_Group::addToGroup($user3, $group1); OC_Group::addToGroup($user3, $group2); - $this->assertEqual(array($user1, $user2, $user3), + $this->assertEquals(array($user1, $user2, $user3), OC_Group::usersInGroups(array($group1, $group2, $group3))); // FIXME: needs more parameter variation @@ -141,16 +141,16 @@ class Test_Group extends UnitTestCase { OC_Group::createGroup($group1); //groups should be added to the first registered backend - $this->assertEqual(array($group1), $backend1->getGroups()); - $this->assertEqual(array(), $backend2->getGroups()); + $this->assertEquals(array($group1), $backend1->getGroups()); + $this->assertEquals(array(), $backend2->getGroups()); - $this->assertEqual(array($group1), OC_Group::getGroups()); + $this->assertEquals(array($group1), OC_Group::getGroups()); $this->assertTrue(OC_Group::groupExists($group1)); $this->assertFalse(OC_Group::groupExists($group2)); $backend1->createGroup($group2); - $this->assertEqual(array($group1, $group2), OC_Group::getGroups()); + $this->assertEquals(array($group1, $group2), OC_Group::getGroups()); $this->assertTrue(OC_Group::groupExists($group1)); $this->assertTrue(OC_Group::groupExists($group2)); @@ -161,22 +161,22 @@ class Test_Group extends UnitTestCase { $this->assertFalse(OC_Group::inGroup($user2, $group1)); - $this->assertTrue(OC_Group::addToGroup($user1, $group1)); + $this->assertTrue((bool)OC_Group::addToGroup($user1, $group1)); $this->assertTrue(OC_Group::inGroup($user1, $group1)); $this->assertFalse(OC_Group::inGroup($user2, $group1)); $this->assertFalse($backend2->inGroup($user1, $group1)); - $this->assertFalse(OC_Group::addToGroup($user1, $group1)); + $this->assertFalse((bool)OC_Group::addToGroup($user1, $group1)); - $this->assertEqual(array($user1), OC_Group::usersInGroup($group1)); + $this->assertEquals(array($user1), OC_Group::usersInGroup($group1)); - $this->assertEqual(array($group1), OC_Group::getUserGroups($user1)); - $this->assertEqual(array(), OC_Group::getUserGroups($user2)); + $this->assertEquals(array($group1), OC_Group::getUserGroups($user1)); + $this->assertEquals(array(), OC_Group::getUserGroups($user2)); OC_Group::deleteGroup($group1); - $this->assertEqual(array(), OC_Group::getUserGroups($user1)); - $this->assertEqual(array(), OC_Group::usersInGroup($group1)); + $this->assertEquals(array(), OC_Group::getUserGroups($user1)); + $this->assertEquals(array(), OC_Group::usersInGroup($group1)); $this->assertFalse(OC_Group::inGroup($user1, $group1)); } } diff --git a/tests/lib/group/backend.php b/tests/lib/group/backend.php index f61abed5f2..d308232a78 100644 --- a/tests/lib/group/backend.php +++ b/tests/lib/group/backend.php @@ -20,7 +20,7 @@ * */ -abstract class Test_Group_Backend extends UnitTestCase { +abstract class Test_Group_Backend extends PHPUnit_Framework_TestCase { /** * @var OC_Group_Backend $backend */ @@ -52,18 +52,18 @@ abstract class Test_Group_Backend extends UnitTestCase { $name2=$this->getGroupName(); $this->backend->createGroup($name1); $count=count($this->backend->getGroups())-$startCount; - $this->assertEqual(1, $count); + $this->assertEquals(1, $count); $this->assertTrue((array_search($name1, $this->backend->getGroups())!==false)); $this->assertFalse((array_search($name2, $this->backend->getGroups())!==false)); $this->backend->createGroup($name2); $count=count($this->backend->getGroups())-$startCount; - $this->assertEqual(2, $count); + $this->assertEquals(2, $count); $this->assertTrue((array_search($name1, $this->backend->getGroups())!==false)); $this->assertTrue((array_search($name2, $this->backend->getGroups())!==false)); $this->backend->deleteGroup($name2); $count=count($this->backend->getGroups())-$startCount; - $this->assertEqual(1, $count); + $this->assertEquals(1, $count); $this->assertTrue((array_search($name1, $this->backend->getGroups())!==false)); $this->assertFalse((array_search($name2, $this->backend->getGroups())!==false)); } @@ -91,15 +91,15 @@ abstract class Test_Group_Backend extends UnitTestCase { $this->assertFalse($this->backend->addToGroup($user1, $group1)); - $this->assertEqual(array($user1), $this->backend->usersInGroup($group1)); - $this->assertEqual(array(), $this->backend->usersInGroup($group2)); + $this->assertEquals(array($user1), $this->backend->usersInGroup($group1)); + $this->assertEquals(array(), $this->backend->usersInGroup($group2)); - $this->assertEqual(array($group1), $this->backend->getUserGroups($user1)); - $this->assertEqual(array(), $this->backend->getUserGroups($user2)); + $this->assertEquals(array($group1), $this->backend->getUserGroups($user1)); + $this->assertEquals(array(), $this->backend->getUserGroups($user2)); $this->backend->deleteGroup($group1); - $this->assertEqual(array(), $this->backend->getUserGroups($user1)); - $this->assertEqual(array(), $this->backend->usersInGroup($group1)); + $this->assertEquals(array(), $this->backend->getUserGroups($user1)); + $this->assertEquals(array(), $this->backend->usersInGroup($group1)); $this->assertFalse($this->backend->inGroup($user1, $group1)); } } diff --git a/tests/lib/helper.php b/tests/lib/helper.php index cfb9a79957..336e8f8b3c 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -class Test_Helper extends UnitTestCase { +class Test_Helper extends PHPUnit_Framework_TestCase { function testHumanFileSize() { $result = OC_Helper::humanFileSize(0); diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php index 92f5d065cf..ab43e47726 100644 --- a/tests/lib/share/share.php +++ b/tests/lib/share/share.php @@ -19,7 +19,7 @@ * License along with this library. If not, see . */ -class Test_Share extends UnitTestCase { +class Test_Share extends PHPUnit_Framework_TestCase { protected $itemType; protected $userBackend; diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index 89b2785fca..aebbc93b90 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -20,7 +20,7 @@ * */ -class Test_StreamWrappers extends UnitTestCase { +class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public function testFakeDir() { $items=array('foo', 'bar'); OC_FakeDirStream::$dirs['test']=$items; @@ -30,7 +30,7 @@ class Test_StreamWrappers extends UnitTestCase { $result[]=$file; $this->assertContains($file, $items); } - $this->assertEqual(count($items), count($result)); + $this->assertEquals(count($items), count($result)); } public function testStaticStream() { @@ -39,7 +39,7 @@ class Test_StreamWrappers extends UnitTestCase { $this->assertFalse(file_exists($staticFile)); file_put_contents($staticFile, file_get_contents($sourceFile)); $this->assertTrue(file_exists($staticFile)); - $this->assertEqual(file_get_contents($sourceFile), file_get_contents($staticFile)); + $this->assertEquals(file_get_contents($sourceFile), file_get_contents($staticFile)); unlink($staticFile); clearstatcache(); $this->assertFalse(file_exists($staticFile)); @@ -52,7 +52,7 @@ class Test_StreamWrappers extends UnitTestCase { $file='close://'.$tmpFile; $this->assertTrue(file_exists($file)); file_put_contents($file, file_get_contents($sourceFile)); - $this->assertEqual(file_get_contents($sourceFile), file_get_contents($file)); + $this->assertEquals(file_get_contents($sourceFile), file_get_contents($file)); unlink($file); clearstatcache(); $this->assertFalse(file_exists($file)); @@ -68,7 +68,7 @@ class Test_StreamWrappers extends UnitTestCase { $this->fail('Expected exception'); }catch(Exception $e) { $path=$e->getMessage(); - $this->assertEqual($path, $tmpFile); + $this->assertEquals($path, $tmpFile); } } diff --git a/tests/lib/template.php b/tests/lib/template.php index 2899c3512b..6e88d4c07f 100644 --- a/tests/lib/template.php +++ b/tests/lib/template.php @@ -22,7 +22,7 @@ OC::autoload('OC_Template'); -class Test_TemplateFunctions extends UnitTestCase { +class Test_TemplateFunctions extends PHPUnit_Framework_TestCase { public function testP() { // FIXME: do we need more testcases? @@ -31,7 +31,7 @@ class Test_TemplateFunctions extends UnitTestCase { p($htmlString); $result = ob_get_clean(); - $this->assertEqual("<script>alert('xss');</script>", $result); + $this->assertEquals("<script>alert('xss');</script>", $result); } public function testPNormalString() { @@ -40,7 +40,7 @@ class Test_TemplateFunctions extends UnitTestCase { p($normalString); $result = ob_get_clean(); - $this->assertEqual("This is a good string!", $result); + $this->assertEquals("This is a good string!", $result); } @@ -51,7 +51,7 @@ class Test_TemplateFunctions extends UnitTestCase { print_unescaped($htmlString); $result = ob_get_clean(); - $this->assertEqual($htmlString, $result); + $this->assertEquals($htmlString, $result); } public function testPrintUnescapedNormalString() { @@ -60,7 +60,7 @@ class Test_TemplateFunctions extends UnitTestCase { print_unescaped($normalString); $result = ob_get_clean(); - $this->assertEqual("This is a good string!", $result); + $this->assertEquals("This is a good string!", $result); } diff --git a/tests/lib/user/backend.php b/tests/lib/user/backend.php index 0b744770ea..40674424c9 100644 --- a/tests/lib/user/backend.php +++ b/tests/lib/user/backend.php @@ -30,7 +30,7 @@ * For an example see /tests/lib/user/dummy.php */ -abstract class Test_User_Backend extends UnitTestCase { +abstract class Test_User_Backend extends PHPUnit_Framework_TestCase { /** * @var OC_User_Backend $backend */ @@ -53,18 +53,18 @@ abstract class Test_User_Backend extends UnitTestCase { $name2=$this->getUser(); $this->backend->createUser($name1, ''); $count=count($this->backend->getUsers())-$startCount; - $this->assertEqual(1, $count); + $this->assertEquals(1, $count); $this->assertTrue((array_search($name1, $this->backend->getUsers())!==false)); $this->assertFalse((array_search($name2, $this->backend->getUsers())!==false)); $this->backend->createUser($name2, ''); $count=count($this->backend->getUsers())-$startCount; - $this->assertEqual(2, $count); + $this->assertEquals(2, $count); $this->assertTrue((array_search($name1, $this->backend->getUsers())!==false)); $this->assertTrue((array_search($name2, $this->backend->getUsers())!==false)); $this->backend->deleteUser($name2); $count=count($this->backend->getUsers())-$startCount; - $this->assertEqual(1, $count); + $this->assertEquals(1, $count); $this->assertTrue((array_search($name1, $this->backend->getUsers())!==false)); $this->assertFalse((array_search($name2, $this->backend->getUsers())!==false)); } diff --git a/tests/lib/util.php b/tests/lib/util.php index 27635cb805..ebff3c7381 100644 --- a/tests/lib/util.php +++ b/tests/lib/util.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -class Test_Util extends UnitTestCase { +class Test_Util extends PHPUnit_Framework_TestCase { // Constructor function Test_Util() { diff --git a/tests/lib/vcategories.php b/tests/lib/vcategories.php index 63516a063d..e79dd49870 100644 --- a/tests/lib/vcategories.php +++ b/tests/lib/vcategories.php @@ -22,7 +22,7 @@ //require_once("../lib/template.php"); -class Test_VCategories extends UnitTestCase { +class Test_VCategories extends PHPUnit_Framework_TestCase { protected $objectType; protected $user; @@ -49,7 +49,7 @@ class Test_VCategories extends UnitTestCase { $catmgr = new OC_VCategories($this->objectType, $this->user, $defcategories); - $this->assertEqual(4, count($catmgr->categories())); + $this->assertEquals(4, count($catmgr->categories())); } public function testAddCategories() { @@ -59,25 +59,25 @@ class Test_VCategories extends UnitTestCase { foreach($categories as $category) { $result = $catmgr->add($category); - $this->assertTrue($result); + $this->assertTrue((bool)$result); } $this->assertFalse($catmgr->add('Family')); $this->assertFalse($catmgr->add('fAMILY')); - $this->assertEqual(4, count($catmgr->categories())); + $this->assertEquals(4, count($catmgr->categories())); } public function testdeleteCategories() { $defcategories = array('Friends', 'Family', 'Work', 'Other'); $catmgr = new OC_VCategories($this->objectType, $this->user, $defcategories); - $this->assertEqual(4, count($catmgr->categories())); + $this->assertEquals(4, count($catmgr->categories())); $catmgr->delete('family'); - $this->assertEqual(3, count($catmgr->categories())); + $this->assertEquals(3, count($catmgr->categories())); $catmgr->delete(array('Friends', 'Work', 'Other')); - $this->assertEqual(0, count($catmgr->categories())); + $this->assertEquals(0, count($catmgr->categories())); } @@ -90,8 +90,8 @@ class Test_VCategories extends UnitTestCase { $catmgr->addToCategory($id, 'Family'); } - $this->assertEqual(1, count($catmgr->categories())); - $this->assertEqual(9, count($catmgr->idsForCategory('Family'))); + $this->assertEquals(1, count($catmgr->categories())); + $this->assertEquals(9, count($catmgr->idsForCategory('Family'))); } /** @@ -110,8 +110,8 @@ class Test_VCategories extends UnitTestCase { $this->assertFalse(in_array($id, $catmgr->idsForCategory('Family'))); } - $this->assertEqual(1, count($catmgr->categories())); - $this->assertEqual(0, count($catmgr->idsForCategory('Family'))); + $this->assertEquals(1, count($catmgr->categories())); + $this->assertEquals(0, count($catmgr->idsForCategory('Family'))); } } From 6832dddf397bd30968a8892ee69dcbdbc84f2b9b Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Fri, 25 Jan 2013 00:05:56 +0100 Subject: [PATCH 254/315] [tx-robot] updated from transifex --- apps/files/l10n/fr.php | 1 + apps/files/l10n/sk_SK.php | 9 +++++++ apps/files_encryption/l10n/el.php | 2 ++ apps/files_encryption/l10n/fr.php | 11 +++++++++ apps/files_encryption/l10n/sv.php | 11 +++++++++ apps/files_sharing/l10n/zh_TW.php | 3 ++- apps/user_ldap/l10n/fr.php | 8 +++++-- apps/user_webdavauth/l10n/fr.php | 4 +++- apps/user_webdavauth/l10n/sk_SK.php | 3 ++- l10n/el/files_encryption.po | 8 +++---- l10n/fr/files.po | 8 +++---- l10n/fr/files_encryption.po | 30 +++++++++++------------ l10n/fr/lib.po | 12 +++++----- l10n/fr/user_ldap.po | 20 ++++++++-------- l10n/fr/user_webdavauth.po | 10 ++++---- l10n/sk_SK/files.po | 25 +++++++++---------- l10n/sk_SK/settings.po | 37 +++++++++++++++-------------- l10n/sk_SK/user_webdavauth.po | 11 +++++---- l10n/sv/files_encryption.po | 30 +++++++++++------------ l10n/templates/core.pot | 2 +- l10n/templates/files.pot | 2 +- l10n/templates/files_encryption.pot | 2 +- l10n/templates/files_external.pot | 2 +- l10n/templates/files_sharing.pot | 2 +- l10n/templates/files_versions.pot | 2 +- l10n/templates/lib.pot | 2 +- l10n/templates/settings.pot | 2 +- l10n/templates/user_ldap.pot | 2 +- l10n/templates/user_webdavauth.pot | 2 +- l10n/zh_TW/files_sharing.po | 9 +++---- lib/l10n/fr.php | 1 + settings/l10n/sk_SK.php | 15 ++++++++++++ 32 files changed, 175 insertions(+), 113 deletions(-) diff --git a/apps/files/l10n/fr.php b/apps/files/l10n/fr.php index 162c2e2dfd..2e4ae63820 100644 --- a/apps/files/l10n/fr.php +++ b/apps/files/l10n/fr.php @@ -29,6 +29,7 @@ "'.' is an invalid file name." => "'.' n'est pas un nom de fichier valide.", "File name cannot be empty." => "Le nom de fichier ne peut être vide.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nom invalide, les caractères '\\', '/', '<', '>', ':', '\"', '|', '?' et '*' ne sont pas autorisés.", +"Your download is being prepared. This might take some time if the files are big." => "Votre téléchargement est cours de préparation. Ceci peut nécessiter un certain temps si les fichiers sont volumineux.", "Unable to upload your file as it is a directory or has 0 bytes" => "Impossible de charger vos fichiers car il s'agit d'un dossier ou le fichier fait 0 octet.", "Upload Error" => "Erreur de chargement", "Close" => "Fermer", diff --git a/apps/files/l10n/sk_SK.php b/apps/files/l10n/sk_SK.php index b28e2648fe..66163b1e53 100644 --- a/apps/files/l10n/sk_SK.php +++ b/apps/files/l10n/sk_SK.php @@ -1,5 +1,8 @@ "Odoslať", +"Could not move %s - File with this name already exists" => "Nie je možné presunúť %s - súbor s týmto menom už existuje", +"Could not move %s" => "Nie je možné presunúť %s", +"Unable to rename file" => "Nemožno premenovať súbor", "No file was uploaded. Unknown error" => "Žiaden súbor nebol odoslaný. Neznáma chyba", "There is no error, the file uploaded with success" => "Nenastala žiadna chyba, súbor bol úspešne nahraný", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Nahraný súbor predčil konfiguračnú direktívu upload_max_filesize v súbore php.ini:", @@ -8,6 +11,8 @@ "No file was uploaded" => "Žiaden súbor nebol nahraný", "Missing a temporary folder" => "Chýbajúci dočasný priečinok", "Failed to write to disk" => "Zápis na disk sa nepodaril", +"Not enough space available" => "Nie je k dispozícii dostatok miesta", +"Invalid directory." => "Neplatný adresár", "Files" => "Súbory", "Unshare" => "Nezdielať", "Delete" => "Odstrániť", @@ -21,7 +26,10 @@ "replaced {new_name} with {old_name}" => "prepísaný {new_name} súborom {old_name}", "unshared {files}" => "zdieľanie zrušené pre {files}", "deleted {files}" => "zmazané {files}", +"'.' is an invalid file name." => "'.' je neplatné meno súboru.", +"File name cannot be empty." => "Meno súboru nemôže byť prázdne", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nesprávne meno, '\\', '/', '<', '>', ':', '\"', '|', '?' a '*' nie sú povolené hodnoty.", +"Your download is being prepared. This might take some time if the files are big." => "Vaše sťahovanie sa pripravuje. Ak sú sťahované súbory veľké, môže to chvíľu trvať.", "Unable to upload your file as it is a directory or has 0 bytes" => "Nemôžem nahrať súbor lebo je to priečinok alebo má 0 bajtov.", "Upload Error" => "Chyba odosielania", "Close" => "Zavrieť", @@ -31,6 +39,7 @@ "Upload cancelled." => "Odosielanie zrušené", "File upload is in progress. Leaving the page now will cancel the upload." => "Opustenie stránky zruší práve prebiehajúce odosielanie súboru.", "URL cannot be empty." => "URL nemôže byť prázdne", +"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Neplatné meno adresára. Používanie mena 'Shared' je vyhradené len pre Owncloud", "{count} files scanned" => "{count} súborov prehľadaných", "error while scanning" => "chyba počas kontroly", "Name" => "Meno", diff --git a/apps/files_encryption/l10n/el.php b/apps/files_encryption/l10n/el.php index cbf65b5cfa..50b812c82d 100644 --- a/apps/files_encryption/l10n/el.php +++ b/apps/files_encryption/l10n/el.php @@ -1,5 +1,7 @@ "Αλλαγή συνθηματικού κρυπτογράφησης στο συνθηματικό εισόδου ", "Please check your passwords and try again." => "Παρακαλώ ελέγξτε το συνθηματικό σας και προσπαθήστε ξανά.", +"Could not change your file encryption password to your login password" => "Αδυναμία αλλαγής συνθηματικού κρυπτογράφησης αρχείων στο συνθηματικό εισόδου σας", "Choose encryption mode:" => "Επιλογή κατάστασης κρυπτογράφησης:", "Encryption" => "Κρυπτογράφηση", "Exclude the following file types from encryption" => "Εξαίρεση των παρακάτω τύπων αρχείων από την κρυπτογράφηση", diff --git a/apps/files_encryption/l10n/fr.php b/apps/files_encryption/l10n/fr.php index f78a90ad59..41e37134d4 100644 --- a/apps/files_encryption/l10n/fr.php +++ b/apps/files_encryption/l10n/fr.php @@ -1,4 +1,15 @@ "Veuillez vous connecter depuis votre client de synchronisation ownCloud et changer votre mot de passe de chiffrement pour finaliser la conversion.", +"switched to client side encryption" => "Mode de chiffrement changé en chiffrement côté client", +"Change encryption password to login password" => "Convertir le mot de passe de chiffrement en mot de passe de connexion", +"Please check your passwords and try again." => "Veuillez vérifier vos mots de passe et réessayer.", +"Could not change your file encryption password to your login password" => "Impossible de convertir votre mot de passe de chiffrement en mot de passe de connexion", +"Choose encryption mode:" => "Choix du type de chiffrement :", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Chiffrement côté client (plus sécurisé, mais ne permet pas l'accès à vos données depuis l'interface web)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Chiffrement côté serveur (vous permet d'accéder à vos fichiers depuis l'interface web et depuis le client de synchronisation)", +"None (no encryption at all)" => "Aucun (pas de chiffrement)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Important : Une fois le mode de chiffrement choisi, il est impossible de revenir en arrière", +"User specific (let the user decide)" => "Propre à l'utilisateur (laisse le choix à l'utilisateur)", "Encryption" => "Chiffrement", "Exclude the following file types from encryption" => "Ne pas chiffrer les fichiers dont les types sont les suivants", "None" => "Aucun" diff --git a/apps/files_encryption/l10n/sv.php b/apps/files_encryption/l10n/sv.php index c154de1a76..9b6ce14178 100644 --- a/apps/files_encryption/l10n/sv.php +++ b/apps/files_encryption/l10n/sv.php @@ -1,4 +1,15 @@ "Vänligen växla till ownCloud klienten och ändra ditt krypteringslösenord för att slutföra omvandlingen.", +"switched to client side encryption" => "Bytte till kryptering på klientsidan", +"Change encryption password to login password" => "Ändra krypteringslösenord till loginlösenord", +"Please check your passwords and try again." => "Kontrollera dina lösenord och försök igen.", +"Could not change your file encryption password to your login password" => "Kunde inte ändra ditt filkrypteringslösenord till ditt loginlösenord", +"Choose encryption mode:" => "Välj krypteringsläge:", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Kryptering på klientsidan (säkraste men gör det omöjligt att komma åt dina filer med en webbläsare)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Kryptering på serversidan (kan komma åt dina filer från webbläsare och datorklient)", +"None (no encryption at all)" => "Ingen (ingen kryptering alls)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Viktigt: När du har valt ett krypteringsläge finns det inget sätt att ändra tillbaka", +"User specific (let the user decide)" => "Användarspecifik (låter användaren bestämma)", "Encryption" => "Kryptering", "Exclude the following file types from encryption" => "Exkludera följande filtyper från kryptering", "None" => "Ingen" diff --git a/apps/files_sharing/l10n/zh_TW.php b/apps/files_sharing/l10n/zh_TW.php index fa4f8075c6..f1d28731a7 100644 --- a/apps/files_sharing/l10n/zh_TW.php +++ b/apps/files_sharing/l10n/zh_TW.php @@ -4,5 +4,6 @@ "%s shared the folder %s with you" => "%s 分享了資料夾 %s 給您", "%s shared the file %s with you" => "%s 分享了檔案 %s 給您", "Download" => "下載", -"No preview available for" => "無法預覽" +"No preview available for" => "無法預覽", +"web services under your control" => "在您掌控之下的網路服務" ); diff --git a/apps/user_ldap/l10n/fr.php b/apps/user_ldap/l10n/fr.php index dd2fb08091..28ee6346ef 100644 --- a/apps/user_ldap/l10n/fr.php +++ b/apps/user_ldap/l10n/fr.php @@ -1,11 +1,13 @@ Warning: Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behaviour. Please ask your system administrator to disable one of them." => "Avertissement: Les applications user_ldap et user_webdavauth sont incompatibles. Des disfonctionnements peuvent survenir. Contactez votre administrateur système pour qu'il désactive l'une d'elles.", +"Warning: The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "Attention : Le module php LDAP n'est pas installé, par conséquent cette extension ne pourra fonctionner. Veuillez contacter votre administrateur système afin qu'il l'installe.", "Host" => "Hôte", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Vous pouvez omettre le protocole, sauf si vous avez besoin de SSL. Dans ce cas préfixez avec ldaps://", "Base DN" => "DN Racine", -"You can specify Base DN for users and groups in the Advanced tab" => "Vous pouvez détailler les DN Racines de vos utilisateurs et groupes dans l'onglet Avancé", +"One Base DN per line" => "Un DN racine par ligne", +"You can specify Base DN for users and groups in the Advanced tab" => "Vous pouvez spécifier les DN Racines de vos utilisateurs et groupes via l'onglet Avancé", "User DN" => "DN Utilisateur (Autorisé à consulter l'annuaire)", -"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Le DN de l'utilisateur client avec lequel la liaison doit se faire, par exemple uid=agent,dc=example,dc=com. Pour l'accès anonyme, laisser le DN et le mot de passe vides.", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN de l'utilisateur client pour lequel la liaison doit se faire, par exemple uid=agent,dc=example,dc=com. Pour un accès anonyme, laisser le DN et le mot de passe vides.", "Password" => "Mot de passe", "For anonymous access, leave DN and Password empty." => "Pour un accès anonyme, laisser le DN Utilisateur et le mot de passe vides.", "User Login Filter" => "Modèle d'authentification utilisateurs", @@ -19,7 +21,9 @@ "without any placeholder, e.g. \"objectClass=posixGroup\"." => "sans élément de substitution, par exemple \"objectClass=posixGroup\".", "Port" => "Port", "Base User Tree" => "DN racine de l'arbre utilisateurs", +"One User Base DN per line" => "Un DN racine utilisateur par ligne", "Base Group Tree" => "DN racine de l'arbre groupes", +"One Group Base DN per line" => "Un DN racine groupe par ligne", "Group-Member association" => "Association groupe-membre", "Use TLS" => "Utiliser TLS", "Do not use it for SSL connections, it will fail." => "Ne pas utiliser pour les connexions SSL, car cela échouera.", diff --git a/apps/user_webdavauth/l10n/fr.php b/apps/user_webdavauth/l10n/fr.php index 339931c7ce..9d528a3a9d 100644 --- a/apps/user_webdavauth/l10n/fr.php +++ b/apps/user_webdavauth/l10n/fr.php @@ -1,3 +1,5 @@ "URL : http://" +"WebDAV Authentication" => "Authentification WebDAV", +"URL: http://" => "URL : http://", +"ownCloud will send the user credentials to this URL. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud enverra les informations de connexion à cette adresse. Ce module complémentaire analyse le code réponse HTTP et considère tout code différent des codes 401 et 403 comme associé à une authentification correcte." ); diff --git a/apps/user_webdavauth/l10n/sk_SK.php b/apps/user_webdavauth/l10n/sk_SK.php index 9bd32954b0..6e34b818ed 100644 --- a/apps/user_webdavauth/l10n/sk_SK.php +++ b/apps/user_webdavauth/l10n/sk_SK.php @@ -1,3 +1,4 @@ "WebDAV URL: http://" +"WebDAV Authentication" => "WebDAV overenie", +"URL: http://" => "URL: http://" ); diff --git a/l10n/el/files_encryption.po b/l10n/el/files_encryption.po index db198521dc..8733b3c001 100644 --- a/l10n/el/files_encryption.po +++ b/l10n/el/files_encryption.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" -"PO-Revision-Date: 2013-01-22 23:23+0000\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 08:32+0000\n" "Last-Translator: Efstathios Iosifidis \n" "Language-Team: Greek (http://www.transifex.com/projects/p/owncloud/language/el/)\n" "MIME-Version: 1.0\n" @@ -31,7 +31,7 @@ msgstr "" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Αλλαγή συνθηματικού κρυπτογράφησης στο συνθηματικό εισόδου " #: js/settings-personal.js:25 msgid "Please check your passwords and try again." @@ -39,7 +39,7 @@ msgstr "Παρακαλώ ελέγξτε το συνθηματικό σας κα #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Αδυναμία αλλαγής συνθηματικού κρυπτογράφησης αρχείων στο συνθηματικό εισόδου σας" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" diff --git a/l10n/fr/files.po b/l10n/fr/files.po index ca272a1b28..c0d0775a98 100644 --- a/l10n/fr/files.po +++ b/l10n/fr/files.po @@ -19,9 +19,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 01:27+0000\n" +"Last-Translator: Romain DEP. \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -161,7 +161,7 @@ msgstr "Nom invalide, les caractères '\\', '/', '<', '>', ':', '\"', '|', '?' e msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "Votre téléchargement est cours de préparation. Ceci peut nécessiter un certain temps si les fichiers sont volumineux." #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" diff --git a/l10n/fr/files_encryption.po b/l10n/fr/files_encryption.po index 8c8754a7a8..f1305f621d 100644 --- a/l10n/fr/files_encryption.po +++ b/l10n/fr/files_encryption.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# Romain DEP. , 2012. +# Romain DEP. , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 01:10+0000\n" +"Last-Translator: Romain DEP. \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,53 +22,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Veuillez vous connecter depuis votre client de synchronisation ownCloud et changer votre mot de passe de chiffrement pour finaliser la conversion." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "Mode de chiffrement changé en chiffrement côté client" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Convertir le mot de passe de chiffrement en mot de passe de connexion" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Veuillez vérifier vos mots de passe et réessayer." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Impossible de convertir votre mot de passe de chiffrement en mot de passe de connexion" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Choix du type de chiffrement :" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Chiffrement côté client (plus sécurisé, mais ne permet pas l'accès à vos données depuis l'interface web)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Chiffrement côté serveur (vous permet d'accéder à vos fichiers depuis l'interface web et depuis le client de synchronisation)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Aucun (pas de chiffrement)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Important : Une fois le mode de chiffrement choisi, il est impossible de revenir en arrière" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Propre à l'utilisateur (laisse le choix à l'utilisateur)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/fr/lib.po b/l10n/fr/lib.po index 07fd3669c4..0ae131d5c5 100644 --- a/l10n/fr/lib.po +++ b/l10n/fr/lib.po @@ -4,14 +4,14 @@ # # Translators: # Geoffrey Guerrier , 2012. -# Romain DEP. , 2012. +# Romain DEP. , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 01:17+0000\n" +"Last-Translator: Romain DEP. \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -59,9 +59,9 @@ msgstr "Retour aux Fichiers" msgid "Selected files too large to generate zip file." msgstr "Les fichiers sélectionnés sont trop volumineux pour être compressés." -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "impossible à déterminer" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/fr/user_ldap.po b/l10n/fr/user_ldap.po index c437634e5e..1beebaaf58 100644 --- a/l10n/fr/user_ldap.po +++ b/l10n/fr/user_ldap.po @@ -6,16 +6,16 @@ # Cyril Glapa , 2012. # , 2012. # , 2012. -# Romain DEP. , 2012. +# Romain DEP. , 2012-2013. # , 2012. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-16 00:19+0100\n" -"PO-Revision-Date: 2013-01-15 23:20+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 01:50+0000\n" +"Last-Translator: Romain DEP. \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -34,7 +34,7 @@ msgstr "Avertissement: Les applications user_ldap et user_webdavauth sont msgid "" "Warning: The PHP LDAP module is not installed, the backend will not " "work. Please ask your system administrator to install it." -msgstr "" +msgstr "Attention : Le module php LDAP n'est pas installé, par conséquent cette extension ne pourra fonctionner. Veuillez contacter votre administrateur système afin qu'il l'installe." #: templates/settings.php:15 msgid "Host" @@ -51,11 +51,11 @@ msgstr "DN Racine" #: templates/settings.php:16 msgid "One Base DN per line" -msgstr "" +msgstr "Un DN racine par ligne" #: templates/settings.php:16 msgid "You can specify Base DN for users and groups in the Advanced tab" -msgstr "Vous pouvez détailler les DN Racines de vos utilisateurs et groupes dans l'onglet Avancé" +msgstr "Vous pouvez spécifier les DN Racines de vos utilisateurs et groupes via l'onglet Avancé" #: templates/settings.php:17 msgid "User DN" @@ -66,7 +66,7 @@ msgid "" "The DN of the client user with which the bind shall be done, e.g. " "uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password " "empty." -msgstr "Le DN de l'utilisateur client avec lequel la liaison doit se faire, par exemple uid=agent,dc=example,dc=com. Pour l'accès anonyme, laisser le DN et le mot de passe vides." +msgstr "DN de l'utilisateur client pour lequel la liaison doit se faire, par exemple uid=agent,dc=example,dc=com. Pour un accès anonyme, laisser le DN et le mot de passe vides." #: templates/settings.php:18 msgid "Password" @@ -126,7 +126,7 @@ msgstr "DN racine de l'arbre utilisateurs" #: templates/settings.php:25 msgid "One User Base DN per line" -msgstr "" +msgstr "Un DN racine utilisateur par ligne" #: templates/settings.php:26 msgid "Base Group Tree" @@ -134,7 +134,7 @@ msgstr "DN racine de l'arbre groupes" #: templates/settings.php:26 msgid "One Group Base DN per line" -msgstr "" +msgstr "Un DN racine groupe par ligne" #: templates/settings.php:27 msgid "Group-Member association" diff --git a/l10n/fr/user_webdavauth.po b/l10n/fr/user_webdavauth.po index ec81f76c54..4d665c8ff4 100644 --- a/l10n/fr/user_webdavauth.po +++ b/l10n/fr/user_webdavauth.po @@ -12,9 +12,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:04+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 01:04+0000\n" +"Last-Translator: Romain DEP. \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,7 +24,7 @@ msgstr "" #: templates/settings.php:3 msgid "WebDAV Authentication" -msgstr "" +msgstr "Authentification WebDAV" #: templates/settings.php:4 msgid "URL: http://" @@ -35,4 +35,4 @@ msgid "" "ownCloud will send the user credentials to this URL. This plugin checks the " "response and will interpret the HTTP statuscodes 401 and 403 as invalid " "credentials, and all other responses as valid credentials." -msgstr "" +msgstr "ownCloud enverra les informations de connexion à cette adresse. Ce module complémentaire analyse le code réponse HTTP et considère tout code différent des codes 401 et 403 comme associé à une authentification correcte." diff --git a/l10n/sk_SK/files.po b/l10n/sk_SK/files.po index 30706c6eff..0ffb88a213 100644 --- a/l10n/sk_SK/files.po +++ b/l10n/sk_SK/files.po @@ -4,6 +4,7 @@ # # Translators: # , 2012. +# Marián Hvolka , 2013. # , 2012. # Roman Priesol , 2012. # , 2012. @@ -11,9 +12,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 19:08+0000\n" +"Last-Translator: mhh \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -29,16 +30,16 @@ msgstr "Odoslať" #: ajax/move.php:17 #, php-format msgid "Could not move %s - File with this name already exists" -msgstr "" +msgstr "Nie je možné presunúť %s - súbor s týmto menom už existuje" #: ajax/move.php:24 #, php-format msgid "Could not move %s" -msgstr "" +msgstr "Nie je možné presunúť %s" #: ajax/rename.php:19 msgid "Unable to rename file" -msgstr "" +msgstr "Nemožno premenovať súbor" #: ajax/upload.php:20 msgid "No file was uploaded. Unknown error" @@ -77,11 +78,11 @@ msgstr "Zápis na disk sa nepodaril" #: ajax/upload.php:57 msgid "Not enough space available" -msgstr "" +msgstr "Nie je k dispozícii dostatok miesta" #: ajax/upload.php:91 msgid "Invalid directory." -msgstr "" +msgstr "Neplatný adresár" #: appinfo/app.php:10 msgid "Files" @@ -137,11 +138,11 @@ msgstr "zmazané {files}" #: js/files.js:48 msgid "'.' is an invalid file name." -msgstr "" +msgstr "'.' je neplatné meno súboru." #: js/files.js:53 msgid "File name cannot be empty." -msgstr "" +msgstr "Meno súboru nemôže byť prázdne" #: js/files.js:62 msgid "" @@ -153,7 +154,7 @@ msgstr "Nesprávne meno, '\\', '/', '<', '>', ':', '\"', '|', '?' a '*' nie sú msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "Vaše sťahovanie sa pripravuje. Ak sú sťahované súbory veľké, môže to chvíľu trvať." #: js/files.js:242 msgid "Unable to upload your file as it is a directory or has 0 bytes" @@ -194,7 +195,7 @@ msgstr "URL nemôže byť prázdne" #: js/files.js:565 msgid "Invalid folder name. Usage of 'Shared' is reserved by Owncloud" -msgstr "" +msgstr "Neplatné meno adresára. Používanie mena 'Shared' je vyhradené len pre Owncloud" #: js/files.js:775 msgid "{count} files scanned" diff --git a/l10n/sk_SK/settings.po b/l10n/sk_SK/settings.po index e3c919f0ad..dec1e38009 100644 --- a/l10n/sk_SK/settings.po +++ b/l10n/sk_SK/settings.po @@ -4,6 +4,7 @@ # # Translators: # , 2011, 2012. +# Marián Hvolka , 2013. # , 2012. # Roman Priesol , 2012. # , 2012. @@ -12,9 +13,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 18:54+0000\n" +"Last-Translator: mhh \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -118,19 +119,19 @@ msgstr "-licencované , 2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:04+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 19:09+0000\n" +"Last-Translator: mhh \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,11 +21,11 @@ msgstr "" #: templates/settings.php:3 msgid "WebDAV Authentication" -msgstr "" +msgstr "WebDAV overenie" #: templates/settings.php:4 msgid "URL: http://" -msgstr "" +msgstr "URL: http://" #: templates/settings.php:6 msgid "" diff --git a/l10n/sv/files_encryption.po b/l10n/sv/files_encryption.po index 946f272acc..cb599b8ee0 100644 --- a/l10n/sv/files_encryption.po +++ b/l10n/sv/files_encryption.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: -# Magnus Höglund , 2012. +# Magnus Höglund , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 20:45+0000\n" +"Last-Translator: Magnus Höglund \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,53 +22,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Vänligen växla till ownCloud klienten och ändra ditt krypteringslösenord för att slutföra omvandlingen." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "Bytte till kryptering på klientsidan" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Ändra krypteringslösenord till loginlösenord" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Kontrollera dina lösenord och försök igen." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Kunde inte ändra ditt filkrypteringslösenord till ditt loginlösenord" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Välj krypteringsläge:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Kryptering på klientsidan (säkraste men gör det omöjligt att komma åt dina filer med en webbläsare)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Kryptering på serversidan (kan komma åt dina filer från webbläsare och datorklient)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Ingen (ingen kryptering alls)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Viktigt: När du har valt ett krypteringsläge finns det inget sätt att ändra tillbaka" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Användarspecifik (låter användaren bestämma)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot index 972ace2da7..b3fda01a0b 100644 --- a/l10n/templates/core.pot +++ b/l10n/templates/core.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files.pot b/l10n/templates/files.pot index 4e2eb92673..a3be804fff 100644 --- a/l10n/templates/files.pot +++ b/l10n/templates/files.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_encryption.pot b/l10n/templates/files_encryption.pot index 43ecb33b16..2198dc9eed 100644 --- a/l10n/templates/files_encryption.pot +++ b/l10n/templates/files_encryption.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_external.pot b/l10n/templates/files_external.pot index fadf6a450a..71dfe6cdf4 100644 --- a/l10n/templates/files_external.pot +++ b/l10n/templates/files_external.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_sharing.pot b/l10n/templates/files_sharing.pot index a6236dbce7..1f08c6a44d 100644 --- a/l10n/templates/files_sharing.pot +++ b/l10n/templates/files_sharing.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_versions.pot b/l10n/templates/files_versions.pot index 2b8a051d31..0fce19b38f 100644 --- a/l10n/templates/files_versions.pot +++ b/l10n/templates/files_versions.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/lib.pot b/l10n/templates/lib.pot index 829f4a30b7..1939f0089b 100644 --- a/l10n/templates/lib.pot +++ b/l10n/templates/lib.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot index 893a5ea219..f20fad1465 100644 --- a/l10n/templates/settings.pot +++ b/l10n/templates/settings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/user_ldap.pot b/l10n/templates/user_ldap.pot index a6b7c1cae5..f53be4e27a 100644 --- a/l10n/templates/user_ldap.pot +++ b/l10n/templates/user_ldap.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/user_webdavauth.pot b/l10n/templates/user_webdavauth.pot index 82fcbf1276..0c284c7002 100644 --- a/l10n/templates/user_webdavauth.pot +++ b/l10n/templates/user_webdavauth.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-24 00:06+0100\n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/zh_TW/files_sharing.po b/l10n/zh_TW/files_sharing.po index 01ec04db5b..c60cf46d16 100644 --- a/l10n/zh_TW/files_sharing.po +++ b/l10n/zh_TW/files_sharing.po @@ -4,14 +4,15 @@ # # Translators: # , 2012. +# Pellaeon Lin , 2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2012-11-28 00:10+0100\n" -"PO-Revision-Date: 2012-11-27 14:28+0000\n" -"Last-Translator: dw4dev \n" +"POT-Creation-Date: 2013-01-25 00:05+0100\n" +"PO-Revision-Date: 2013-01-24 13:15+0000\n" +"Last-Translator: pellaeon \n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/owncloud/language/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -47,4 +48,4 @@ msgstr "無法預覽" #: templates/public.php:43 msgid "web services under your control" -msgstr "" +msgstr "在您掌控之下的網路服務" diff --git a/lib/l10n/fr.php b/lib/l10n/fr.php index 218c22c1d5..c6bf8f7f9c 100644 --- a/lib/l10n/fr.php +++ b/lib/l10n/fr.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "Les fichiers nécessitent d'être téléchargés un par un.", "Back to Files" => "Retour aux Fichiers", "Selected files too large to generate zip file." => "Les fichiers sélectionnés sont trop volumineux pour être compressés.", +"couldn't be determined" => "impossible à déterminer", "Application is not enabled" => "L'application n'est pas activée", "Authentication error" => "Erreur d'authentification", "Token expired. Please reload page." => "La session a expiré. Veuillez recharger la page.", diff --git a/settings/l10n/sk_SK.php b/settings/l10n/sk_SK.php index ecf1a90500..884e785ad8 100644 --- a/settings/l10n/sk_SK.php +++ b/settings/l10n/sk_SK.php @@ -22,8 +22,16 @@ "Select an App" => "Vyberte aplikáciu", "See application page at apps.owncloud.com" => "Pozrite si stránku aplikácií na apps.owncloud.com", "-licensed by " => "-licencované ", +"User Documentation" => "Príručka používateľa", +"Administrator Documentation" => "Príručka správcu", +"Online Documentation" => "Online príručka", +"Forum" => "Fórum", +"Commercial Support" => "Komerčná podpora", "You have used %s of the available %s" => "Použili ste %s z %s dostupných ", "Clients" => "Klienti", +"Download Desktop Clients" => "Stiahnuť desktopového klienta", +"Download Android Client" => "Stiahnuť Android klienta", +"Download iOS Client" => "Stiahnuť iOS klienta", "Password" => "Heslo", "Your password was changed" => "Heslo bolo zmenené", "Unable to change your password" => "Nie je možné zmeniť vaše heslo", @@ -36,11 +44,18 @@ "Fill in an email address to enable password recovery" => "Vyplňte emailovú adresu pre aktivovanie obnovy hesla", "Language" => "Jazyk", "Help translate" => "Pomôcť s prekladom", +"WebDAV" => "WebDAV", +"Use this address to connect to your ownCloud in your file manager" => "Použite túto adresu pre pripojenie vášho ownCloud k súborovému správcovi", +"Version" => "Verzia", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Vyvinuté komunitou ownCloud,zdrojový kód je licencovaný pod AGPL.", "Name" => "Meno", "Groups" => "Skupiny", "Create" => "Vytvoriť", +"Default Storage" => "Predvolené úložisko", +"Unlimited" => "Nelimitované", "Other" => "Iné", "Group Admin" => "Správca skupiny", +"Storage" => "Úložisko", +"Default" => "Predvolené", "Delete" => "Odstrániť" ); From 9bb8e0583995fff244432bc34820127ef8ff6ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 11:05:00 +0100 Subject: [PATCH 255/315] get all display names --- lib/public/user.php | 10 ++++++++++ lib/user.php | 18 ++++++++++++++++++ lib/user/backend.php | 15 +++++++++++++++ settings/users.php | 15 ++++++++++----- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/lib/public/user.php b/lib/public/user.php index 2d22bdd96c..3a2f4d02f5 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -60,6 +60,16 @@ class User { return \OC_USER::getDisplayName(); } + /** + * @brief Get a list of all display names + * @returns array with all display names and the correspondig uids + * + * Get a list of all display names. + */ + public static function getDisplayNames($search = '', $limit = null, $offset = null) { + return \OC_USER::getDisplayNames($search, $limit, $offset); + } + /** * @brief Check if the user is logged in * @returns true/false diff --git a/lib/user.php b/lib/user.php index f9c8f48568..f84b4c01df 100644 --- a/lib/user.php +++ b/lib/user.php @@ -457,6 +457,24 @@ class OC_User { asort($users); return $users; } + + /** + * @brief Get a list of all users display name + * @returns associative array with all display names and corresponding uids + * + * Get a list of all users. + */ + public static function getDisplayNames($search = '', $limit = null, $offset = null) { + $displayNames = array(); + foreach (self::$_usedBackends as $backend) { + $backendDisplayNames = $backend->getDisplayNames($search, $limit, $offset); + if (is_array($backendDisplayNames)) { + $displayNames = array_merge($displayNames, $backendDisplayNames); + } + } + ksort($displayNames); + return $displayNames; + } /** * @brief check if a user exists diff --git a/lib/user/backend.php b/lib/user/backend.php index 47c92f5fe7..5823e39040 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -131,4 +131,19 @@ abstract class OC_User_Backend implements OC_User_Interface { public function getDisplayName($uid) { return $uid; } + + /** + * @brief Get a list of all display names + * @returns array with all displayNames and the correspondig uids + * + * Get a list of all display names. + */ + public function getDisplayNames($search = '', $limit = null, $offset = null) { + $displayNames = array(); + $users = $this->getUsers($search, $limit, $offset); + foreach ( $users as $user) { + $displayNames[$user] = $user; + } + return $displayNames; + } } diff --git a/settings/users.php b/settings/users.php index 668d974693..3706dc918c 100644 --- a/settings/users.php +++ b/settings/users.php @@ -22,7 +22,7 @@ $isadmin = OC_User::isAdminUser(OC_User::getUser()); if($isadmin) { $accessiblegroups = OC_Group::getGroups(); - $accessibleusers = OC_User::getUsers('', 30); + $accessibleusers = OC_User::getDisplayNames('', 30); $subadmins = OC_SubAdmin::getAllSubAdmins(); }else{ $accessiblegroups = OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()); @@ -42,16 +42,21 @@ $defaultQuota=OC_Appconfig::getValue('files', 'default_quota', 'none'); $defaultQuotaIsUserDefined=array_search($defaultQuota, $quotaPreset)===false && array_search($defaultQuota, array('none', 'default'))===false; // load users and quota -foreach($accessibleusers as $i) { +foreach($accessibleusers as $displayName => $uid) { $quota=OC_Preferences::getValue($i, 'files', 'quota', 'default'); $isQuotaUserDefined=array_search($quota, $quotaPreset)===false && array_search($quota, array('none', 'default'))===false; + $name = $displayName; + if ( $displayName != $uid ) { + $name = $name . ' ('.$uid.')'; + } + $users[] = array( - "name" => $i, - "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($i)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/), + "name" => $name, + "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($uid)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/), 'quota'=>$quota, 'isQuotaUserDefined'=>$isQuotaUserDefined, - 'subadmin'=>implode(', ', OC_SubAdmin::getSubAdminsGroups($i))); + 'subadmin'=>implode(', ', OC_SubAdmin::getSubAdminsGroups($iuid))); } foreach( $accessiblegroups as $i ) { From 4271430e609be252d9b4a69fd7b3590571c14f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 11:48:03 +0100 Subject: [PATCH 256/315] get all display names from users in a given group --- lib/group.php | 29 +++++++++++++++++++++++++++++ lib/group/backend.php | 18 ++++++++++++++++++ lib/public/user.php | 4 ++-- lib/user.php | 4 ++-- lib/user/backend.php | 4 ++-- settings/users.php | 2 +- 6 files changed, 54 insertions(+), 7 deletions(-) diff --git a/lib/group.php b/lib/group.php index ed9482418b..8ebb698692 100644 --- a/lib/group.php +++ b/lib/group.php @@ -286,4 +286,33 @@ class OC_Group { } return $users; } + + /** + * @brief get a list of all display names in a group + * @returns array with display names (key) and user ids(value) + */ + public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + $displayNames=array(); + foreach(self::$_usedBackends as $backend) { + $displayNames = array_merge($backend->displayNamesInGroup($gid, $search, $limit, $offset), $displayNames); + } + return $displayNames; + } + + /** + * @brief get a list of all display names in several groups + * @param array $gids + * @param string $search + * @param int $limit + * @param int $offset + * @return array with display names (Key) user ids (value) + */ + public static function displayNamesInGroups($gids, $search = '', $limit = -1, $offset = 0) { + $displayNames = array(); + foreach ($gids as $gid) { + // TODO Need to apply limits to groups as total + $displayNames = array_merge(array_diff(self::displayNamesInGroup($gid, $search, $limit, $offset), $displayNames), $displayNames); + } + return $displayNames; + } } diff --git a/lib/group/backend.php b/lib/group/backend.php index 9ff432d066..ceb2d9242d 100644 --- a/lib/group/backend.php +++ b/lib/group/backend.php @@ -133,5 +133,23 @@ abstract class OC_Group_Backend implements OC_Group_Interface { public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { return array(); } + + /** + * @brief get a list of all display names in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return array with display names (key) and user ids (value) + */ + public function DisplayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + $displayNames = ''; + $users = $this->usersInGroup($gid, $search, $limit, $offset); + foreach ( $users as $user ) { + $DisplayNames[$user] = $user; + } + + return $DisplayNames; + } } diff --git a/lib/public/user.php b/lib/public/user.php index 3a2f4d02f5..a93e3a674a 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -62,9 +62,9 @@ class User { /** * @brief Get a list of all display names - * @returns array with all display names and the correspondig uids + * @returns array with all display names (key) and the correspondig uids (value) * - * Get a list of all display names. + * Get a list of all display names and user ids. */ public static function getDisplayNames($search = '', $limit = null, $offset = null) { return \OC_USER::getDisplayNames($search, $limit, $offset); diff --git a/lib/user.php b/lib/user.php index f84b4c01df..4cdf07dc3f 100644 --- a/lib/user.php +++ b/lib/user.php @@ -460,9 +460,9 @@ class OC_User { /** * @brief Get a list of all users display name - * @returns associative array with all display names and corresponding uids + * @returns associative array with all display names (key) and corresponding uids (value) * - * Get a list of all users. + * Get a list of all display names and user ids. */ public static function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = array(); diff --git a/lib/user/backend.php b/lib/user/backend.php index 5823e39040..ec43d7f187 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -134,9 +134,9 @@ abstract class OC_User_Backend implements OC_User_Interface { /** * @brief Get a list of all display names - * @returns array with all displayNames and the correspondig uids + * @returns array with all displayNames (key) and the correspondig uids (value) * - * Get a list of all display names. + * Get a list of all display names and user ids. */ public function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = array(); diff --git a/settings/users.php b/settings/users.php index 3706dc918c..bf27e80441 100644 --- a/settings/users.php +++ b/settings/users.php @@ -26,7 +26,7 @@ if($isadmin) { $subadmins = OC_SubAdmin::getAllSubAdmins(); }else{ $accessiblegroups = OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()); - $accessibleusers = OC_Group::usersInGroups($accessiblegroups, '', 30); + $accessibleusers = OC_Group::displayNamesInGroups($accessiblegroups, '', 30); $subadmins = false; } From 64e853394c120888a7555901a52c5868f33aef3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 12:46:32 +0100 Subject: [PATCH 257/315] compare the correct uids --- settings/templates/users.php | 2 +- settings/users.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/settings/templates/users.php b/settings/templates/users.php index 6cbbca2404..44e9b5bafe 100644 --- a/settings/templates/users.php +++ b/settings/templates/users.php @@ -157,7 +157,7 @@ var isadmin = ;
                - + diff --git a/settings/users.php b/settings/users.php index bf27e80441..c8f5ef5ff3 100644 --- a/settings/users.php +++ b/settings/users.php @@ -53,6 +53,7 @@ foreach($accessibleusers as $displayName => $uid) { $users[] = array( "name" => $name, + "uid" => $uid, "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($uid)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/), 'quota'=>$quota, 'isQuotaUserDefined'=>$isQuotaUserDefined, From b4291f1e8e2326f5f1cbd97fa130d547f949b62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 13:00:17 +0100 Subject: [PATCH 258/315] allow to get the display name from an abitrary user --- lib/public/user.php | 4 ++-- lib/user.php | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/public/user.php b/lib/public/user.php index a93e3a674a..411098ed5a 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -56,8 +56,8 @@ class User { * @brief get the user display name of the user currently logged in. * @return string display name */ - public static function getDisplayName() { - return \OC_USER::getDisplayName(); + public static function getDisplayName($user=null) { + return \OC_USER::getDisplayName($user); } /** diff --git a/lib/user.php b/lib/user.php index 4cdf07dc3f..65f899aa27 100644 --- a/lib/user.php +++ b/lib/user.php @@ -350,8 +350,10 @@ class OC_User { * @brief get the display name of the user currently logged in. * @return string uid or false */ - public static function getDisplayName() { - if( isset($_SESSION['display_name']) AND $_SESSION['display_name'] ) { + public static function getDisplayName($user=null) { + if ( $user ) { + return self::determineDisplayName($user); + } else if( isset($_SESSION['display_name']) AND $_SESSION['display_name'] ) { return $_SESSION['display_name']; } else{ From 839f4bd94916d0673341528ffa8a2a7b3242bf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 13:01:53 +0100 Subject: [PATCH 259/315] show display name instead of uid in the public shared files view --- apps/files_sharing/public.php | 1 + apps/files_sharing/templates/public.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index efd977a1b6..93f3b4da2b 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -207,6 +207,7 @@ if ($linkItem) { OCP\Util::addScript('files', 'fileactions'); $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('uidOwner', $shareOwner); + $tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner)); $tmpl->assign('dir', $dir); $tmpl->assign('filename', $file); $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 647e1e08a3..13af528ce8 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -14,9 +14,9 @@ ownCloud
                - t('%s shared the folder %s with you', array($_['uidOwner'], $_['filename'])) ?> + t('%s shared the folder %s with you', array($_['displayName'], $_['filename'])) ?> - t('%s shared the file %s with you', array($_['uidOwner'], $_['filename'])) ?> + t('%s shared the file %s with you', array($_['displayName'], $_['filename'])) ?> Download" />t('Download')?> From e9a57e28fc9b87c0fd84de39a0e4cb305165a9d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 13:57:08 +0100 Subject: [PATCH 260/315] show display name instead of uid --- core/ajax/share.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/core/ajax/share.php b/core/ajax/share.php index 077baa8ba5..231cdc5e24 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -72,6 +72,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo case 'email': // read post variables $user = OCP\USER::getUser(); + $displayName = OCP\User::getDisplayName(); $type = $_POST['itemType']; $link = $_POST['link']; $file = $_POST['file']; @@ -81,13 +82,13 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo $l = OC_L10N::get('core'); // setup the email - $subject = (string)$l->t('User %s shared a file with you', $user); + $subject = (string)$l->t('User %s shared a file with you', $displayName); if ($type === 'dir') - $subject = (string)$l->t('User %s shared a folder with you', $user); + $subject = (string)$l->t('User %s shared a folder with you', $displayName); - $text = (string)$l->t('User %s shared the file "%s" with you. It is available for download here: %s', array($user, $file, $link)); + $text = (string)$l->t('User %s shared the file "%s" with you. It is available for download here: %s', array($displayName, $file, $link)); if ($type === 'dir') - $text = (string)$l->t('User %s shared the folder "%s" with you. It is available for download here: %s', array($user, $file, $link)); + $text = (string)$l->t('User %s shared the folder "%s" with you. It is available for download here: %s', array($displayName, $file, $link)); $default_from = OCP\Util::getDefaultEmailAddress('sharing-noreply'); @@ -158,14 +159,14 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo while ($count < 4 && count($users) == $limit) { $limit = 4 - $count; if ($sharePolicy == 'groups_only') { - $users = OC_Group::usersInGroups($groups, $_GET['search'], $limit, $offset); + $users = OC_Group::DisplayNamesInGroups($groups, $_GET['search'], $limit, $offset); } else { - $users = OC_User::getUsers($_GET['search'], $limit, $offset); + $users = OC_User::getDisplayNames($_GET['search'], $limit, $offset); } $offset += $limit; - foreach ($users as $user) { - if ((!isset($_GET['itemShares']) || !is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]) || !in_array($user, $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])) && $user != OC_User::getUser()) { - $shareWith[] = array('label' => $user, 'value' => array('shareType' => OCP\Share::SHARE_TYPE_USER, 'shareWith' => $user)); + foreach ($users as $displayName => $uid) { + if ((!isset($_GET['itemShares']) || !is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]) || !in_array($uid, $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])) && $uid != OC_User::getUser()) { + $shareWith[] = array('label' => $displayName, 'value' => array('shareType' => OCP\Share::SHARE_TYPE_USER, 'shareWith' => $uid)); $count++; } } From e5cc5a0a2d287e0acfd754c79f4f05785ea9a201 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 25 Jan 2013 14:26:14 +0100 Subject: [PATCH 261/315] Allow the loading of external images --- config/config.sample.php | 2 +- lib/template.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 18b7532e8f..864c66f7e3 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -105,7 +105,7 @@ $CONFIG = array( "remember_login_cookie_lifetime" => 60*60*24*15, /* Custom CSP policy, changing this will overwrite the standard policy */ -"custom_csp_policy" => "default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; frame-src *", +"custom_csp_policy" => "default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; frame-src *; img-src *", /* The directory where the user data is stored, default to data in the owncloud * directory. The sqlite database is also stored here, when sqlite is used. diff --git a/lib/template.php b/lib/template.php index a545d91f3c..da757a0866 100644 --- a/lib/template.php +++ b/lib/template.php @@ -192,7 +192,7 @@ class OC_Template{ // Content Security Policy // If you change the standard policy, please also change it in config.sample.php - $policy = OC_Config::getValue('custom_csp_policy', 'default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; frame-src *'); + $policy = OC_Config::getValue('custom_csp_policy', 'default-src \'self\'; script-src \'self\' \'unsafe-eval\'; style-src \'self\' \'unsafe-inline\'; frame-src *; img-src *'); header('Content-Security-Policy:'.$policy); // Standard header('X-WebKit-CSP:'.$policy); // Older webkit browsers header('X-Content-Security-Policy:'.$policy); // Mozilla + Internet Explorer From 0d2a58bc5de41cc0af70c231e274d4c3e8972c25 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 25 Jan 2013 14:57:52 +0100 Subject: [PATCH 262/315] Initialize router also if ownCloud isn't installed --- lib/base.php | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/base.php b/lib/base.php index 3bd998de3a..f1a60a1773 100644 --- a/lib/base.php +++ b/lib/base.php @@ -541,22 +541,6 @@ class OC */ public static function handleRequest() { - if (!OC_Config::getValue('installed', false)) { - require_once 'core/setup.php'; - exit(); - } - // Handle redirect URL for logged in users - if (isset($_REQUEST['redirect_url']) && OC_User::isLoggedIn()) { - $location = OC_Helper::makeURLAbsolute(urldecode($_REQUEST['redirect_url'])); - header('Location: ' . $location); - return; - } - // Handle WebDAV - if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') { - header('location: ' . OC_Helper::linkToRemote('webdav')); - return; - } - // load all the classpaths from the enabled apps so they are available // in the routing files of each app OC::loadAppClassPaths(); @@ -578,6 +562,24 @@ class OC self::loadCSSFile($param); return; } + + if (!OC_Config::getValue('installed', false)) { + require_once 'core/setup.php'; + exit(); + } + + // Handle redirect URL for logged in users + if (isset($_REQUEST['redirect_url']) && OC_User::isLoggedIn()) { + $location = OC_Helper::makeURLAbsolute(urldecode($_REQUEST['redirect_url'])); + header('Location: ' . $location); + return; + } + // Handle WebDAV + if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') { + header('location: ' . OC_Helper::linkToRemote('webdav')); + return; + } + // Someone is logged in : if (OC_User::isLoggedIn()) { OC_App::loadApps(); From ff4d62132af1950c77a6fb56bc16e3cc9d3a83a0 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 25 Jan 2013 15:47:57 +0100 Subject: [PATCH 263/315] This breaks the installation @bartv2 This JS part is breaking the installation (POST parameters are not transferred), could you please take a look? THX. JS console says: uncaught exception: cannot call methods on button prior to initialization; attempted to call method 'disable' --- core/js/setup.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/js/setup.js b/core/js/setup.js index 39fcf4a271..9aded6591c 100644 --- a/core/js/setup.js +++ b/core/js/setup.js @@ -52,11 +52,12 @@ $(document).ready(function() { // Save form parameters var post = $(this).serializeArray(); + // FIXME: This lines are breaking the installation // Disable inputs - $(':submit', this).attr('disabled','disabled').val('Finishing …'); - $('input', this).addClass('ui-state-disabled').attr('disabled','disabled'); - $('#selectDbType').button('disable'); - $('label.ui-button', this).addClass('ui-state-disabled').attr('aria-disabled', 'true').button('disable'); + // $(':submit', this).attr('disabled','disabled').val('Finishing …'); + // $('input', this).addClass('ui-state-disabled').attr('disabled','disabled'); + // $('#selectDbType').button('disable'); + // $('label.ui-button', this).addClass('ui-state-disabled').attr('aria-disabled', 'true').button('disable'); // Create the form var form = $('
                '); From 936e991394d8984bde69ce6878cb67f268456173 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Fri, 25 Jan 2013 16:00:26 +0100 Subject: [PATCH 264/315] Add js linkToRemote and linkToRemoteBase --- core/js/js.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/js/js.js b/core/js/js.js index 6241036b1b..6e0a405114 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -100,6 +100,27 @@ var OC={ linkTo:function(app,file){ return OC.filePath(app,'',file); }, + /** + * Creates an url for remote use + * @param string $service id + * @return string the url + * + * Returns a url to the given service. + */ + linkToRemoteBase:function(service) { + return OC.webroot + '/remote.php/' + service; + }, + /** + * @brief Creates an absolute url for remote use + * @param string $service id + * @param bool $add_slash + * @return string the url + * + * Returns a absolute url to the given service. + */ + linkToRemote:function(service) { + return window.location.protocol + '//' + window.location.host + OC.linkToRemoteBase(service); + }, /** * get the absolute url for a file in an app * @param app the id of the app From bc9ab0726efb591e3a42c3058a204d401cb1b68d Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Fri, 25 Jan 2013 15:57:57 +0100 Subject: [PATCH 265/315] add smart app banner to promote ios app --- core/templates/layout.guest.php | 1 + core/templates/layout.user.php | 1 + 2 files changed, 2 insertions(+) diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php index 5b39503474..fd29b3ab36 100644 --- a/core/templates/layout.guest.php +++ b/core/templates/layout.guest.php @@ -3,6 +3,7 @@ ownCloud + diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index a16d2c9e55..5860b1ab14 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -3,6 +3,7 @@ <?php echo isset($_['application']) && !empty($_['application'])?$_['application'].' | ':'' ?>ownCloud <?php echo OC_User::getUser()?' ('.OC_User::getUser().') ':'' ?> + From d8c4e620afcfc104b30a325a17671b1207e95ffc Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 25 Jan 2013 16:23:03 +0100 Subject: [PATCH 266/315] Use black background images --- core/css/jquery-ui-1.10.0.custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/css/jquery-ui-1.10.0.custom.css b/core/css/jquery-ui-1.10.0.custom.css index 71b3979aa8..a1e9895c77 100644 --- a/core/css/jquery-ui-1.10.0.custom.css +++ b/core/css/jquery-ui-1.10.0.custom.css @@ -931,7 +931,7 @@ body .ui-tooltip { background-image: url(images/ui-icons_222222_256x240.png); } .ui-widget-header .ui-icon { - background-image: url(images/ui-icons_ffffff_256x240.png); + background-image: url(images/ui-icons_222222_256x240.png); } .ui-state-default .ui-icon { background-image: url(images/ui-icons_1d2d44_256x240.png); From 9f5847b739c20a0b2de3672459445f08300ef790 Mon Sep 17 00:00:00 2001 From: TheSFReader Date: Fri, 25 Jan 2013 17:02:44 +0100 Subject: [PATCH 267/315] Simplify the code and remove a first unnecessary (and non conform) '&' character when there are pending arguments --- lib/helper.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/helper.php b/lib/helper.php index 5d7e3fa489..540a7dceb3 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -78,11 +78,8 @@ class OC_Helper { } } - if (!empty($args)) { - $urlLinkTo .= '?'; - foreach($args as $k => $v) { - $urlLinkTo .= '&'.$k.'='.urlencode($v); - } + if ($args && $query = http_build_query($args, '', '&')) { + $urlLinkTo .= '?'.$query; } return $urlLinkTo; From a606e8d944f7c2754f00e9c50804b8c2beedc986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 17:40:23 +0100 Subject: [PATCH 268/315] use display name to show share_width and owner information --- core/js/share.js | 18 +++++++++--------- lib/public/share.php | 9 +++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/core/js/share.js b/core/js/share.js index bb3ec010ff..1486d7f177 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -148,9 +148,9 @@ OC.Share={ var html = '