[
  {
    "path": ".gitattributes",
    "content": "# Set default behaviour, in case users don't have core.autocrlf set.\n* text=auto\n\n# Explicitly declare text files we want to always be normalized and converted \n# to native line endings on checkout.\n*.php text eol=lf\n*.js text eol=lf\n*.css text eol=lf\n*.html text eol=lf\n*.xml text eol=lf\n\n# Denote all files that are truly binary and should not be modified.\n*.png binary\n*.jpg binary\n\n"
  },
  {
    "path": ".gitignore",
    "content": ".*.swp\n.*.swo\n._*\n.DS_Store\n/Debug/\n/ImgCache/\n/Backup_rar/\n/Debug/\n/debug/\n/upload/\n/avatar/\n/.idea/\n.svn/\n*.orig\n*.aps\n*.APS\n*.chm\n*.exp\n*.pdb\n*.rar\n.smbdelete*\n*.sublime*\n.sass-cache\nconfig.rb\n/config.inc.php\n/usr/uploads/\n"
  },
  {
    "path": "Akismet/Plugin.php",
    "content": "<?php\n/**\n * Akismet 反垃圾评论插件 for Typecho\n * \n * @package Akismet\n * @author qining\n * @version 1.1.4\n * @link http://typecho.org\n */\nclass Akismet_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        if (false == Typecho_Http_Client::get()) {\n            throw new Typecho_Plugin_Exception(_t('对不起, 您的主机不支持 php-curl 扩展而且没有打开 allow_url_fopen 功能, 无法正常使用此功能'));\n        }\n    \n        Typecho_Plugin::factory('Widget_Feedback')->comment = array('Akismet_Plugin', 'filter');\n        Typecho_Plugin::factory('Widget_Feedback')->trackback = array('Akismet_Plugin', 'filter');\n        Typecho_Plugin::factory('Widget_XmlRpc')->pingback = array('Akismet_Plugin', 'filter');\n        Typecho_Plugin::factory('Widget_Comments_Edit')->mark = array('Akismet_Plugin', 'mark');\n        \n        return _t('请配置此插件的API KEY, 以使您的反垃圾策略生效');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $key = new Typecho_Widget_Helper_Form_Element_Textarea('key', NULL, NULL, _t('服务密钥'), _t('此密钥需要向服务提供商注册<br />\n        它是一个用于表明您合法用户身份的字符串'));\n        $form->addInput($key->addRule('required', _t('您必须填写一个服务密钥'))\n        ->addRule(array('Akismet_Plugin', 'validate'), _t('您使用的服务密钥错误')));\n        \n        $url = new Typecho_Widget_Helper_Form_Element_Text('url', NULL, 'http://rest.akismet.com',\n        _t('服务地址'), _t('这是反垃圾评论服务提供商的服务器地址<br />\n        我们推荐您使用 <a href=\"http://akismet.com\">Akismet</a> 或者 <a href=\"http://antispam.typepad.com\">Typepad</a> 的反垃圾服务'));\n        $form->addInput($url->addRule('url', _t('您使用的地址格式错误')));\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 验证api的key值\n     * \n     * @access public\n     * @param string $key 服务密钥\n     * @return boolean\n     */\n    public static function validate($key)\n    {\n        $options = Typecho_Widget::widget('Widget_Options');\n        $url = Typecho_Request::getInstance()->url;\n        \n        $data = array(\n            'key'   =>  $key,\n            'blog'  =>  $options->siteUrl\n        );\n        \n        $client = Typecho_Http_Client::get('Curl', 'Socket');\n        if (false != $client) {\n            $client->setData($data)\n            ->setHeader('User-Agent', $options->generator . ' | Akismet/1.1')\n            ->send(Typecho_Common::url('/1.1/verify-key', $url));\n            \n            if ('valid' == $client->getResponseBody()) {\n                return true;\n            }\n        }\n        \n        return false;\n    }\n    \n    /**\n     * 标记评论状态时的插件接口\n     * \n     * @access public\n     * @param array $comment 评论数据的结构体\n     * @param Typecho_Widget $commentWidget 评论组件\n     * @param string $status 评论状态\n     * @return void\n     */\n    public static function mark($comment, $commentWidget, $status)\n    {\n        if ('spam' == $comment['status'] && $status != 'spam') {\n            self::filter($comment, $commentWidget, NULL, 'submit-ham');\n        } else if ('spam' != $comment['status'] && $status == 'spam') {\n            self::filter($comment, $commentWidget, NULL, 'submit-spam');\n        }\n    }\n    \n    /**\n     * 评论过滤器\n     * \n     * @access public\n     * @param array $comment 评论结构\n     * @param Typecho_Widget $post 被评论的文章\n     * @param array $result 返回的结果上下文\n     * @param string $api api地址\n     * @return void\n     */\n    public static function filter($comment, $post, $result, $api = 'comment-check')\n    {\n        $comment = empty($result) ? $comment : $result;\n    \n        $options = Typecho_Widget::widget('Widget_Options');\n        $url = $options->plugin('Akismet')->url;\n        $key = $options->plugin('Akismet')->key;\n        \n        $allowedServerVars = 'comment-check' == $api ? array(\n            'SCRIPT_URI',\n            'HTTP_HOST',\n            'HTTP_USER_AGENT',\n            'HTTP_ACCEPT',\n            'HTTP_ACCEPT_LANGUAGE',\n            'HTTP_ACCEPT_ENCODING',\n            'HTTP_ACCEPT_CHARSET',\n            'HTTP_KEEP_ALIVE',\n            'HTTP_CONNECTION',\n            'HTTP_CACHE_CONTROL',\n            'HTTP_PRAGMA',\n            'HTTP_DATE',\n            'HTTP_EXPECT',\n            'HTTP_MAX_FORWARDS',\n            'HTTP_RANGE',\n            'CONTENT_TYPE',\n            'CONTENT_LENGTH',\n            'SERVER_SIGNATURE',\n            'SERVER_SOFTWARE',\n            'SERVER_NAME',\n            'SERVER_ADDR',\n            'SERVER_PORT',\n            'REMOTE_PORT',\n            'GATEWAY_INTERFACE',\n            'SERVER_PROTOCOL',\n            'REQUEST_METHOD',\n            'QUERY_STRING',\n            'REQUEST_URI',\n            'SCRIPT_NAME',\n            'REQUEST_TIME'\n        ) : array();\n        \n        $data = array(\n            'blog'                  =>  $options->siteUrl,\n            'user_ip'               =>  $comment['ip'],\n            'user_agent'            =>  $comment['agent'],\n            'referrer'              =>  Typecho_Request::getInstance()->getReferer(),\n            'permalink'             =>  $post->permalink,\n            'comment_type'          =>  $comment['type'],\n            'comment_author'        =>  $comment['author'],\n            'comment_author_email'  =>  $comment['mail'],\n            'comment_author_url'    =>  $comment['url'],\n            'comment_content'       =>  $comment['text']\n        );\n        \n        foreach ($allowedServerVars as $val) {\n            if (array_key_exists($val, $_SERVER)) {\n                $data[$val] = $_SERVER[$val];\n            }\n        }\n\n        try {\n            $client = Typecho_Http_Client::get();\n            if (false != $client && $key) {\n                $params = parse_url($url);\n                $url = $params['scheme'] . '://' . $key . '.' . $params['host'] . (isset($params['path']) ? $params['path'] : NULL);\n\n                $client->setHeader('User-Agent', $options->generator . ' | Akismet/1.1')\n                ->setTimeout(5)\n                ->setData($data)\n                ->send(Typecho_Common::url('/1.1/' . $api, $url));\n\n                if ('true' == $client->getResponseBody()) {\n                    $comment['status'] = 'spam';\n                }\n            }\n        } catch (Typecho_Http_Client_Exception $e) {\n            //do nothing\n            error_log($e->getMessage());\n        }\n        \n        return $comment;\n    }\n}\n"
  },
  {
    "path": "AliUpload/Plugin.php",
    "content": "<?php\n\nif(!defined('OSS_API_PATH'))\ndefine('OSS_API_PATH', dirname(__FILE__));\n\n//ACCESS_ID\ndefine('OSS_ACCESS_ID', '');\n\n//ACCESS_KEY\ndefine('OSS_ACCESS_KEY', '');\n\n//是否记录日志\ndefine('ALI_LOG', FALSE);\n\n//自定义日志路径，如果没有设置，则使用系统默认路径，在./logs/\ndefine('ALI_LOG_PATH',OSS_API_PATH.'/logs/');\n\n//是否显示LOG输出\ndefine('ALI_DISPLAY_LOG', FALSE);\n\nrequire_once 'lib/sdk.class.php';\n\n\n\n/**\n * <a href=\"http://loftor.com/\" target=\"_blank\">Alioss</a>专用的文件上传插件。\n * \n * @package AliUpload\n * @author loftor\n * @version 1.0.0 Beta\n * @link http://loftor.com/\n */\nclass AliUpload_Plugin implements Typecho_Plugin_Interface\n{\n\n    //上传文件目录\n    const UPLOAD_PATH = 'usr/uploads';\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Upload')->uploadHandle = array('AliUpload_Plugin', 'uploadHandle');\n        Typecho_Plugin::factory('Widget_Upload')->modifyHandle = array('AliUpload_Plugin', 'modifyHandle');\n        Typecho_Plugin::factory('Widget_Upload')->deleteHandle = array('AliUpload_Plugin', 'deleteHandle');\n        Typecho_Plugin::factory('Widget_Upload')->attachmentHandle = array('AliUpload_Plugin', 'attachmentHandle');\n        Typecho_Plugin::factory('Widget_Upload')->attachmentDataHandle = array('AliUpload_Plugin', 'attachmentDataHandle');\n        \n        return _t('启用成功，请进行相应设置！');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $buketName = new Typecho_Widget_Helper_Form_Element_Text('bucket', NULL, 'loftor',\n            _t('Bucket名称'), _t('请填写Buket名称!'));\n        $form->addInput($buketName);\n\n        $accessID = new Typecho_Widget_Helper_Form_Element_Text('access_id', NULL, '',\n            _t('ACCESS_ID'), _t('请填写ACCESS_ID!'));\n        $form->addInput($accessID);\n\n        $accessKEY = new Typecho_Widget_Helper_Form_Element_Text('access_key', NULL, '',\n            _t('ACCESS_KEY'), _t('请填写请填写ACCESS_KEY!'));\n        $form->addInput($accessKEY);\n\n        $domianName = new Typecho_Widget_Helper_Form_Element_Text('domian', NULL, 'http://oss.loftor.com/',\n            _t('域名名称'), _t('请填写域名名称!'));\n        $form->addInput($domianName);\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n\n    /**\n     * 上传文件处理函数\n     *\n     * @access public\n     * @param array $file 上传的文件\n     * @return mixed\n     */\n    public static function uploadHandle($file)\n    {\n\n\n        if (empty($file['name'])) {\n            return false;\n        }\n\n        $fileName = preg_split(\"(\\/|\\\\|:)\", $file['name']);\n        $file['name'] = array_pop($fileName);\n        \n        //获取扩展名\n        $ext = '';\n        $part = explode('.', $file['name']);\n        if (($length = count($part)) > 1) {\n            $ext = strtolower($part[$length - 1]);\n        }\n\n        if (!self::checkFileType($ext)) {\n            return false;\n        }\n\n        $options = Typecho_Widget::widget('Widget_Options');\n        $date = new Typecho_Date($options->gmtTime);\n        $path = self::UPLOAD_PATH;\n\n\n        $options = Typecho_Widget::widget('Widget_Options');\n\n        $access_id=$options->plugin('AliUpload')->access_id;\n        $access_key=$options->plugin('AliUpload')->access_key;\n        $bucket = $options->plugin('AliUpload')->bucket;\n\n        $oss_service = new ALIOSS($access_id,$access_key);\n\n        $path = $path . '/' . $date->year . '/' . $date->month;\n\n        //获取文件名\n        $fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext;\n        $path = $path . '/' . $fileName;//add for mkdir\n\n        $response;\n        if (isset($file['tmp_name'])) {\n            //移动上传文件\n            $response = $oss_service->upload_file_by_file($bucket,$path,$file['tmp_name']);\n\n            if (!$response->isOk()) {\n                return false;\n            }\n        } else if (isset($file['bits'])) {\n            //直接写入文件\n            $upload_file_options = array(\n                'content' => $file['bits'],\n                'length' => strlen($file['bits'])\n                );\n\n            $response = $oss_service->upload_file_by_content($bucket,$path,$upload_file_options);\n\n            if (!$response->isOk()) {\n                return false;\n            }\n        } else {\n            return false;\n        }\n\n        if (!isset($file['size'])) {\n\n            $file['size'] = $response->header['_info']['size_upload'];\n        }\n\n        $path=$response->header['x-oss-request-url'];\n\n        //返回相对存储路径\n        return array(\n            'name' => $file['name'],\n            'path' => self::UPLOAD_PATH . '/' . $date->year . '/' . $date->month . '/' . $fileName,\n            'size' => $file['size'],\n            'type' => $ext,\n            'mime' => self::mimeContentType($ext)\n            );\n    }\n\n    /**\n     * 修改文件处理函数\n     *\n     * @access public\n     * @param array $content 老文件\n     * @param array $file 新上传的文件\n     * @return mixed\n     */\n    public static function modifyHandle($content, $file)\n    {\n\n        if (empty($file['name'])) {\n            return false;\n        }\n\n        $fileName = preg_split(\"(\\/|\\\\|:)\", $file['name']);\n        $file['name'] = array_pop($fileName);\n        \n        //获取扩展名\n        $ext = '';\n        $part = explode('.', $file['name']);\n        if (($length = count($part)) > 1) {\n            $ext = strtolower($part[$length - 1]);\n        }\n\n        if ($content['attachment']->type != $ext) {\n            return false;\n        }\n\n        //获取文件名\n        $fileName = $content['attachment']->path;\n        $path = $path . '/' . $fileName;//add for mkdir\n        $path=substr($path, 1);\n\n        $options = Typecho_Widget::widget('Widget_Options');\n\n        $access_id=$options->plugin('AliUpload')->access_id;\n        $access_key=$options->plugin('AliUpload')->access_key;\n        $bucket = $options->plugin('AliUpload')->bucket;\n\n        $oss_service = new ALIOSS($access_id,$access_key);\n\n        \n\n        if (isset($file['tmp_name'])) {\n            //移动上传文件\n            $response = $oss_service->upload_file_by_file($bucket,$path,$file['tmp_name']);\n            if (!$response->isOk()) {\n                return false;\n            }\n        } else if (isset($file['bits'])) {\n            //直接写入文件\n            $upload_file_options = array(\n                'content' => $file['bits'],\n                'length' => strlen($file['bits'])\n                );\n\n            $response = $oss_service->upload_file_by_content($bucket,$path,$upload_file_options);\n\n            if (!$response->isOk()) {\n                return false;\n            }\n        } else {\n            return false;\n        }\n\n        if (!isset($file['size'])) {\n            $file['size'] = $response->header['_info']['size_upload'];\n        }\n\n        //返回相对存储路径\n        return array(\n            'name' => $content['attachment']->name,\n            'path' => $content['attachment']->path,\n            'size' => $file['size'],\n            'type' => $content['attachment']->type,\n            'mime' => $content['attachment']->mime\n            );\n    }\n\n    /**\n     * 删除文件\n     *\n     * @access public\n     * @param array $content 文件相关信息\n     * @return string\n     */\n    public static function deleteHandle(array $content)\n    {\n        $options = Typecho_Widget::widget('Widget_Options');\n\n        $access_id=$options->plugin('AliUpload')->access_id;\n        $access_key=$options->plugin('AliUpload')->access_key;\n        $bucket = $options->plugin('AliUpload')->bucket;\n\n        $oss_service = new ALIOSS($access_id,$access_key);\n\n        $response = $oss_service->delete_object($bucket,$content['attachment']->path);\n        return $response->isOk();\n    }\n\n    /**\n     * 获取实际文件绝对访问路径\n     *\n     * @access public\n     * @param array $content 文件相关信息\n     * @return string\n     */\n    public static function attachmentHandle(array $content)\n    {\n        $options = Typecho_Widget::widget('Widget_Options');\n        $domian = $options->plugin('AliUpload')->domian;\n        return $domian.$content['attachment']->path;\n    }\n\n    /**\n     * 获取实际文件数据\n     *\n     * @access public\n     * @param array $content\n     * @return string\n     */\n    public static function attachmentDataHandle(array $content)\n    {\n        $options = Typecho_Widget::widget('Widget_Options');\n        $domian = $options->plugin('AliUpload')->domian;\n        return file_get_contents($domian.$content['attachment']->path);\n    }\n\n    /**\n     * 检查文件名\n     *\n     * @access private\n     * @param string $ext 扩展名\n     * @return boolean\n     */\n    public static function checkFileType($ext)\n    {\n        $options = Typecho_Widget::widget('Widget_Options');\n        return in_array($ext, $options->allowedAttachmentTypes);\n    }\n\n    /**\n     * 获取图片\n     *\n     * @access public\n     * @param string $fileName 文件名\n     * @return string\n     */\n    public static function mimeContentType($ext)\n    {\n        $mimeTypes = array(\n          'ez' => 'application/andrew-inset',\n          'csm' => 'application/cu-seeme',\n          'cu' => 'application/cu-seeme',\n          'tsp' => 'application/dsptype',\n          'spl' => 'application/x-futuresplash',\n          'hta' => 'application/hta',\n          'cpt' => 'image/x-corelphotopaint',\n          'hqx' => 'application/mac-binhex40',\n          'nb' => 'application/mathematica',\n          'mdb' => 'application/msaccess',\n          'doc' => 'application/msword',\n          'dot' => 'application/msword',\n          'bin' => 'application/octet-stream',\n          'oda' => 'application/oda',\n          'ogg' => 'application/ogg',\n          'prf' => 'application/pics-rules',\n          'key' => 'application/pgp-keys',\n          'pdf' => 'application/pdf',\n          'pgp' => 'application/pgp-signature',\n          'ps' => 'application/postscript',\n          'ai' => 'application/postscript',\n          'eps' => 'application/postscript',\n          'rss' => 'application/rss+xml',\n          'rtf' => 'text/rtf',\n          'smi' => 'application/smil',\n          'smil' => 'application/smil',\n          'wp5' => 'application/wordperfect5.1',\n          'xht' => 'application/xhtml+xml',\n          'xhtml' => 'application/xhtml+xml',\n          'zip' => 'application/zip',\n          'cdy' => 'application/vnd.cinderella',\n          'mif' => 'application/x-mif',\n          'xls' => 'application/vnd.ms-excel',\n          'xlb' => 'application/vnd.ms-excel',\n          'cat' => 'application/vnd.ms-pki.seccat',\n          'stl' => 'application/vnd.ms-pki.stl',\n          'ppt' => 'application/vnd.ms-powerpoint',\n          'pps' => 'application/vnd.ms-powerpoint',\n          'pot' => 'application/vnd.ms-powerpoint',\n          'sdc' => 'application/vnd.stardivision.calc',\n          'sda' => 'application/vnd.stardivision.draw',\n          'sdd' => 'application/vnd.stardivision.impress',\n          'sdp' => 'application/vnd.stardivision.impress',\n          'smf' => 'application/vnd.stardivision.math',\n          'sdw' => 'application/vnd.stardivision.writer',\n          'vor' => 'application/vnd.stardivision.writer',\n          'sgl' => 'application/vnd.stardivision.writer-global',\n          'sxc' => 'application/vnd.sun.xml.calc',\n          'stc' => 'application/vnd.sun.xml.calc.template',\n          'sxd' => 'application/vnd.sun.xml.draw',\n          'std' => 'application/vnd.sun.xml.draw.template',\n          'sxi' => 'application/vnd.sun.xml.impress',\n          'sti' => 'application/vnd.sun.xml.impress.template',\n          'sxm' => 'application/vnd.sun.xml.math',\n          'sxw' => 'application/vnd.sun.xml.writer',\n          'sxg' => 'application/vnd.sun.xml.writer.global',\n          'stw' => 'application/vnd.sun.xml.writer.template',\n          'sis' => 'application/vnd.symbian.install',\n          'wbxml' => 'application/vnd.wap.wbxml',\n          'wmlc' => 'application/vnd.wap.wmlc',\n          'wmlsc' => 'application/vnd.wap.wmlscriptc',\n          'wk' => 'application/x-123',\n          'dmg' => 'application/x-apple-diskimage',\n          'bcpio' => 'application/x-bcpio',\n          'torrent' => 'application/x-bittorrent',\n          'cdf' => 'application/x-cdf',\n          'vcd' => 'application/x-cdlink',\n          'pgn' => 'application/x-chess-pgn',\n          'cpio' => 'application/x-cpio',\n          'csh' => 'text/x-csh',\n          'deb' => 'application/x-debian-package',\n          'dcr' => 'application/x-director',\n          'dir' => 'application/x-director',\n          'dxr' => 'application/x-director',\n          'wad' => 'application/x-doom',\n          'dms' => 'application/x-dms',\n          'dvi' => 'application/x-dvi',\n          'pfa' => 'application/x-font',\n          'pfb' => 'application/x-font',\n          'gsf' => 'application/x-font',\n          'pcf' => 'application/x-font',\n          'pcf.Z' => 'application/x-font',\n          'gnumeric' => 'application/x-gnumeric',\n          'sgf' => 'application/x-go-sgf',\n          'gcf' => 'application/x-graphing-calculator',\n          'gtar' => 'application/x-gtar',\n          'tgz' => 'application/x-gtar',\n          'taz' => 'application/x-gtar',\n          'gz'  => 'application/x-gtar',\n          'hdf' => 'application/x-hdf',\n          'phtml' => 'application/x-httpd-php',\n          'pht' => 'application/x-httpd-php',\n          'php' => 'application/x-httpd-php',\n          'phps' => 'application/x-httpd-php-source',\n          'php3' => 'application/x-httpd-php3',\n          'php3p' => 'application/x-httpd-php3-preprocessed',\n          'php4' => 'application/x-httpd-php4',\n          'ica' => 'application/x-ica',\n          'ins' => 'application/x-internet-signup',\n          'isp' => 'application/x-internet-signup',\n          'iii' => 'application/x-iphone',\n          'jar' => 'application/x-java-archive',\n          'jnlp' => 'application/x-java-jnlp-file',\n          'ser' => 'application/x-java-serialized-object',\n          'class' => 'application/x-java-vm',\n          'js' => 'application/x-javascript',\n          'chrt' => 'application/x-kchart',\n          'kil' => 'application/x-killustrator',\n          'kpr' => 'application/x-kpresenter',\n          'kpt' => 'application/x-kpresenter',\n          'skp' => 'application/x-koan',\n          'skd' => 'application/x-koan',\n          'skt' => 'application/x-koan',\n          'skm' => 'application/x-koan',\n          'ksp' => 'application/x-kspread',\n          'kwd' => 'application/x-kword',\n          'kwt' => 'application/x-kword',\n          'latex' => 'application/x-latex',\n          'lha' => 'application/x-lha',\n          'lzh' => 'application/x-lzh',\n          'lzx' => 'application/x-lzx',\n          'frm' => 'application/x-maker',\n          'maker' => 'application/x-maker',\n          'frame' => 'application/x-maker',\n          'fm' => 'application/x-maker',\n          'fb' => 'application/x-maker',\n          'book' => 'application/x-maker',\n          'fbdoc' => 'application/x-maker',\n          'wmz' => 'application/x-ms-wmz',\n          'wmd' => 'application/x-ms-wmd',\n          'com' => 'application/x-msdos-program',\n          'exe' => 'application/x-msdos-program',\n          'bat' => 'application/x-msdos-program',\n          'dll' => 'application/x-msdos-program',\n          'msi' => 'application/x-msi',\n          'nc' => 'application/x-netcdf',\n          'pac' => 'application/x-ns-proxy-autoconfig',\n          'nwc' => 'application/x-nwc',\n          'o' => 'application/x-object',\n          'oza' => 'application/x-oz-application',\n          'pl' => 'application/x-perl',\n          'pm' => 'application/x-perl',\n          'p7r' => 'application/x-pkcs7-certreqresp',\n          'crl' => 'application/x-pkcs7-crl',\n          'qtl' => 'application/x-quicktimeplayer',\n          'rpm' => 'audio/x-pn-realaudio-plugin',\n          'shar' => 'application/x-shar',\n          'swf' => 'application/x-shockwave-flash',\n          'swfl' => 'application/x-shockwave-flash',\n          'sh' => 'text/x-sh',\n          'sit' => 'application/x-stuffit',\n          'sv4cpio' => 'application/x-sv4cpio',\n          'sv4crc' => 'application/x-sv4crc',\n          'tar' => 'application/x-tar',\n          'tcl' => 'text/x-tcl',\n          'tex' => 'text/x-tex',\n          'gf' => 'application/x-tex-gf',\n          'pk' => 'application/x-tex-pk',\n          'texinfo' => 'application/x-texinfo',\n          'texi' => 'application/x-texinfo',\n          '~' => 'application/x-trash',\n          '%' => 'application/x-trash',\n          'bak' => 'application/x-trash',\n          'old' => 'application/x-trash',\n          'sik' => 'application/x-trash',\n          't' => 'application/x-troff',\n          'tr' => 'application/x-troff',\n          'roff' => 'application/x-troff',\n          'man' => 'application/x-troff-man',\n          'me' => 'application/x-troff-me',\n          'ms' => 'application/x-troff-ms',\n          'ustar' => 'application/x-ustar',\n          'src' => 'application/x-wais-source',\n          'wz' => 'application/x-wingz',\n          'crt' => 'application/x-x509-ca-cert',\n          'fig' => 'application/x-xfig',\n          'au' => 'audio/basic',\n          'snd' => 'audio/basic',\n          'mid' => 'audio/midi',\n          'midi' => 'audio/midi',\n          'kar' => 'audio/midi',\n          'mpga' => 'audio/mpeg',\n          'mpega' => 'audio/mpeg',\n          'mp2' => 'audio/mpeg',\n          'mp3' => 'audio/mpeg',\n          'm3u' => 'audio/x-mpegurl',\n          'sid' => 'audio/prs.sid',\n          'aif' => 'audio/x-aiff',\n          'aiff' => 'audio/x-aiff',\n          'aifc' => 'audio/x-aiff',\n          'gsm' => 'audio/x-gsm',\n          'wma' => 'audio/x-ms-wma',\n          'wax' => 'audio/x-ms-wax',\n          'ra' => 'audio/x-realaudio',\n          'rm' => 'audio/x-pn-realaudio',\n          'ram' => 'audio/x-pn-realaudio',\n          'pls' => 'audio/x-scpls',\n          'sd2' => 'audio/x-sd2',\n          'wav' => 'audio/x-wav',\n          'pdb' => 'chemical/x-pdb',\n          'xyz' => 'chemical/x-xyz',\n          'bmp' => 'image/x-ms-bmp',\n          'gif' => 'image/gif',\n          'ief' => 'image/ief',\n          'jpeg' => 'image/jpeg',\n          'jpg' => 'image/jpeg',\n          'jpe' => 'image/jpeg',\n          'pcx' => 'image/pcx',\n          'png' => 'image/png',\n          'svg' => 'image/svg+xml',\n          'svgz' => 'image/svg+xml',\n          'tiff' => 'image/tiff',\n          'tif' => 'image/tiff',\n          'wbmp' => 'image/vnd.wap.wbmp',\n          'ras' => 'image/x-cmu-raster',\n          'cdr' => 'image/x-coreldraw',\n          'pat' => 'image/x-coreldrawpattern',\n          'cdt' => 'image/x-coreldrawtemplate',\n          'djvu' => 'image/x-djvu',\n          'djv' => 'image/x-djvu',\n          'ico' => 'image/x-icon',\n          'art' => 'image/x-jg',\n          'jng' => 'image/x-jng',\n          'psd' => 'image/x-photoshop',\n          'pnm' => 'image/x-portable-anymap',\n          'pbm' => 'image/x-portable-bitmap',\n          'pgm' => 'image/x-portable-graymap',\n          'ppm' => 'image/x-portable-pixmap',\n          'rgb' => 'image/x-rgb',\n          'xbm' => 'image/x-xbitmap',\n          'xpm' => 'image/x-xpixmap',\n          'xwd' => 'image/x-xwindowdump',\n          'igs' => 'model/iges',\n          'iges' => 'model/iges',\n          'msh' => 'model/mesh',\n          'mesh' => 'model/mesh',\n          'silo' => 'model/mesh',\n          'wrl' => 'x-world/x-vrml',\n          'vrml' => 'x-world/x-vrml',\n          'csv' => 'text/comma-separated-values',\n          'css' => 'text/css',\n          '323' => 'text/h323',\n          'htm' => 'text/html',\n          'html' => 'text/html',\n          'uls' => 'text/iuls',\n          'mml' => 'text/mathml',\n          'asc' => 'text/plain',\n          'txt' => 'text/plain',\n          'text' => 'text/plain',\n          'diff' => 'text/plain',\n          'rtx' => 'text/richtext',\n          'sct' => 'text/scriptlet',\n          'wsc' => 'text/scriptlet',\n          'tm' => 'text/texmacs',\n          'ts' => 'text/texmacs',\n          'tsv' => 'text/tab-separated-values',\n          'jad' => 'text/vnd.sun.j2me.app-descriptor',\n          'wml' => 'text/vnd.wap.wml',\n          'wmls' => 'text/vnd.wap.wmlscript',\n          'xml' => 'text/xml',\n          'xsl' => 'text/xml',\n          'h++' => 'text/x-c++hdr',\n          'hpp' => 'text/x-c++hdr',\n          'hxx' => 'text/x-c++hdr',\n          'hh' => 'text/x-c++hdr',\n          'c++' => 'text/x-c++src',\n          'cpp' => 'text/x-c++src',\n          'cxx' => 'text/x-c++src',\n          'cc' => 'text/x-c++src',\n          'h' => 'text/x-chdr',\n          'c' => 'text/x-csrc',\n          'java' => 'text/x-java',\n          'moc' => 'text/x-moc',\n          'p' => 'text/x-pascal',\n          'pas' => 'text/x-pascal',\n          '***' => 'text/x-pcs-***',\n          'shtml' => 'text/x-server-parsed-html',\n          'etx' => 'text/x-setext',\n          'tk' => 'text/x-tcl',\n          'ltx' => 'text/x-tex',\n          'sty' => 'text/x-tex',\n          'cls' => 'text/x-tex',\n          'vcs' => 'text/x-vcalendar',\n          'vcf' => 'text/x-vcard',\n          'dl' => 'video/dl',\n          'fli' => 'video/fli',\n          'gl' => 'video/gl',\n          'mpeg' => 'video/mpeg',\n          'mpg' => 'video/mpeg',\n          'mpe' => 'video/mpeg',\n          'qt' => 'video/quicktime',\n          'mov' => 'video/quicktime',\n          'mxu' => 'video/vnd.mpegurl',\n          'dif' => 'video/x-dv',\n          'dv' => 'video/x-dv',\n          'lsf' => 'video/x-la-asf',\n          'lsx' => 'video/x-la-asf',\n          'mng' => 'video/x-mng',\n          'asf' => 'video/x-ms-asf',\n          'asx' => 'video/x-ms-asf',\n          'wm' => 'video/x-ms-wm',\n          'wmv' => 'video/x-ms-wmv',\n          'wmx' => 'video/x-ms-wmx',\n          'wvx' => 'video/x-ms-wvx',\n          'avi' => 'video/x-msvideo',\n          'movie' => 'video/x-sgi-movie',\n          'ice' => 'x-conference/x-cooltalk',\n          'vrm' => 'x-world/x-vrml',\n          'rar' => 'application/x-rar-compressed',\n          'cab' => 'application/vnd.ms-cab-compressed'\n        );\n            \n            $ext=strtolower($ext);\n            if (isset($mimeTypes[$ext])) {\n                return $mimeTypes[$ext];\n            }\n\n        return 'application/octet-stream';\n    }\n}\n"
  },
  {
    "path": "AliUpload/lib/mimetypes.class.php",
    "content": "<?php\n/**\n * 获得文件的mime type类型\n * @author xiaobing.meng\n *\n */\nclass MimeTypes {\n\tpublic static $mime_types = array (\n\t\t\t'apk' => 'application/vnd.android.package-archive',\n\t\t\t'3gp' => 'video/3gpp', 'ai' => 'application/postscript', \n\t\t\t'aif' => 'audio/x-aiff', 'aifc' => 'audio/x-aiff', \n\t\t\t'aiff' => 'audio/x-aiff', 'asc' => 'text/plain', \n\t\t\t'atom' => 'application/atom+xml', 'au' => 'audio/basic', \n\t\t\t'avi' => 'video/x-msvideo', 'bcpio' => 'application/x-bcpio', \n\t\t\t'bin' => 'application/octet-stream', 'bmp' => 'image/bmp', \n\t\t\t'cdf' => 'application/x-netcdf', 'cgm' => 'image/cgm', \n\t\t\t'class' => 'application/octet-stream', \n\t\t\t'cpio' => 'application/x-cpio', \n\t\t\t'cpt' => 'application/mac-compactpro', \n\t\t\t'csh' => 'application/x-csh', 'css' => 'text/css', \n\t\t\t'dcr' => 'application/x-director', 'dif' => 'video/x-dv', \n\t\t\t'dir' => 'application/x-director', 'djv' => 'image/vnd.djvu', \n\t\t\t'djvu' => 'image/vnd.djvu', \n\t\t\t'dll' => 'application/octet-stream', \n\t\t\t'dmg' => 'application/octet-stream', \n\t\t\t'dms' => 'application/octet-stream', \n\t\t\t'doc' => 'application/msword', 'dtd' => 'application/xml-dtd', \n\t\t\t'dv' => 'video/x-dv', 'dvi' => 'application/x-dvi', \n\t\t\t'dxr' => 'application/x-director', \n\t\t\t'eps' => 'application/postscript', 'etx' => 'text/x-setext', \n\t\t\t'exe' => 'application/octet-stream', \n\t\t\t'ez' => 'application/andrew-inset', 'flv' => 'video/x-flv', \n\t\t\t'gif' => 'image/gif', 'gram' => 'application/srgs', \n\t\t\t'grxml' => 'application/srgs+xml', \n\t\t\t'gtar' => 'application/x-gtar', 'gz' => 'application/x-gzip', \n\t\t\t'hdf' => 'application/x-hdf', \n\t\t\t'hqx' => 'application/mac-binhex40', 'htm' => 'text/html', \n\t\t\t'html' => 'text/html', 'ice' => 'x-conference/x-cooltalk', \n\t\t\t'ico' => 'image/x-icon', 'ics' => 'text/calendar', \n\t\t\t'ief' => 'image/ief', 'ifb' => 'text/calendar', \n\t\t\t'iges' => 'model/iges', 'igs' => 'model/iges', \n\t\t\t'jnlp' => 'application/x-java-jnlp-file', 'jp2' => 'image/jp2', \n\t\t\t'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', \n\t\t\t'jpg' => 'image/jpeg', 'js' => 'application/x-javascript', \n\t\t\t'kar' => 'audio/midi', 'latex' => 'application/x-latex', \n\t\t\t'lha' => 'application/octet-stream', \n\t\t\t'lzh' => 'application/octet-stream', \n\t\t\t'm3u' => 'audio/x-mpegurl', 'm4a' => 'audio/mp4a-latm', \n\t\t\t'm4p' => 'audio/mp4a-latm', 'm4u' => 'video/vnd.mpegurl', \n\t\t\t'm4v' => 'video/x-m4v', 'mac' => 'image/x-macpaint', \n\t\t\t'man' => 'application/x-troff-man', \n\t\t\t'mathml' => 'application/mathml+xml', \n\t\t\t'me' => 'application/x-troff-me', 'mesh' => 'model/mesh', \n\t\t\t'mid' => 'audio/midi', 'midi' => 'audio/midi', \n\t\t\t'mif' => 'application/vnd.mif', 'mov' => 'video/quicktime', \n\t\t\t'movie' => 'video/x-sgi-movie', 'mp2' => 'audio/mpeg', \n\t\t\t'mp3' => 'audio/mpeg', 'mp4' => 'video/mp4', \n\t\t\t'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', \n\t\t\t'mpg' => 'video/mpeg', 'mpga' => 'audio/mpeg', \n\t\t\t'ms' => 'application/x-troff-ms', 'msh' => 'model/mesh', \n\t\t\t'mxu' => 'video/vnd.mpegurl', 'nc' => 'application/x-netcdf', \n\t\t\t'oda' => 'application/oda', 'ogg' => 'application/ogg', \n\t\t\t'ogv' => 'video/ogv', 'pbm' => 'image/x-portable-bitmap', \n\t\t\t'pct' => 'image/pict', 'pdb' => 'chemical/x-pdb', \n\t\t\t'pdf' => 'application/pdf', \n\t\t\t'pgm' => 'image/x-portable-graymap', \n\t\t\t'pgn' => 'application/x-chess-pgn', 'pic' => 'image/pict', \n\t\t\t'pict' => 'image/pict', 'png' => 'image/png', \n\t\t\t'pnm' => 'image/x-portable-anymap', \n\t\t\t'pnt' => 'image/x-macpaint', 'pntg' => 'image/x-macpaint', \n\t\t\t'ppm' => 'image/x-portable-pixmap', \n\t\t\t'ppt' => 'application/vnd.ms-powerpoint', \n\t\t\t'ps' => 'application/postscript', 'qt' => 'video/quicktime', \n\t\t\t'qti' => 'image/x-quicktime', 'qtif' => 'image/x-quicktime', \n\t\t\t'ra' => 'audio/x-pn-realaudio', \n\t\t\t'ram' => 'audio/x-pn-realaudio', 'ras' => 'image/x-cmu-raster', \n\t\t\t'rdf' => 'application/rdf+xml', 'rgb' => 'image/x-rgb', \n\t\t\t'rm' => 'application/vnd.rn-realmedia', \n\t\t\t'roff' => 'application/x-troff', 'rtf' => 'text/rtf', \n\t\t\t'rtx' => 'text/richtext', 'sgm' => 'text/sgml', \n\t\t\t'sgml' => 'text/sgml', 'sh' => 'application/x-sh', \n\t\t\t'shar' => 'application/x-shar', 'silo' => 'model/mesh', \n\t\t\t'sit' => 'application/x-stuffit', \n\t\t\t'skd' => 'application/x-koan', 'skm' => 'application/x-koan', \n\t\t\t'skp' => 'application/x-koan', 'skt' => 'application/x-koan', \n\t\t\t'smi' => 'application/smil', 'smil' => 'application/smil', \n\t\t\t'snd' => 'audio/basic', 'so' => 'application/octet-stream', \n\t\t\t'spl' => 'application/x-futuresplash', \n\t\t\t'src' => 'application/x-wais-source', \n\t\t\t'sv4cpio' => 'application/x-sv4cpio', \n\t\t\t'sv4crc' => 'application/x-sv4crc', 'svg' => 'image/svg+xml', \n\t\t\t'swf' => 'application/x-shockwave-flash', \n\t\t\t't' => 'application/x-troff', 'tar' => 'application/x-tar', \n\t\t\t'tcl' => 'application/x-tcl', 'tex' => 'application/x-tex', \n\t\t\t'texi' => 'application/x-texinfo', \n\t\t\t'texinfo' => 'application/x-texinfo', 'tif' => 'image/tiff', \n\t\t\t'tiff' => 'image/tiff', 'tr' => 'application/x-troff', \n\t\t\t'tsv' => 'text/tab-separated-values', 'txt' => 'text/plain', \n\t\t\t'ustar' => 'application/x-ustar', \n\t\t\t'vcd' => 'application/x-cdlink', 'vrml' => 'model/vrml', \n\t\t\t'vxml' => 'application/voicexml+xml', 'wav' => 'audio/x-wav', \n\t\t\t'wbmp' => 'image/vnd.wap.wbmp', \n\t\t\t'wbxml' => 'application/vnd.wap.wbxml', 'webm' => 'video/webm', \n\t\t\t'wml' => 'text/vnd.wap.wml', \n\t\t\t'wmlc' => 'application/vnd.wap.wmlc', \n\t\t\t'wmls' => 'text/vnd.wap.wmlscript', \n\t\t\t'wmlsc' => 'application/vnd.wap.wmlscriptc', \n\t\t\t'wmv' => 'video/x-ms-wmv', 'wrl' => 'model/vrml', \n\t\t\t'xbm' => 'image/x-xbitmap', 'xht' => 'application/xhtml+xml', \n\t\t\t'xhtml' => 'application/xhtml+xml', \n\t\t\t'xls' => 'application/vnd.ms-excel', \n\t\t\t'xml' => 'application/xml', 'xpm' => 'image/x-xpixmap', \n\t\t\t'xsl' => 'application/xml', 'xslt' => 'application/xslt+xml', \n\t\t\t'xul' => 'application/vnd.mozilla.xul+xml', \n\t\t\t'xwd' => 'image/x-xwindowdump', 'xyz' => 'chemical/x-xyz', \n\t\t\t'zip' => 'application/zip' );\n\t\n\tpublic static function get_mimetype($ext) {\n\t\treturn (isset ( self::$mime_types [$ext] ) ? self::$mime_types [$ext] : 'application/octet-stream');\n\t}\n}\n"
  },
  {
    "path": "AliUpload/lib/requestcore.class.php",
    "content": "<?php\n/**\n * Handles all HTTP requests using cURL and manages the responses.\n *\n * @version 2011.06.07\n * @copyright 2006-2011 Ryan Parman\n * @copyright 2006-2010 Foleeo Inc.\n * @copyright 2010-2011 Amazon.com, Inc. or its affiliates.\n * @copyright 2008-2011 Contributors\n * @license http://opensource.org/licenses/bsd-license.php Simplified BSD License\n */\nclass RequestCore\n{\n\t/**\n\t * The URL being requested.\n\t */\n\tpublic $request_url;\n\n\t/**\n\t * The headers being sent in the request.\n\t */\n\tpublic $request_headers;\n\n\t/**\n\t * The body being sent in the request.\n\t */\n\tpublic $request_body;\n\n\t/**\n\t * The response returned by the request.\n\t */\n\tpublic $response;\n\n\t/**\n\t * The headers returned by the request.\n\t */\n\tpublic $response_headers;\n\n\t/**\n\t * The body returned by the request.\n\t */\n\tpublic $response_body;\n\n\t/**\n\t * The HTTP status code returned by the request.\n\t */\n\tpublic $response_code;\n\n\t/**\n\t * Additional response data.\n\t */\n\tpublic $response_info;\n\n\t/**\n\t * The handle for the cURL object.\n\t */\n\tpublic $curl_handle;\n\n\t/**\n\t * The method by which the request is being made.\n\t */\n\tpublic $method;\n\n\t/**\n\t * Stores the proxy settings to use for the request.\n\t */\n\tpublic $proxy = null;\n\n\t/**\n\t * The username to use for the request.\n\t */\n\tpublic $username = null;\n\n\t/**\n\t * The password to use for the request.\n\t */\n\tpublic $password = null;\n\n\t/**\n\t * Custom CURLOPT settings.\n\t */\n\tpublic $curlopts = null;\n\n\t/**\n\t * The state of debug mode.\n\t */\n\tpublic $debug_mode = false;\n\n\t/**\n\t * The default class to use for HTTP Requests (defaults to <RequestCore>).\n\t */\n\tpublic $request_class = 'RequestCore';\n\n\t/**\n\t * The default class to use for HTTP Responses (defaults to <ResponseCore>).\n\t */\n\tpublic $response_class = 'ResponseCore';\n\n\t/**\n\t * Default useragent string to use.\n\t */\n\tpublic $useragent = 'RequestCore/1.4.3';\n\n\t/**\n\t * File to read from while streaming up.\n\t */\n\tpublic $read_file = null;\n\n\t/**\n\t * The resource to read from while streaming up.\n\t */\n\tpublic $read_stream = null;\n\n\t/**\n\t * The size of the stream to read from.\n\t */\n\tpublic $read_stream_size = null;\n\n\t/**\n\t * The length already read from the stream.\n\t */\n\tpublic $read_stream_read = 0;\n\n\t/**\n\t * File to write to while streaming down.\n\t */\n\tpublic $write_file = null;\n\n\t/**\n\t * The resource to write to while streaming down.\n\t */\n\tpublic $write_stream = null;\n\n\t/**\n\t * Stores the intended starting seek position.\n\t */\n\tpublic $seek_position = null;\n\n\t/**\n\t * The location of the cacert.pem file to use.\n\t */\n\tpublic $cacert_location = false;\n\n\t/**\n\t * The state of SSL certificate verification.\n\t */\n\tpublic $ssl_verification = true;\n\n\t/**\n\t * The user-defined callback function to call when a stream is read from.\n\t */\n\tpublic $registered_streaming_read_callback = null;\n\n\t/**\n\t * The user-defined callback function to call when a stream is written to.\n\t */\n\tpublic $registered_streaming_write_callback = null;\n\n\n\t/*%******************************************************************************************%*/\n\t// CONSTANTS\n\n\t/**\n\t * GET HTTP Method\n\t */\n\tconst HTTP_GET = 'GET';\n\n\t/**\n\t * POST HTTP Method\n\t */\n\tconst HTTP_POST = 'POST';\n\n\t/**\n\t * PUT HTTP Method\n\t */\n\tconst HTTP_PUT = 'PUT';\n\n\t/**\n\t * DELETE HTTP Method\n\t */\n\tconst HTTP_DELETE = 'DELETE';\n\n\t/**\n\t * HEAD HTTP Method\n\t */\n\tconst HTTP_HEAD = 'HEAD';\n\n\n\t/*%******************************************************************************************%*/\n\t// CONSTRUCTOR/DESTRUCTOR\n\n\t/**\n\t * Constructs a new instance of this class.\n\t *\n\t * @param string $url (Optional) The URL to request or service endpoint to query.\n\t * @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port`\n\t * @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function __construct($url = null, $proxy = null, $helpers = null)\n\t{\n\t\t// Set some default values.\n\t\t$this->request_url = $url;\n\t\t$this->method = self::HTTP_GET;\n\t\t$this->request_headers = array();\n\t\t$this->request_body = '';\n\n\t\t// Set a new Request class if one was set.\n\t\tif (isset($helpers['request']) && !empty($helpers['request']))\n\t\t{\n\t\t\t$this->request_class = $helpers['request'];\n\t\t}\n\n\t\t// Set a new Request class if one was set.\n\t\tif (isset($helpers['response']) && !empty($helpers['response']))\n\t\t{\n\t\t\t$this->response_class = $helpers['response'];\n\t\t}\n\n\t\tif ($proxy)\n\t\t{\n\t\t\t$this->set_proxy($proxy);\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Destructs the instance. Closes opened file handles.\n\t *\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function __destruct()\n\t{\n\t\tif (isset($this->read_file) && isset($this->read_stream))\n\t\t{\n\t\t\tfclose($this->read_stream);\n\t\t}\n\n\t\tif (isset($this->write_file) && isset($this->write_stream))\n\t\t{\n\t\t\tfclose($this->write_stream);\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\n\t/*%******************************************************************************************%*/\n\t// REQUEST METHODS\n\n\t/**\n\t * Sets the credentials to use for authentication.\n\t *\n\t * @param string $user (Required) The username to authenticate with.\n\t * @param string $pass (Required) The password to authenticate with.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_credentials($user, $pass)\n\t{\n\t\t$this->username = $user;\n\t\t$this->password = $pass;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Adds a custom HTTP header to the cURL request.\n\t *\n\t * @param string $key (Required) The custom HTTP header to set.\n\t * @param mixed $value (Required) The value to assign to the custom HTTP header.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function add_header($key, $value)\n\t{\n\t\t$this->request_headers[$key] = $value;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Removes an HTTP header from the cURL request.\n\t *\n\t * @param string $key (Required) The custom HTTP header to set.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function remove_header($key)\n\t{\n\t\tif (isset($this->request_headers[$key]))\n\t\t{\n\t\t\tunset($this->request_headers[$key]);\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set the method type for the request.\n\t *\n\t * @param string $method (Required) One of the following constants: <HTTP_GET>, <HTTP_POST>, <HTTP_PUT>, <HTTP_HEAD>, <HTTP_DELETE>.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_method($method)\n\t{\n\t\t$this->method = strtoupper($method);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Sets a custom useragent string for the class.\n\t *\n\t * @param string $ua (Required) The useragent string to use.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_useragent($ua)\n\t{\n\t\t$this->useragent = $ua;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set the body to send in the request.\n\t *\n\t * @param string $body (Required) The textual content to send along in the body of the request.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_body($body)\n\t{\n\t\t$this->request_body = $body;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set the URL to make the request to.\n\t *\n\t * @param string $url (Required) The URL to make the request to.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_request_url($url)\n\t{\n\t\t$this->request_url = $url;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set additional CURLOPT settings. These will merge with the default settings, and override if\n\t * there is a duplicate.\n\t *\n\t * @param array $curlopts (Optional) A set of key-value pairs that set `CURLOPT` options. These will merge with the existing CURLOPTs, and ones passed here will override the defaults. Keys should be the `CURLOPT_*` constants, not strings.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_curlopts($curlopts)\n\t{\n\t\t$this->curlopts = $curlopts;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Sets the length in bytes to read from the stream while streaming up.\n\t *\n\t * @param integer $size (Required) The length in bytes to read from the stream.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_read_stream_size($size)\n\t{\n\t\t$this->read_stream_size = $size;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Sets the resource to read from while streaming up. Reads the stream from its current position until\n\t * EOF or `$size` bytes have been read. If `$size` is not given it will be determined by <php:fstat()> and\n\t * <php:ftell()>.\n\t *\n\t * @param resource $resource (Required) The readable resource to read from.\n\t * @param integer $size (Optional) The size of the stream to read.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_read_stream($resource, $size = null)\n\t{\n\t\tif (!isset($size) || $size < 0)\n\t\t{\n\t\t\t$stats = fstat($resource);\n\n\t\t\tif ($stats && $stats['size'] >= 0)\n\t\t\t{\n\t\t\t\t$position = ftell($resource);\n\n\t\t\t\tif ($position !== false && $position >= 0)\n\t\t\t\t{\n\t\t\t\t\t$size = $stats['size'] - $position;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$this->read_stream = $resource;\n\n\t\treturn $this->set_read_stream_size($size);\n\t}\n\n\t/**\n\t * Sets the file to read from while streaming up.\n\t *\n\t * @param string $location (Required) The readable location to read from.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_read_file($location)\n\t{\n\t\t$this->read_file = $location;\n\t\t$read_file_handle = fopen($location, 'r');\n\n\t\treturn $this->set_read_stream($read_file_handle);\n\t}\n\n\t/**\n\t * Sets the resource to write to while streaming down.\n\t *\n\t * @param resource $resource (Required) The writeable resource to write to.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_write_stream($resource)\n\t{\n\t\t$this->write_stream = $resource;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Sets the file to write to while streaming down.\n\t *\n\t * @param string $location (Required) The writeable location to write to.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_write_file($location)\n\t{\n\t\t$this->write_file = $location;\n\t\t$write_file_handle = fopen($location, 'w');\n\n\t\treturn $this->set_write_stream($write_file_handle);\n\t}\n\n\t/**\n\t * Set the proxy to use for making requests.\n\t *\n\t * @param string $proxy (Required) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port`\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_proxy($proxy)\n\t{\n\t\t$proxy = parse_url($proxy);\n\t\t$proxy['user'] = isset($proxy['user']) ? $proxy['user'] : null;\n\t\t$proxy['pass'] = isset($proxy['pass']) ? $proxy['pass'] : null;\n\t\t$proxy['port'] = isset($proxy['port']) ? $proxy['port'] : null;\n\t\t$this->proxy = $proxy;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set the intended starting seek position.\n\t *\n\t * @param integer $position (Required) The byte-position of the stream to begin reading from.\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function set_seek_position($position)\n\t{\n\t\t$this->seek_position = isset($position) ? (integer) $position : null;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Register a callback function to execute whenever a data stream is read from using\n\t * <CFRequest::streaming_read_callback()>.\n\t *\n\t * The user-defined callback function should accept three arguments:\n\t *\n\t * <ul>\n\t * \t<li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li>\n\t * \t<li><code>$file_handle</code> - <code>resource</code> - Required - The file handle resource that represents the file on the local file system.</li>\n\t * \t<li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li>\n\t * </ul>\n\t *\n\t * @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul>\n\t * \t<li>The name of a global function to execute, passed as a string.</li>\n\t * \t<li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li>\n\t * \t<li>An anonymous function (PHP 5.3+).</li></ul>\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function register_streaming_read_callback($callback)\n\t{\n\t\t$this->registered_streaming_read_callback = $callback;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Register a callback function to execute whenever a data stream is written to using\n\t * <CFRequest::streaming_write_callback()>.\n\t *\n\t * The user-defined callback function should accept two arguments:\n\t *\n\t * <ul>\n\t * \t<li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li>\n\t * \t<li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li>\n\t * </ul>\n\t *\n\t * @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul>\n\t * \t<li>The name of a global function to execute, passed as a string.</li>\n\t * \t<li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li>\n\t * \t<li>An anonymous function (PHP 5.3+).</li></ul>\n\t * @return $this A reference to the current instance.\n\t */\n\tpublic function register_streaming_write_callback($callback)\n\t{\n\t\t$this->registered_streaming_write_callback = $callback;\n\n\t\treturn $this;\n\t}\n\n\n\t/*%******************************************************************************************%*/\n\t// PREPARE, SEND, AND PROCESS REQUEST\n\n\t/**\n\t * A callback function that is invoked by cURL for streaming up.\n\t *\n\t * @param resource $curl_handle (Required) The cURL handle for the request.\n\t * @param resource $file_handle (Required) The open file handle resource.\n\t * @param integer $length (Required) The maximum number of bytes to read.\n\t * @return binary Binary data from a stream.\n\t */\n\tpublic function streaming_read_callback($curl_handle, $file_handle, $length)\n\t{\n\t\t// Once we've sent as much as we're supposed to send...\n\t\tif ($this->read_stream_read >= $this->read_stream_size)\n\t\t{\n\t\t\t// Send EOF\n\t\t\treturn '';\n\t\t}\n\n\t\t// If we're at the beginning of an upload and need to seek...\n\t\tif ($this->read_stream_read == 0 && isset($this->seek_position) && $this->seek_position !== ftell($this->read_stream))\n\t\t{\n\t\t\tif (fseek($this->read_stream, $this->seek_position) !== 0)\n\t\t\t{\n\t\t\t\tthrow new RequestCore_Exception('The stream does not support seeking and is either not at the requested position or the position is unknown.');\n\t\t\t}\n\t\t}\n\n\t\t$read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size\n\t\t$this->read_stream_read += strlen($read);\n\n\t\t$out = $read === false ? '' : $read;\n\n\t\t// Execute callback function\n\t\tif ($this->registered_streaming_read_callback)\n\t\t{\n\t\t\tcall_user_func($this->registered_streaming_read_callback, $curl_handle, $file_handle, $out);\n\t\t}\n\n\t\treturn $out;\n\t}\n\n\t/**\n\t * A callback function that is invoked by cURL for streaming down.\n\t *\n\t * @param resource $curl_handle (Required) The cURL handle for the request.\n\t * @param binary $data (Required) The data to write.\n\t * @return integer The number of bytes written.\n\t */\n\tpublic function streaming_write_callback($curl_handle, $data)\n\t{\n\t\t$length = strlen($data);\n\t\t$written_total = 0;\n\t\t$written_last = 0;\n\n\t\twhile ($written_total < $length)\n\t\t{\n\t\t\t$written_last = fwrite($this->write_stream, substr($data, $written_total));\n\n\t\t\tif ($written_last === false)\n\t\t\t{\n\t\t\t\treturn $written_total;\n\t\t\t}\n\n\t\t\t$written_total += $written_last;\n\t\t}\n\n\t\t// Execute callback function\n\t\tif ($this->registered_streaming_write_callback)\n\t\t{\n\t\t\tcall_user_func($this->registered_streaming_write_callback, $curl_handle, $written_total);\n\t\t}\n\n\t\treturn $written_total;\n\t}\n\n\t/**\n\t * Prepares and adds the details of the cURL request. This can be passed along to a <php:curl_multi_exec()>\n\t * function.\n\t *\n\t * @return resource The handle for the cURL object.\n\t */\n\tpublic function prep_request()\n\t{\n\t\t$curl_handle = curl_init();\n\n\t\t// Set default options.\n\t\tcurl_setopt($curl_handle, CURLOPT_URL, $this->request_url);\n\t\tcurl_setopt($curl_handle, CURLOPT_FILETIME, true);\n\t\tcurl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false);\n\t\tcurl_setopt($curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED);\n\t\tcurl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5);\n\t\tcurl_setopt($curl_handle, CURLOPT_HEADER, true);\n\t\tcurl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);\n\t\tcurl_setopt($curl_handle, CURLOPT_TIMEOUT, 5184000);\n\t\tcurl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 120);\n\t\tcurl_setopt($curl_handle, CURLOPT_NOSIGNAL, true);\n\t\tcurl_setopt($curl_handle, CURLOPT_REFERER, $this->request_url);\n\t\tcurl_setopt($curl_handle, CURLOPT_USERAGENT, $this->useragent);\n\t\tcurl_setopt($curl_handle, CURLOPT_READFUNCTION, array($this, 'streaming_read_callback'));\n\n\t\t// Verification of the SSL cert\n\t\tif ($this->ssl_verification)\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, true);\n\t\t\tcurl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, true);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);\n\t\t\tcurl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false);\n\t\t}\n\n\t\t// chmod the file as 0755\n\t\tif ($this->cacert_location === true)\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');\n\t\t}\n\t\telseif (is_string($this->cacert_location))\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_CAINFO, $this->cacert_location);\n\t\t}\n\n\t\t// Debug mode\n\t\tif ($this->debug_mode)\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_VERBOSE, true);\n\t\t}\n\n\t\t// Handle open_basedir & safe mode\n\t\tif (!ini_get('safe_mode') && !ini_get('open_basedir'))\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true);\n\t\t}\n\n\t\t// Enable a proxy connection if requested.\n\t\tif ($this->proxy)\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_HTTPPROXYTUNNEL, true);\n\n\t\t\t$host = $this->proxy['host'];\n\t\t\t$host .= ($this->proxy['port']) ? ':' . $this->proxy['port'] : '';\n\t\t\tcurl_setopt($curl_handle, CURLOPT_PROXY, $host);\n\n\t\t\tif (isset($this->proxy['user']) && isset($this->proxy['pass']))\n\t\t\t{\n\t\t\t\tcurl_setopt($curl_handle, CURLOPT_PROXYUSERPWD, $this->proxy['user'] . ':' . $this->proxy['pass']);\n\t\t\t}\n\t\t}\n\n\t\t// Set credentials for HTTP Basic/Digest Authentication.\n\t\tif ($this->username && $this->password)\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);\n\t\t\tcurl_setopt($curl_handle, CURLOPT_USERPWD, $this->username . ':' . $this->password);\n\t\t}\n\n\t\t// Handle the encoding if we can.\n\t\tif (extension_loaded('zlib'))\n\t\t{\n\t\t\tcurl_setopt($curl_handle, CURLOPT_ENCODING, '');\n\t\t}\n\n\t\t// Process custom headers\n\t\tif (isset($this->request_headers) && count($this->request_headers))\n\t\t{\n\t\t\t$temp_headers = array();\n\n\t\t\tforeach ($this->request_headers as $k => $v)\n\t\t\t{\n\t\t\t\t$temp_headers[] = $k . ': ' . $v;\n\t\t\t}\n\n\t\t\tcurl_setopt($curl_handle, CURLOPT_HTTPHEADER, $temp_headers);\n\t\t}\n\n\t\tswitch ($this->method)\n\t\t{\n\t\t\tcase self::HTTP_PUT:\n\t\t\t\t//unset($this->read_stream);\n\t\t\t\tcurl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT');\n\t\t\t\tif (isset($this->read_stream))\n\t\t\t\t{\n\t\t\t\t\tif (!isset($this->read_stream_size) || $this->read_stream_size < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new RequestCore_Exception('The stream size for the streaming upload cannot be determined.');\n\t\t\t\t\t}\n\n\t\t\t\t\tcurl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size);\n\t\t\t\t\tcurl_setopt($curl_handle, CURLOPT_UPLOAD, true);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcurl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase self::HTTP_POST:\n\t\t\t\tcurl_setopt($curl_handle, CURLOPT_POST, true);\n\t\t\t\tcurl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body);\n\t\t\t\tbreak;\n\n\t\t\tcase self::HTTP_HEAD:\n\t\t\t\tcurl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, self::HTTP_HEAD);\n\t\t\t\tcurl_setopt($curl_handle, CURLOPT_NOBODY, 1);\n\t\t\t\tbreak;\n\n\t\t\tdefault: // Assumed GET\n\t\t\t\tcurl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, $this->method);\n\t\t\t\tif (isset($this->write_stream))\n\t\t\t\t{\n\t\t\t\t\tcurl_setopt($curl_handle, CURLOPT_WRITEFUNCTION, array($this, 'streaming_write_callback'));\n\t\t\t\t\tcurl_setopt($curl_handle, CURLOPT_HEADER, false);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcurl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Merge in the CURLOPTs\n\t\tif (isset($this->curlopts) && sizeof($this->curlopts) > 0)\n\t\t{\n\t\t\tforeach ($this->curlopts as $k => $v)\n\t\t\t{\n\t\t\t\tcurl_setopt($curl_handle, $k, $v);\n\t\t\t}\n\t\t}\n\n\t\treturn $curl_handle;\n\t}\n\n\t/**\n\t * Take the post-processed cURL data and break it down into useful header/body/info chunks. Uses the\n\t * data stored in the `curl_handle` and `response` properties unless replacement data is passed in via\n\t * parameters.\n\t *\n\t * @param resource $curl_handle (Optional) The reference to the already executed cURL request.\n\t * @param string $response (Optional) The actual response content itself that needs to be parsed.\n\t * @return ResponseCore A <ResponseCore> object containing a parsed HTTP response.\n\t */\n\tpublic function process_response($curl_handle = null, $response = null)\n\t{\n\t\t// Accept a custom one if it's passed.\n\t\tif ($curl_handle && $response)\n\t\t{\n\t\t\t$this->curl_handle = $curl_handle;\n\t\t\t$this->response = $response;\n\t\t}\n\n\t\t// As long as this came back as a valid resource...\n\t\tif (is_resource($this->curl_handle))\n\t\t{\n\t\t\t// Determine what's what.\n\t\t\t$header_size = curl_getinfo($this->curl_handle, CURLINFO_HEADER_SIZE);\n\t\t\t$this->response_headers = substr($this->response, 0, $header_size);\n\t\t\t$this->response_body = substr($this->response, $header_size);\n\t\t\t$this->response_code = curl_getinfo($this->curl_handle, CURLINFO_HTTP_CODE);\n\t\t\t$this->response_info = curl_getinfo($this->curl_handle);\n\n\t\t\t// Parse out the headers\n\t\t\t$this->response_headers = explode(\"\\r\\n\\r\\n\", trim($this->response_headers));\n\t\t\t$this->response_headers = array_pop($this->response_headers);\n\t\t\t$this->response_headers = explode(\"\\r\\n\", $this->response_headers);\n\t\t\tarray_shift($this->response_headers);\n\n\t\t\t// Loop through and split up the headers.\n\t\t\t$header_assoc = array();\n\t\t\tforeach ($this->response_headers as $header)\n\t\t\t{\n\t\t\t\t$kv = explode(': ', $header);\n\t\t\t\t$header_assoc[strtolower($kv[0])] = isset($kv[1])?$kv[1]:'';\n\t\t\t}\n\n\t\t\t// Reset the headers to the appropriate property.\n\t\t\t$this->response_headers = $header_assoc;\n\t\t\t$this->response_headers['_info'] = $this->response_info;\n\t\t\t$this->response_headers['_info']['method'] = $this->method;\n\n\t\t\tif ($curl_handle && $response)\n\t\t\t{\n\t\t\t\treturn new $this->response_class($this->response_headers, $this->response_body, $this->response_code, $this->curl_handle);\n\t\t\t}\n\t\t}\n\n\t\t// Return false\n\t\treturn false;\n\t}\n\n\t/**\n\t * Sends the request, calling necessary utility functions to update built-in properties.\n\t *\n\t * @param boolean $parse (Optional) Whether to parse the response with ResponseCore or not.\n\t * @return string The resulting unparsed data from the request.\n\t */\n\tpublic function send_request($parse = false)\n\t{\n\t\tset_time_limit(0);\n\n\t\t$curl_handle = $this->prep_request();\n\t\t$this->response = curl_exec($curl_handle);\n\n\t\tif ($this->response === false)\n\t\t{\n\t\t\tthrow new RequestCore_Exception('cURL resource: ' . (string) $curl_handle . '; cURL error: ' . curl_error($curl_handle) . ' (' . curl_errno($curl_handle) . ')');\n\t\t}\n\n\t\t$parsed_response = $this->process_response($curl_handle, $this->response);\n\n\t\tcurl_close($curl_handle);\n\n\t\tif ($parse)\n\t\t{\n\t\t\treturn $parsed_response;\n\t\t}\n\n\t\treturn $this->response;\n\t}\n\n\t/**\n\t * Sends the request using <php:curl_multi_exec()>, enabling parallel requests. Uses the \"rolling\" method.\n\t *\n\t * @param array $handles (Required) An indexed array of cURL handles to process simultaneously.\n\t * @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>\n\t * \t<li><code>callback</code> - <code>string|array</code> - Optional - The string name of a function to pass the response data to. If this is a method, pass an array where the <code>[0]</code> index is the class and the <code>[1]</code> index is the method name.</li>\n\t * \t<li><code>limit</code> - <code>integer</code> - Optional - The number of simultaneous requests to make. This can be useful for scaling around slow server responses. Defaults to trusting cURLs judgement as to how many to use.</li></ul>\n\t * @return array Post-processed cURL responses.\n\t */\n\tpublic function send_multi_request($handles, $opt = null)\n\t{\n\t\tset_time_limit(0);\n\n\t\t// Skip everything if there are no handles to process.\n\t\tif (count($handles) === 0) return array();\n\n\t\tif (!$opt) $opt = array();\n\n\t\t// Initialize any missing options\n\t\t$limit = isset($opt['limit']) ? $opt['limit'] : -1;\n\n\t\t// Initialize\n\t\t$handle_list = $handles;\n\t\t$http = new $this->request_class();\n\t\t$multi_handle = curl_multi_init();\n\t\t$handles_post = array();\n\t\t$added = count($handles);\n\t\t$last_handle = null;\n\t\t$count = 0;\n\t\t$i = 0;\n\n\t\t// Loop through the cURL handles and add as many as it set by the limit parameter.\n\t\twhile ($i < $added)\n\t\t{\n\t\t\tif ($limit > 0 && $i >= $limit) break;\n\t\t\tcurl_multi_add_handle($multi_handle, array_shift($handles));\n\t\t\t$i++;\n\t\t}\n\n\t\tdo\n\t\t{\n\t\t\t$active = false;\n\n\t\t\t// Start executing and wait for a response.\n\t\t\twhile (($status = curl_multi_exec($multi_handle, $active)) === CURLM_CALL_MULTI_PERFORM)\n\t\t\t{\n\t\t\t\t// Start looking for possible responses immediately when we have to add more handles\n\t\t\t\tif (count($handles) > 0) break;\n\t\t\t}\n\n\t\t\t// Figure out which requests finished.\n\t\t\t$to_process = array();\n\n\t\t\twhile ($done = curl_multi_info_read($multi_handle))\n\t\t\t{\n\t\t\t\t// Since curl_errno() isn't reliable for handles that were in multirequests, we check the 'result' of the info read, which contains the curl error number, (listed here http://curl.haxx.se/libcurl/c/libcurl-errors.html )\n\t\t\t\tif ($done['result'] > 0)\n\t\t\t\t{\n\t\t\t\t\tthrow new RequestCore_Exception('cURL resource: ' . (string) $done['handle'] . '; cURL error: ' . curl_error($done['handle']) . ' (' . $done['result'] . ')');\n\t\t\t\t}\n\n\t\t\t\t// Because curl_multi_info_read() might return more than one message about a request, we check to see if this request is already in our array of completed requests\n\t\t\t\telseif (!isset($to_process[(int) $done['handle']]))\n\t\t\t\t{\n\t\t\t\t\t$to_process[(int) $done['handle']] = $done;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Actually deal with the request\n\t\t\tforeach ($to_process as $pkey => $done)\n\t\t\t{\n\t\t\t\t$response = $http->process_response($done['handle'], curl_multi_getcontent($done['handle']));\n\t\t\t\t$key = array_search($done['handle'], $handle_list, true);\n\t\t\t\t$handles_post[$key] = $response;\n\n\t\t\t\tif (count($handles) > 0)\n\t\t\t\t{\n\t\t\t\t\tcurl_multi_add_handle($multi_handle, array_shift($handles));\n\t\t\t\t}\n\n\t\t\t\tcurl_multi_remove_handle($multi_handle, $done['handle']);\n\t\t\t\tcurl_close($done['handle']);\n\t\t\t}\n\t\t}\n\t\twhile ($active || count($handles_post) < $added);\n\n\t\tcurl_multi_close($multi_handle);\n\n\t\tksort($handles_post, SORT_NUMERIC);\n\t\treturn $handles_post;\n\t}\n\n\n\t/*%******************************************************************************************%*/\n\t// RESPONSE METHODS\n\n\t/**\n\t * Get the HTTP response headers from the request.\n\t *\n\t * @param string $header (Optional) A specific header value to return. Defaults to all headers.\n\t * @return string|array All or selected header values.\n\t */\n\tpublic function get_response_header($header = null)\n\t{\n\t\tif ($header)\n\t\t{\n\t\t\treturn $this->response_headers[strtolower($header)];\n\t\t}\n\t\treturn $this->response_headers;\n\t}\n\n\t/**\n\t * Get the HTTP response body from the request.\n\t *\n\t * @return string The response body.\n\t */\n\tpublic function get_response_body()\n\t{\n\t\treturn $this->response_body;\n\t}\n\n\t/**\n\t * Get the HTTP response code from the request.\n\t *\n\t * @return string The HTTP response code.\n\t */\n\tpublic function get_response_code()\n\t{\n\t\treturn $this->response_code;\n\t}\n}\n\n\n/**\n * Container for all response-related methods.\n */\nclass ResponseCore\n{\n\t/**\n\t * Stores the HTTP header information.\n\t */\n\tpublic $header;\n\n\t/**\n\t * Stores the SimpleXML response.\n\t */\n\tpublic $body;\n\n\t/**\n\t * Stores the HTTP response code.\n\t */\n\tpublic $status;\n\n\t/**\n\t * Constructs a new instance of this class.\n\t *\n\t * @param array $header (Required) Associative array of HTTP headers (typically returned by <RequestCore::get_response_header()>).\n\t * @param string $body (Required) XML-formatted response from AWS.\n\t * @param integer $status (Optional) HTTP response status code from the request.\n\t * @return object Contains an <php:array> `header` property (HTTP headers as an associative array), a <php:SimpleXMLElement> or <php:string> `body` property, and an <php:integer> `status` code.\n\t */\n\tpublic function __construct($header, $body, $status = null)\n\t{\n\t\t$this->header = $header;\n\t\t$this->body = $body;\n\t\t$this->status = $status;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Did we receive the status code we expected?\n\t *\n\t * @param integer|array $codes (Optional) The status code(s) to expect. Pass an <php:integer> for a single acceptable value, or an <php:array> of integers for multiple acceptable values.\n\t * @return boolean Whether we received the expected status code or not.\n\t */\n\tpublic function isOK($codes = array(200, 201, 204, 206))\n\t{\n\t\tif (is_array($codes))\n\t\t{\n\t\t\treturn in_array($this->status, $codes);\n\t\t}\n\n\t\treturn $this->status === $codes;\n\t}\n}\n\n/**\n * Default RequestCore Exception.\n */\nclass RequestCore_Exception extends Exception {}\n"
  },
  {
    "path": "AliUpload/lib/sdk.class.php",
    "content": "<?php\n/**\n * OSS(Open Storage Services) PHP SDK v1.1.5\n */\n//设置默认时区\ndate_default_timezone_set('Asia/Shanghai');\n\n//检测API路径\nif(!defined('OSS_API_PATH'))\ndefine('OSS_API_PATH', dirname(__FILE__));\n\n//加载RequestCore\nrequire_once 'requestcore.class.php';\n\n//加载MimeTypes\nrequire_once 'mimetypes.class.php';\n\n//加载MimeTypes\nrequire_once 'zh.inc.php';\n\n\n//定义软件名称，版本号等信息\ndefine('OSS_NAME','oss-sdk-php');\ndefine('OSS_VERSION','1.1.5');\ndefine('OSS_BUILD','201210121010245');\ndefine('OSS_AUTHOR', 'xiaobing.meng@alibaba-inc.com');\n\n// EXCEPTIONS\n\n/**\n * OSS异常类，继承自基类\n */\nclass OSS_Exception extends Exception {}\n\n\n//检测get_loaded_extensions函数是否被禁用。由于有些版本把该函数禁用了，所以先检测该函数是否存在。\nif(function_exists('get_loaded_extensions')){\n\t//检测curl扩展\n\t$extensions = get_loaded_extensions();\n\tif($extensions){\n\t\tif(!in_array('curl', $extensions)){\n\t\t\tthrow new OSS_Exception(OSS_CURL_EXTENSION_MUST_BE_LOAD);\n\t\t}\n\t}else{\n\t\tthrow new OSS_Exception(OSS_NO_ANY_EXTENSIONS_LOADED);\n\t}\n}else{\n\tthrow new OSS_Exception('Function get_loaded_extensions has been disabled,Pls check php config.');\n}\n\n\n//CLASS\n/**\n * OSS基础类\n * @author xiaobing.meng@alibaba-inc.com\n * @since 2012-05-31\n */\nclass ALIOSS{\n\t/*%******************************************************************************************%*/\n\t// CONSTANTS\n\n\t/**\n\t * OSS服务地址\n\t */\n\tconst DEFAULT_OSS_HOST = 'oss.aliyuncs.com';\n\n\t/**\n\t * 软件名称\n\t */\n\tconst NAME = OSS_NAME;\n\n\t/**\n\t * OSS软件Build ID\n\t */\n\tconst BUILD = OSS_BUILD;\n\n\t/**\n\t * 版本号\n\t */\n\tconst VERSION = OSS_VERSION;\n\n\t/**\n\t * 作者\n\t */\n\tconst AUTHOR = OSS_AUTHOR;\n\n\t/*%******************************************************************************************%*/\n\t//OSS 内部常量\n\n\tconst OSS_BUCKET = 'bucket';\n\tconst OSS_OBJECT = 'object';\n\tconst OSS_HEADERS = 'headers';\n\tconst OSS_METHOD = 'method';\n\tconst OSS_QUERY = 'query';\n\tconst OSS_BASENAME = 'basename';\n\tconst OSS_MAX_KEYS = 'max-keys';\n\tconst OSS_UPLOAD_ID = 'uploadId';\n\tconst OSS_MAX_KEYS_VALUE = 100;\n\tconst OSS_MAX_OBJECT_GROUP_VALUE = 1000;\n\tconst OSS_FILE_SLICE_SIZE = 8192;\n\tconst OSS_PREFIX = 'prefix';\n\tconst OSS_DELIMITER = 'delimiter';\n\tconst OSS_MARKER = 'marker';\n\tconst OSS_CONTENT_MD5 = 'Content-Md5';\n\tconst OSS_CONTENT_TYPE = 'Content-Type';\n\tconst OSS_CONTENT_LENGTH = 'Content-Length';\n\tconst OSS_IF_MODIFIED_SINCE = 'If-Modified-Since';\n\tconst OSS_IF_UNMODIFIED_SINCE = 'If-Unmodified-Since';\n\tconst OSS_IF_MATCH = 'If-Match';\n\tconst OSS_IF_NONE_MATCH = 'If-None-Match';\n\tconst OSS_CACHE_CONTROL = 'Cache-Control';\n\tconst OSS_EXPIRES = 'Expires';\n\tconst OSS_PREAUTH = 'preauth';\n\tconst OSS_CONTENT_COING = 'Content-Coding';\n\tconst OSS_CONTENT_DISPOSTION = 'Content-Disposition';\n\tconst OSS_RANGE = 'Range';\n\tconst OS_CONTENT_RANGE = 'Content-Range';\n\tconst OSS_CONTENT = 'content';\n\tconst OSS_BODY = 'body';\n\tconst OSS_LENGTH = 'length';\n\tconst OSS_HOST = 'Host';\n\tconst OSS_DATE = 'Date';\n\tconst OSS_AUTHORIZATION = 'Authorization';\n\tconst OSS_FILE_DOWNLOAD = 'fileDownload';\n\tconst OSS_FILE_UPLOAD = 'fileUpload';\n\tconst OSS_PART_SIZE = 'partSize';\n\tconst OSS_SEEK_TO = 'seekTo';\n\tconst OSS_SIZE = 'size';\n\tconst OSS_QUERY_STRING = 'query_string';\n\tconst OSS_SUB_RESOURCE = 'sub_resource';\n\tconst OSS_DEFAULT_PREFIX = 'x-oss-';\n\n\t/*%******************************************************************************************%*/\n\t//私有URL变量\n\n\tconst OSS_URL_ACCESS_KEY_ID = 'OSSAccessKeyId';\n\tconst OSS_URL_EXPIRES = 'Expires';\n\tconst OSS_URL_SIGNATURE = 'Signature';\n\n\t/*%******************************************************************************************%*/\n\t//HTTP方法\n\n\tconst OSS_HTTP_GET = 'GET';\n\tconst OSS_HTTP_PUT = 'PUT';\n\tconst OSS_HTTP_HEAD = 'HEAD';\n\tconst OSS_HTTP_POST = 'POST';\n\tconst OSS_HTTP_DELETE = 'DELETE';\n\n\n\t/*%******************************************************************************************%*/\n\t//其他常量\n\n\t//x-oss\n\tconst OSS_ACL = 'x-oss-acl';\n\n\t//OBJECT GROUP\n\tconst OSS_OBJECT_GROUP = 'x-oss-file-group';\n\t\n\t//Multi Part\n\tconst OSS_MULTI_PART = 'uploads';\n\t\n\t//Multi Delete\n\tconst OSS_MULTI_DELETE = 'delete';\n\n\t//OBJECT COPY SOURCE\n\tconst OSS_OBJECT_COPY_SOURCE = 'x-oss-copy-source';\n\n\t//private,only owner\n\tconst OSS_ACL_TYPE_PRIVATE = 'private';\n\n\t//public reand\n\tconst OSS_ACL_TYPE_PUBLIC_READ = 'public-read';\n\n\t//public read write\n\tconst OSS_ACL_TYPE_PUBLIC_READ_WRITE = 'public-read-write';\n\n\t//OSS ACL数组\n\tstatic $OSS_ACL_TYPES = array(\n\tself::OSS_ACL_TYPE_PRIVATE,\n\tself::OSS_ACL_TYPE_PUBLIC_READ,\n\tself::OSS_ACL_TYPE_PUBLIC_READ_WRITE\n\t);\n\n\n\t/*%******************************************************************************************%*/\n\t// PROPERTIES\n\n\t/**\n\t * 是否使用SSL\n\t */\n\tprotected $use_ssl = false;\n\n\t/**\n\t * 是否开启debug模式\n\t */\n\tprivate $debug_mode = true;\n\t\n\t/**\n\t * 最大重试次数\n\t */\n\tprivate $max_retries = 3;\n\t\n\t/**\n\t * 已经重试次数\n\t */\n\tprivate   $redirects = 0;\t\n\t\n\t/**\n\t * 虚拟地址\n\t */\n\tprivate $vhost;\n\t\n\t/**\n\t * 路径表现方式\n\t */\n\tprivate $enable_domain_style = true;\n\t\n\t/**\n\t * 请求URL\n\t */\n\tprivate  $request_url;\n\t\n\t/**\n\t * OSS API ACCESS ID\n\t */\n\tprivate $access_id;\n\n\t/**\n\t * OSS API ACCESS KEY\n\t */\n\tprivate $access_key;\n\n\t/**\n\t * hostname\n\t */\n\tprivate $hostname;\n\t\n\t/**\n\t * port number\n\t */\n\tprivate $port;\n\n\t/*%******************************************************************************************************%*/\n\t//Constructor\n\n\t/**\n\t * 默认构造函数\n\t * @param string $_access_id (Optional)\n\t * @param string $access_key (Optional)\n\t * @param string $hostname (Optional)\n\t * @throws OSS_Exception\n\t * @author\txiaobing.meng@alibaba-inc.com\n\t * @since\t2011-11-08\n\t */\n\tpublic function __construct($access_id = NULL,$access_key = NULL, $hostname = NULL  ){\n\t\t//验证access_id,access_key\n\t\tif(!$access_id && !defined('OSS_ACCESS_ID')){\n\t\t\t\tthrow new OSS_Exception(NOT_SET_OSS_ACCESS_ID);\n\t\t}\n\n\t\tif(!$access_key && !defined('OSS_ACCESS_KEY')){\n\t\t\tthrow new OSS_Exception(NOT_SET_OSS_ACCESS_KEY);\n\t\t}\n\n\t\tif($access_id && $access_key){\n\t\t\t$this->access_id = $access_id;\n\t\t\t$this->access_key = $access_key;\n\t\t}elseif (defined('OSS_ACCESS_ID') && defined('OSS_ACCESS_KEY')){\n\t\t\t$this->access_id = OSS_ACCESS_ID;\n\t\t\t$this->access_key = OSS_ACCESS_KEY;\n\t\t}else{\n\t\t\tthrow new OSS_Exception(NOT_SET_OSS_ACCESS_ID_AND_ACCESS_KEY);\n\t\t}\n\n\t\t//校验access_id&access_key \n\t\tif(empty($this->access_id) || empty($this->access_key)){\n\t\t\tthrow new OSS_Exception(OSS_ACCESS_ID_OR_ACCESS_KEY_EMPTY);\n\t\t}\n\n\t\t//校验hostname\n\t\tif(NULL === $hostname){\n\t\t\t$this->hostname = self::DEFAULT_OSS_HOST;\n\t\t}else{\n\t\t\t$this->hostname = $hostname;\n\t\t}\n\t}\n\n\n\t/*%******************************************************************************************************%*/\n\t//属性\n\t\n\t/**\n\t * 设置debug模式\n\t * @param boolean $debug_mode (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-05-29\n\t * @return void\n\t */\n\tpublic function set_debug_mode($debug_mode = true){\n\t\t$this->debug_mode = $debug_mode;\n\t}\n\t\n\t/**\n\t * 设置最大尝试次数\n\t * @param int $max_retries\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-05-29\n\t * @return void\n\t */\n\tpublic function set_max_retries($max_retries = 3){\n\t\t$this->max_retries = $max_retries;\n\t}\n\t\n\t/**\n\t * 获取最大尝试次数\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-05-29\n\t * @return int\n\t */\n\tpublic function get_max_retries(){\n\t\treturn $this->max_retries;\n\t}\n\n\t/**\n\t * 设置host地址\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @param string $hostname host name\n\t * @param int\t$port int\n\t * @since 2012-06-11\n\t * @return void\n\t */\n\tpublic function set_host_name($hostname,$port = null){\n\t\t$this->hostname = $hostname;\n\t\t\n\t\tif($port){\n\t\t\t$this->port = $port;\n\t\t\t$this->hostname .= ':'.$port;\n\t\t}\n\t}\n\t\n\t/**\n\t * 设置vhost地址\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @param string $vhost vhost\n\t * @since 2012-06-11\n\t * @return void\n\t */\n\tpublic function set_vhost($vhost){\n\t\t$this->vhost = $vhost;\n\t}\n\t\n\t/**\n\t * 设置路径形式，如果为true,则启用三级域名，如bucket.oss.aliyuncs.com\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @param boolean $enable_domain_style \n\t * @since 2012-06-11\n\t * @return void\n\t */\n\tpublic function set_enable_domain_style($enable_domain_style = true){\n\t\t$this->enable_domain_style = $enable_domain_style;\n\t}\n\n\t\n\t/*%******************************************************************************************************%*/\n\t//请求\n\n\t/**\n\t * Authorization\n\t * @param array $options (Required)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-05-31\n\t */\n\tpublic function auth($options){\n\t\t//开始记录LOG\n\t\t$msg = \"---LOG START---------------------------------------------------------------------------\\n\";\n\t\t\n\t\t//验证Bucket,list_bucket时不需要验证\n\t\tif(!( ('/' == $options[self::OSS_OBJECT]) && ('' == $options[self::OSS_BUCKET]) && ('GET' == $options[self::OSS_METHOD])) && !$this->validate_bucket($options[self::OSS_BUCKET])){\n\t\t\tthrow new OSS_Exception('\"'.$options[self::OSS_BUCKET].'\"'.OSS_BUCKET_NAME_INVALID);\n\t\t}\n\t\n\t\t//验证Object\n\t\tif(isset($options[self::OSS_OBJECT]) && !$this->validate_object($options[self::OSS_OBJECT])){\n\t\t\tthrow  new OSS_Exception($options[self::OSS_OBJECT].OSS_OBJECT_NAME_INVALID);\n\t\t}\n\t\t\n\t\t//Object编码为UTF-8\n\t\tif($this->is_gb2312($options[self::OSS_OBJECT])){\n\t\t\t$options[self::OSS_OBJECT] = iconv('GB2312', \"UTF-8\",$options[self::OSS_OBJECT]);\n\t\t}elseif($this->check_char($options[self::OSS_OBJECT],true)){\n\t\t\t$options[self::OSS_OBJECT] = iconv('GBK', \"UTF-8\",$options[self::OSS_OBJECT]);\n\t\t}\t\n\n\t\t\n\t\t//验证ACL\n\t\tif(isset($options[self::OSS_HEADERS][self::OSS_ACL]) && !empty($options[self::OSS_HEADERS][self::OSS_ACL])){\n\t\t\tif(!in_array(strtolower($options[self::OSS_HEADERS][self::OSS_ACL]), self::$OSS_ACL_TYPES)){\n\t\t\t\tthrow new OSS_Exception($options[self::OSS_HEADERS][self::OSS_ACL].':'.OSS_ACL_INVALID);\n\t\t\t}\n\t\t}\n\n\t\t\t\t\n\t\t//定义scheme\n\t\t$scheme = $this->use_ssl ? 'https://' : 'http://';\n\t\t\n\t\t//匹配bucket\n\t\tif(strpos($options[self::OSS_BUCKET],\"-\")!== false){//bucket 带\"-\"的时候\n\t\t\t$this->set_enable_domain_style(false);\n\t\t}else{\n\t\t\t$this->set_enable_domain_style(true);\n\t\t}\n\t\t\n\t\tif($this->enable_domain_style){\n\t\t\t$hostname = $this->vhost ? $this->vhost : (($options[self::OSS_BUCKET] =='')?$this->hostname:($options[self::OSS_BUCKET].'.').$this->hostname);\n\t\t}else{\n\t\t\t$hostname = (isset($options[self::OSS_BUCKET]) && ''!==$options[self::OSS_BUCKET])?$this->hostname.'/'.$options[self::OSS_BUCKET]:$this->hostname;\n\t\t}\n\n\t\t\n\t\t//请求参数\n\t\t$resource = '';\n\t\t$sub_resource = '';\n\t\t$signable_resource = '';\n\t\t$query_string_params = array();\n\t\t$signable_query_string_params = array();\n\t\t$string_to_sign = '';\t\t\n\t\t\n\t\t$headers = array (\n\t\t\tself::OSS_CONTENT_MD5 => '',\n\t\t\tself::OSS_CONTENT_TYPE => isset($options[self::OSS_CONTENT_TYPE])?$options[self::OSS_CONTENT_TYPE]:'application/x-www-form-urlencoded',\n\t\t\tself::OSS_DATE => isset($options[self::OSS_DATE])? $options[self::OSS_DATE]: gmdate('D, d M Y H:i:s \\G\\M\\T'),\n\t\t\tself::OSS_HOST => $this->enable_domain_style?$hostname:$this->hostname,\n\t\t);\n\n\t\tif(isset ( $options [self::OSS_OBJECT] ) && '/' !== $options [self::OSS_OBJECT]){\n\t\t\t$signable_resource = '/'.str_replace('%2F', '/', rawurlencode($options[self::OSS_OBJECT]));\n\t\t}\n\n\t\tif(isset($options[self::OSS_QUERY_STRING])){\n\t\t\t$query_string_params = array_merge($query_string_params,$options[self::OSS_QUERY_STRING]);\n\t\t}\n\t\t$query_string = $this->to_query_string($query_string_params);\n\t\n\t\t$signable_list = array(\n\t\t\t'partNumber',\n\t\t\t'uploadId',\t\t\t\n\t\t);\n\t\t\n\t\tforeach ($signable_list as $item){\n\t\t\tif(isset($options[$item])){\n\t\t\t\t$signable_query_string_params[$item] = $options[$item]; \n\t\t\t}\n\t\t}\n\t\t$signable_query_string = $this->to_query_string($signable_query_string_params);\n\t\t\n\t\t//合并 HTTP headers\n\t\tif (isset ( $options [self::OSS_HEADERS] )) {\n\t\t\t$headers = array_merge ( $headers, $options [self::OSS_HEADERS] );\n\t\t}\n\t\t\n\t\t//生成请求URL\n\t\t$conjunction = '?';\n\t\t\n\t\t$non_signable_resource = '';\n\n\t\tif (isset($options[self::OSS_SUB_RESOURCE])){\n\t\t\t$signable_resource .= $conjunction . $options[self::OSS_SUB_RESOURCE];\n\t\t\t$conjunction = '&';\n\t\t}\t\n\n\t\tif($signable_query_string !== ''){\n\t\t\t$signable_query_string = $conjunction.$signable_query_string;\n\t\t\t$conjunction = '&';\n\t\t}\n\t\t\n\t\tif($query_string !== ''){\n\t\t\t$non_signable_resource .= $conjunction . $query_string;\n\t\t\t$conjunction = '&';\t\t\t\n\t\t}\n\t\t\n\t\t$this->request_url = \t $scheme . $hostname . $signable_resource . $signable_query_string . $non_signable_resource;\n\n\t\t$msg .= \"--REQUEST URL:----------------------------------------------\\n\".$this->request_url.\"\\n\";\n\t\t\n\t\t//创建请求\n\t\t$request = new RequestCore($this->request_url);\n\t\t \n\t\t// Streaming uploads\n\t\tif (isset($options[self::OSS_FILE_UPLOAD])){\n\t\t\tif (is_resource($options[self::OSS_FILE_UPLOAD])){\n\t\t\t\t$length = null; \n\n\t\t\t\tif (isset($options[self::OSS_CONTENT_LENGTH])){\n\t\t\t\t\t$length = $options[self::OSS_CONTENT_LENGTH];\n\t\t\t\t}elseif (isset($options[self::OSS_SEEK_TO])){\n\t\t\t\t\t\n\t\t\t\t\t$stats = fstat($options[self::OSS_FILE_UPLOAD]);\n\n\t\t\t\t\tif ($stats && $stats[self::OSS_SIZE] >= 0){\n\t\t\t\t\t\t$length = $stats[self::OSS_SIZE] - (integer) $options[self::OSS_SEEK_TO];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$request->set_read_stream($options[self::OSS_FILE_UPLOAD], $length);\n\n\t\t\t\tif ($headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded'){\n\t\t\t\t\t$headers[self::OSS_CONTENT_TYPE] = 'application/octet-stream';\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\t$request->set_read_file($options[self::OSS_FILE_UPLOAD]);\n\n\t\t\t\t$length = $request->read_stream_size; \n\n\t\t\t\tif (isset($options[self::OSS_CONTENT_LENGTH])){\n\t\t\t\t\t$length = $options[self::OSS_CONTENT_LENGTH];\n\t\t\t\t}elseif (isset($options[self::OSS_SEEK_TO]) && isset($length)){\n\t\t\t\t\t$length -= (integer) $options[self::OSS_SEEK_TO];\n\t\t\t\t}\n\n\t\t\t\t$request->set_read_stream_size($length);\n\n\t\t\t\tif (isset($headers[self::OSS_CONTENT_TYPE]) && ($headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded')){\n\t\t\t\t\t$extension = explode('.', $options[self::OSS_FILE_UPLOAD]);\n\t\t\t\t\t$extension = array_pop($extension);\n\t\t\t\t\t$mime_type = MimeTypes::get_mimetype($extension);\n\t\t\t\t\t$headers[self::OSS_CONTENT_TYPE] = $mime_type;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$options[self::OSS_CONTENT_MD5] = '';\n\t\t}\n\n\t\tif (isset($options[self::OSS_SEEK_TO])){\n\t\t\t$request->set_seek_position((integer) $options[self::OSS_SEEK_TO]);\n\t\t}\t\n\n\t\tif (isset($options[self::OSS_FILE_DOWNLOAD])){\n\t\t\tif (is_resource($options[self::OSS_FILE_DOWNLOAD])){\n\t\t\t\t$request->set_write_stream($options[self::OSS_FILE_DOWNLOAD]);\n\t\t\t}else{\n\t\t\t\t$request->set_write_file($options[self::OSS_FILE_DOWNLOAD]);\n\t\t\t}\n\t\t}\t\t\n\t\t\n\t\t\n\t\tif(isset($options[self::OSS_METHOD])){\n\t\t\t$request->set_method($options[self::OSS_METHOD]);\n\t\t\t$string_to_sign .= $options[self::OSS_METHOD] . \"\\n\";\t\t\t\n\t\t}\n\t\t\n\t\tif (isset ( $options [self::OSS_CONTENT] )) {\n\t\t\t$request->set_body ( $options [self::OSS_CONTENT] );\n\t\t\tif ($headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded'){\n\t\t\t\t$headers[self::OSS_CONTENT_TYPE] = 'application/octet-stream';\n\t\t\t}\t\t\t\n\t\t\t\n\t\t\t$headers[self::OSS_CONTENT_LENGTH] = strlen($options [self::OSS_CONTENT]);\n\t\t\t$headers[self::OSS_CONTENT_MD5] = $this->hex_to_base64(md5($options[self::OSS_CONTENT]));\n\t\t}\n\n\t\tuksort($headers, 'strnatcasecmp');\n\t\t\n\t\tforeach ( $headers as $header_key => $header_value ) {\n\t\t\t$header_value = str_replace ( array (\"\\r\", \"\\n\" ), '', $header_value );\n\t\t\tif ($header_value !== '') {\n\t\t\t\t$request->add_header ( $header_key, $header_value );\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tstrtolower($header_key) === 'content-md5' ||\n\t\t\t\tstrtolower($header_key) === 'content-type' ||\n\t\t\t\tstrtolower($header_key) === 'date' ||\n\t\t\t\t(isset($options['self::OSS_PREAUTH']) && (integer) $options['self::OSS_PREAUTH'] > 0)\n\t\t\t){\n\t\t\t\t$string_to_sign .= $header_value . \"\\n\";\n\t\t\t}elseif (substr(strtolower($header_key), 0, 6) === self::OSS_DEFAULT_PREFIX){\n\t\t\t\t$string_to_sign .= strtolower($header_key) . ':' . $header_value . \"\\n\";\n\t\t\t}\t\t\t\n\t\t}\n\t\n\t\t$string_to_sign .= '/' . $options[self::OSS_BUCKET];\n\t\t$string_to_sign .=  $this->enable_domain_style ? ($options[self::OSS_BUCKET]!=''? ($options[self::OSS_OBJECT]=='/'?'/':'') :'' ) : '';\n\t\t$string_to_sign .= rawurldecode($signable_resource) . urldecode($signable_query_string);\n\n\t\t$msg .= \"STRING TO SIGN:----------------------------------------------\\n\".$string_to_sign.\"\\n\";\n\t\t\n\t\t$signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->access_key, true));\n\t\t$request->add_header('Authorization', 'OSS ' . $this->access_id . ':' . $signature);\n\n\t\tif (isset($options[self::OSS_PREAUTH]) && (integer) $options[self::OSS_PREAUTH] > 0){\n\t\t\treturn $this->request_url . $conjunction . self::OSS_URL_ACCESS_KEY_ID.'=' . $this->access_id . '&'.self::OSS_URL_EXPIRES.'=' . $options[self::OSS_PREAUTH] . '&'.self::OSS_URL_SIGNATURE.'=' . rawurlencode($signature);\n\t\t}elseif (isset($options[self::OSS_PREAUTH])){\n\t\t\treturn $this->request_url;\n\t\t}\t\t\n\t\t\n\t\tif ($this->debug_mode){\n\t\t\t$request->debug_mode = $this->debug_mode;\n\t\t}\n\n\t\t$msg .= \"REQUEST HEADERS:----------------------------------------------\\n\".serialize($request->request_headers).\"\\n\";\n\t\t\n\t\t$request->send_request();\n\n\t\t$response_header = $request->get_response_header();\n\t\t$response_header['x-oss-request-url'] = $this->request_url;\n\t\t$response_header['x-oss-redirects'] = $this->redirects;\n\t\t$response_header['x-oss-stringtosign'] = $string_to_sign;\n\t\t$response_header['x-oss-requestheaders'] = $request->request_headers;\t\t\t\t\n\t\t\n\t\t$msg .= \"RESPONSE HEADERS:----------------------------------------------\\n\".serialize($response_header).\"\\n\";\n\t\t\n\t\t$data =  new ResponseCore ( $response_header , $request->get_response_body (), $request->get_response_code () );\n\t\t\n\t\tif((integer)$request->get_response_code() === 400 /*Bad Request*/ || (integer)$request->get_response_code() === 500 /*Internal Error*/ || (integer)$request->get_response_code() === 503 /*Service Unavailable*/){\t\n\t\t   if($this->redirects <= $this->max_retries ){\n\t\t   \t\t//设置休眠\n\t\t   \t\t$delay = (integer) (pow(4, $this->redirects) * 100000);\n\t\t   \t\tusleep($delay);\n\t\t   \t\t$this->redirects++;\n\t\t   \t\t$data = $this->auth($options);\n\t\t   }\n\t\t}\n\t\t\n\t\t$msg .= \"RESPONSE DATA:----------------------------------------------\\n\".serialize($data).\"\\n\";\n\t\t$msg .= date('Y-m-d H:i:s').\":---LOG END---------------------------------------------------------------------------\\n\";\n\t\t//add log\n\t\t$this->log($msg);\n\t\t\n\t\t$this->redirects = 0;\t\n\t\treturn $data;\n\t}\n\n\n\t/*%******************************************************************************************************%*/\n\t//Service Operation\n\n\t/**\n\t * Get Buket list\n\t * @param array $options (Optional)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function list_bucket($options = NULL) {\n\t\t//$options\n\t\t$this->validate_options($options);\n\n\t\tif (! $options) {\n\t\t\t$options = array ();\n\t\t}\n\n\t\t$options[self::OSS_BUCKET] = '';\n\t\t$options[self::OSS_METHOD] = 'GET';\n\t\t$options[self::OSS_OBJECT] = '/';\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\n\t/*%******************************************************************************************************%*/\n\t//Bucket Operation\n\n\t/**\n\t * Create Bucket\n\t * @param string $bucket (Required)\n\t * @param string $acl (Optional)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function create_bucket($bucket,$acl = self::OSS_ACL_TYPE_PRIVATE, $options = NULL){\n\t\t//$options\n\t\t$this->validate_options($options);\n\n\t\tif (! $options) {\n\t\t\t$options = array ();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'PUT';\n\t\t$options[self::OSS_OBJECT] = '/';\n\t\t$options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl);\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Delete Bucket\n\t * @param string $bucket (Required)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function delete_bucket($bucket,$options = NULL){\n\t\t//$options\n\t\t$this->validate_options($options);\n\n\t\tif (! $options) {\n\t\t\t$options = array ();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'DELETE';\n\t\t$options[self::OSS_OBJECT] = '/';\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Get Bucket's ACL\n\t * @param string $bucket (Required)\n\t * @param array $options (Optional)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function get_bucket_acl($bucket ,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'GET';\n\t\t$options[self::OSS_OBJECT] = '/';\n\t\t$options[self::OSS_SUB_RESOURCE] = 'acl';\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * Set bucket'ACL\n\t * @param string $bucket (Required)\n\t * @param string $acl  (Required)\n\t * @param array $options (Optional)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function set_bucket_acl($bucket ,$acl , $options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'PUT';\n\t\t$options[self::OSS_OBJECT] = '/';\n\t\t$options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl);\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\n\t/*%******************************************************************************************************%*/\n\t//Object Operation\n\n\t/**\n\t * List Object\n\t * @param string $bucket (Required)\n\t * @param array $options (Optional)\n\t * 其中options中的参数如下\n\t * $options = array(\n\t * \t\t'max-keys' \t=> max-keys用于限定此次返回object的最大数，如果不设定，默认为100，max-keys取值不能大于100。\n\t * \t\t'prefix'\t=> 限定返回的object key必须以prefix作为前缀。注意使用prefix查询时，返回的key中仍会包含prefix。\n\t * \t\t'delimiter' => 是一个用于对Object名字进行分组的字符。所有名字包含指定的前缀且第一次出现delimiter字符之间的object作为一组元素\n\t * \t\t'marker'\t=> 用户设定结果从marker之后按字母排序的第一个开始返回。\n\t * )\n\t * 其中 prefix，marker用来实现分页显示效果，参数的长度必须小于256字节。\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function list_object($bucket,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'GET';\n\t\t$options[self::OSS_OBJECT] = '/';\n\t\t$options[self::OSS_HEADERS] = array(\n\t\tself::OSS_DELIMITER => isset($options[self::OSS_DELIMITER])?$options[self::OSS_DELIMITER]:'/',\n\t\tself::OSS_PREFIX => isset($options[self::OSS_PREFIX])?$options[self::OSS_PREFIX]:'',\n\t\tself::OSS_MAX_KEYS => isset($options[self::OSS_MAX_KEYS])?$options[self::OSS_MAX_KEYS]:self::OSS_MAX_KEYS_VALUE,\n\t\tself::OSS_MARKER => isset($options[self::OSS_MARKER])?$options[self::OSS_MARKER]:'',\n\t\t);\n\t\t\t\t\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\n\t}\n\n\t/**\n\t * 创建目录(目录和文件的区别在于，目录最后增加'/')\n\t * @param string $bucket\n\t * @param string $object\n\t * @param array $options\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function create_object_dir($bucket,$object,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'PUT';\n\t\t$options[self::OSS_OBJECT] = $object.'/';   //虚拟目录需要以'/结尾'\n\t\t$options[self::OSS_CONTENT_LENGTH] = array(self::OSS_CONTENT_LENGTH => 0);\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * 通过在http body中添加内容来上传文件，适合比较小的文件\n\t * 根据api约定，需要在http header中增加content-length字段\n\t * @param string $bucket (Required)\n\t * @param string $object (Required)\n\t * @param string $content (Required)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function upload_file_by_content($bucket,$object,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//内容校验\n\t\t$this->validate_content($options);\n\n\t\t\t\n\t\t$objArr = explode('/', $object);\n\t\t$basename = array_pop($objArr);\n\t\t$extension = explode ( '.', $basename );\n\t\t$extension = array_pop ( $extension );\n\t\t$content_type = MimeTypes::get_mimetype(strtolower($extension));\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'PUT';\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t\n\t\tif(!isset($options[self::OSS_LENGTH])){\n\t\t\t$options[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]);\n\t\t}else{\n\t\t\t$options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH];\n\t\t}\n\t\t\n\t\tif(!isset($options[self::OSS_CONTENT_TYPE]) && isset($content_type) && !empty($content_type) ){\n\t\t\t$options[self::OSS_CONTENT_TYPE] = $content_type;\n\t\t}\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * 上传文件，适合比较大的文件\n\t * @param string $bucket (Required)\n\t * @param string $object (Required)\n\t * @param string $file (Required)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-02-28\n\t * @return ResponseCore\n\t */\n\tpublic function upload_file_by_file($bucket,$object,$file,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//file\n\t\t$this->is_empty($file, OSS_FILE_PATH_IS_NOT_ALLOWED_EMPTY);\n\t\t\n\t\tif($this->chk_chinese($file)){\n\t\t\t$file = iconv('utf-8','gbk',$file);\n\t\t}\n\t\t\n\t\t$options[self::OSS_FILE_UPLOAD] = $file;\n\t\t\n\t\tif(!file_exists($options[self::OSS_FILE_UPLOAD])){\n\t\t\tthrow new OSS_Exception($options[self::OSS_FILE_UPLOAD].OSS_FILE_NOT_EXIST);\n\t\t}\n\t\t\n\t\t$filesize = filesize($options[self::OSS_FILE_UPLOAD]);\n\t\t$partsize = 1024 * 1024 ; //默认为 1M\n\t\t\n\t\t\n\t\t$extension = explode ( '.', $file );\n\t\t$extension = array_pop ( $extension );\n\t\t$content_type = MimeTypes::get_mimetype(strtolower($extension));\n\t\t\t\t\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_PUT;\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t$options[self::OSS_CONTENT_TYPE] = $content_type;\n\t\t$options[self::OSS_CONTENT_LENGTH] = $filesize;\n\t\t\t\t\n\t\t$response = $this->auth($options);\n\t\treturn $response;\n\t}\n\t\n\t\n\t/**\n\t * 拷贝Object\n\t * @param string $bucket (Required)\n\t * @param string $from_object (Required)\n\t * @param string $to_object (Required)\n\t * @param string $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-21\n\t * @return ResponseCore\n\t */\n\tpublic function copy_object($from_bucket,$from_object,$to_bucket,$to_object,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//from bucket\n\t\t$this->is_empty($from_bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//to bucket\n\t\t$this->is_empty($to_bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//from object\n\t\t$this->is_empty($from_object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//to object\n\t\t$this->is_empty($to_object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $to_bucket;\n\t\t$options[self::OSS_METHOD] = 'PUT';\n\t\t$options[self::OSS_OBJECT] = $to_object;\n\t\t$options[self::OSS_HEADERS] = array(self::OSS_OBJECT_COPY_SOURCE => '/'.$from_bucket.'/'.$from_object);\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * 获得object的meta信息\n\t * @param string $bucket (Required)\n\t * @param string $object (Required)\n\t * @param string $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function get_object_meta($bucket,$object,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'HEAD';\n\t\t$options[self::OSS_OBJECT] = $object;\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * 删除object\n\t * @param string $bucket(Required)\n\t * @param string $object (Required)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function delete_object($bucket,$object,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'DELETE';\n\t\t$options[self::OSS_OBJECT] = $object;\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\t\n\t/**\n\t * 批量删除objects\n\t * @param string $bucket(Required)\n\t * @param array $objects (Required)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-03-09\n\t * @return ResponseCore\n\t */\n\tpublic function delete_objects($bucket,$objects,$options = null){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//objects\n\t\tif(!is_array($objects) || !$objects){\n\t\t\tthrow new OSS_Exception('The ' . __FUNCTION__ . ' method requires the \"objects\" option to be set as an array.');\n\t\t}\n\t\t\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_POST;\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = '/';\n\t\t$options[self::OSS_SUB_RESOURCE] = 'delete';\n\t\t$options[self::OSS_CONTENT_TYPE] = 'application/xml';\n\t\t\n\t\t$xml = new SimpleXMLElement('<?xml version=\"1.0\" encoding=\"utf-8\"?><Delete></Delete>');\n\t\t\n\t\t// Quiet mode?\n\t\tif (isset($options['quiet'])){\n\t\t\t$quiet = 'false';\n\t\t\tif (is_bool($options['quiet'])) { //Boolean\n\t\t\t\t$quiet = $options['quiet'] ? 'true' : 'false';\n\t\t\t}elseif (is_string($options['quiet'])){ // String\n\t\t\t\t$quiet = ($options['quiet'] === 'true') ? 'true' : 'false';\n\t\t\t}\n\n\t\t\t$xml->addChild('Quiet', $quiet);\n\t\t}\n\t\t\t\t\n\t\t// Add the objects\n\t\tforeach ($objects as $object){\n\t\t\t$xobject = $xml->addChild('Object');\n\t\t\t$object = $this->s_replace($object);\t\t\n\t\t\t$xobject->addChild('Key', $object);\n\t\t}\t\t\n\n\t\t$options[self::OSS_CONTENT] = $xml->asXML();\t\t\n\t\t\t\n\t\treturn $this->auth($options);\n\t}\n\n\t/**\n\t * 获得Object内容\n\t * @param string $bucket(Required)\n\t * @param string $object (Required)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function get_object($bucket,$object,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\t\t\n\t\tif(isset($options[self::OSS_FILE_DOWNLOAD]) && $this->chk_chinese($options[self::OSS_FILE_DOWNLOAD])){\n\t\t\t$options[self::OSS_FILE_DOWNLOAD] = iconv('utf-8','gbk',$options[self::OSS_FILE_DOWNLOAD]);\n\t\t}\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'GET';\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t\n\t\tif(isset($options['lastmodified'])){\n\t\t\t$options[self::OSS_HEADERS][self::OSS_IF_MODIFIED_SINCE] = $options['lastmodified'];\n            unset($options['lastmodified']);\n\t\t}\n\t\t\n\t\tif(isset($options['etag'])){\n\t\t\t$options[self::OSS_HEADERS][self::OSS_IF_NONE_MATCH] = $options['etag'];\n            unset($options['etag']);\n\t\t}\n\t\t\n\t\tif(isset($options['range'])){\n\t\t\t$options[self::OSS_HEADERS][self::OSS_RANGE] = 'bytes=' . $options['range'];\n            unset($options['range']);\n\t\t}\n\t\t\n\t\treturn $this->auth ( $options );\n\t}\n\n\t/**\n\t * 检测Object是否存在\n\t * @param string $bucket(Required)\n\t * @param string $object (Required)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return boolean\n\t */\n\tpublic function is_object_exist($bucket,$object,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'GET';\n\t\t$options[self::OSS_OBJECT] = $object;\n\n\t\t$response = $this->get_object_meta($bucket, $object,$options);\n\n\t\treturn $response;\n\t}\n\n\n\t/*%******************************************************************************************************%*/\n\t//Multi Part相关操作\t\n\t\n\t/**\n\t * 计算文件可以分成多少个part，以及每个part的长度以及起始位置\n\t * 方法必须在 <upload_part()>中调用\n\t *\n\t * @param integer $filesize (Required) 文件大小\n\t * @param integer $part_size (Required) part大小,默认5M\n\t * @return array An array 包含 key-value 键值对. Key 为 `seekTo` 和 `length`.\n\t */\t\n\tpublic function get_multipart_counts($filesize, $part_size = 5242880 ){\n\t\t$i = 0;\n\t\t$sizecount = $filesize;\n\t\t$values = array();\n\n\t\tif((integer)$part_size <= 5242880){ \n\t\t\t$part_size = 5242880;\t//5M\n\t\t}elseif ((integer)$part_size > 524288000){\n\t\t\t$part_size = 524288000; //500M\n\t\t}else{\n\t\t\t$part_size = 52428800; //50M\n\t\t}\t\t\n\t\t\n\t\twhile ($sizecount > 0)\n\t\t{\n\t\t\t$sizecount -= $part_size;\n\t\t\t$values[] = array(\n\t\t\t\tself::OSS_SEEK_TO => ($part_size * $i),\n\t\t\t\tself::OSS_LENGTH => (($sizecount > 0) ? $part_size : ($sizecount + $part_size)),\n\t\t\t);\n\t\t\t$i++;\n\t\t}\n\n\t\treturn $values;\t\t\n\t}\n\t\n\t/**\n\t * 初始化multi-part upload，并且返回uploadId\n\t * @param string $bucket (Required) Bucket名称\n\t * @param string $object (Required) Object名称\n\t * @param array $options (Optional) Key-Value数组，其中可以包括以下的key\n\t * @return ResponseCore\n\t */\n\tpublic function initiate_multipart_upload($bucket,$object,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t// 发送请求\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_POST;\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t$options[self::OSS_SUB_RESOURCE] = 'uploads';\n\t\t$options[self::OSS_CONTENT] = '';\n\t\t//$options[self::OSS_CONTENT_LENGTH] = 0;\n\t\t$options[self::OSS_HEADERS] = array(self::OSS_CONTENT_TYPE => 'application/octet-stream');\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\t\t\n\t}\n\t\n\t/**\n\t * 上传part\n\t * @param string $bucket (Required) Bucket名称\n\t * @param string $object (Required) Object名称\n\t * @param string $upload_id (Required) uploadId\n\t * @param array $options (Optional) Key-Value数组，其中可以包括以下的key\n\t * @return ResponseCore\n\t */\n\tpublic function upload_part($bucket, $object, $upload_id, $options = null){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\tif (!isset($options[self::OSS_FILE_UPLOAD]) || !isset($options['partNumber'])){\n\t\t\tthrow new OSS_Exception('The `fileUpload` and `partNumber` options are both required in ' . __FUNCTION__ . '().');\n\t\t}\n\t\t\t\t\t\t\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_PUT;\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t$options[self::OSS_UPLOAD_ID] = $upload_id;\t\n\t\t\n\t\tif(isset($options[self::OSS_LENGTH])){\n\t\t\t$options[self::OSS_CONTENT_LENGTH] =  $options[self::OSS_LENGTH];\n\t\t}\n\n\t\treturn $this->auth($options);\n\t}\n\t\n\t/**\n\t * list part\n\t * @param string $bucket (Required) Bucket名称\n\t * @param string $object (Required) Object名称\n\t * @param string $upload_id (Required) uploadId\n\t * @param array $options (Optional) Key-Value数组，其中可以包括以下的key\n\t * @return ResponseCore\n\t */\t\n\tpublic function list_parts($bucket, $object, $upload_id, $options = null){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_GET;\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t$options[self::OSS_UPLOAD_ID] = $upload_id;\n\t\t$options[self::OSS_QUERY_STRING] = array();\n\n\t\tforeach (array('max-parts', 'part-number-marker') as $param){\n\t\t\tif (isset($options[$param])){\n\t\t\t\t$options[self::OSS_QUERY_STRING][$param] = $options[$param];\n\t\t\t\tunset($options[$param]);\n\t\t\t}\n\t\t}\t\n\n\t\treturn $this->auth($options);\n\t}\n\t\n\t/**\n\t * 中止上传mulit-part upload\n\t * @param string $bucket (Required) Bucket名称\n\t * @param string $object (Required) Object名称\n\t * @param string $upload_id (Required) uploadId\n\t * @param array $options (Optional) Key-Value数组，其中可以包括以下的key\n\t * @return ResponseCore\n\t */\t\n\tpublic function abort_multipart_upload($bucket, $object, $upload_id, $options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t$options[self::OSS_UPLOAD_ID] = $upload_id;\n\t\t\n\t\treturn $this->auth($options);\n\t}\n\t\n\t/**\n\t * 完成multi-part上传\n\t * @param string $bucket (Required) Bucket名称\n\t * @param string $object (Required) Object名称\n\t * @param string $upload_id (Required) uploadId\n\t * @param string $parts xml格式文件\n\t * @param array $options (Optional) Key-Value数组，其中可以包括以下的key\n\t * @return ResponseCore\n\t */\t\n\tpublic function complete_multipart_upload($bucket, $object, $upload_id, $parts, $options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\t\t\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_POST;\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t$options[self::OSS_UPLOAD_ID] = $upload_id;\n\t\t$options[self::OSS_CONTENT_TYPE] = 'application/xml';\n\n\t\t\n\t\tif(is_string($parts)){\n\t\t\t$options[self::OSS_CONTENT] = $parts;\n\t\t}else if($parts instanceof SimpleXMLElement){\n\t\t\t$options[self::OSS_CONTENT] = $parts->asXML();\n\t\t}else if((is_array($parts) || $parts instanceof ResponseCore)){\n\t\t\t$xml = new SimpleXMLElement('<?xml version=\"1.0\" encoding=\"utf-8\"?><CompleteMultipartUpload></CompleteMultipartUpload>');\n\n\t\t\tif (is_array($parts)){\n\t\t\t\t//生成关联的xml\n\t\t\t\tforeach ($parts as $node){\n\t\t\t\t\t$part = $xml->addChild('Part');\n\t\t\t\t\t$part->addChild('PartNumber', $node['PartNumber']);\n\t\t\t\t\t$part->addChild('ETag', $node['ETag']);\n\t\t\t\t}\n\t\t\t}elseif ($parts instanceof ResponseCore){\n\t\t\t\tforeach ($parts->body->Part as $node){\n\t\t\t\t\t$part = $xml->addChild('Part');\n\t\t\t\t\t$part->addChild('PartNumber', (string) $node->PartNumber);\n\t\t\t\t\t$part->addChild('ETag', (string) $node->ETag);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$options[self::OSS_CONTENT] = $xml->asXML();\t\t\t\n\t\t}\n\t\n\t\treturn $this->auth($options);\t\t\n\t}\n\t\n\t/**\n\t * 列出multipart上传\n\t * @param string $bucket (Requeired) bucket \n\t * @param array $options (Optional) 关联数组\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-03-05\n\t * @return ResponseCore\n\t */\n\tpublic function list_multipart_uploads($bucket, $options = null){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_GET;\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = '/';\n\t\t$options[self::OSS_SUB_RESOURCE] = 'uploads';\n\n\t\tforeach (array('key-marker', 'max-uploads', 'upload-id-marker') as $param){\n\t\t\tif (isset($options[$param])){\n\t\t\t\t$options[self::OSS_QUERY_STRING][$param] = $options[$param];\n\t\t\t\tunset($options[$param]);\n\t\t\t}\n\t\t}\n\t\t\t\t\n\t\treturn $this->auth($options);\n\t}\n\t\n\t/**\n\t * multipart上传统一封装，从初始化到完成multipart，以及出错后中止动作\n\t * @param unknown_type $bucket\n\t * @param unknown_type $object\n\t * @param unknown_type $options\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-03-05\n\t * @return ResponseCore \n\t */\n\tpublic function create_mpu_object($bucket, $object, $options = null){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\tif(isset($options[self::OSS_LENGTH])){\n\t\t\t$options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH];\n\t\t\tunset($options[self::OSS_LENGTH]);\n\t\t}\n\t\t\n\t\tif(isset($options[self::OSS_FILE_UPLOAD])){\n\t\t\tif($this->chk_chinese($options[self::OSS_FILE_UPLOAD])){\n\t\t\t\t$options[self::OSS_FILE_UPLOAD] = mb_convert_encoding($options[self::OSS_FILE_UPLOAD],'UTF-8');\n\t\t\t}\t\t\t\n\t\t}\n\t\t\n\t\tif(!isset($options[self::OSS_FILE_UPLOAD])){\n\t\t\tthrow new OSS_Exception('The `fileUpload` option is required in ' . __FUNCTION__ . '().');\n\t\t}elseif (is_resource($options[self::OSS_FILE_UPLOAD])){\t\t\t\t\t\n\t\t\t$upload_position = isset($options[self::OSS_SEEK_TO]) ? (integer) $options[self::OSS_SEEK_TO] : ftell($options[self::OSS_FILE_UPLOAD]);\n\t\t\t$upload_filesize = isset($options[self::OSS_CONTENT_LENGTH]) ? (integer) $options[self::OSS_CONTENT_LENGTH] : null;\n\n\t\t\tif (!isset($upload_filesize) && $upload_position !== false){\n\t\t\t\t$stats = fstat($options[self::OSS_FILE_UPLOAD]);\n\n\t\t\t\tif ($stats && $stats[self::OSS_SIZE] >= 0){\n\t\t\t\t\t$upload_filesize = $stats[self::OSS_SIZE] - $upload_position;\n\t\t\t\t}\n\t\t\t}\t\t\t\n\t\t}else{\n\t\t\t$upload_position = isset($options[self::OSS_SEEK_TO]) ? (integer) $options[self::OSS_SEEK_TO] : 0;\n\n\t\t\tif (isset($options[self::OSS_CONTENT_TYPE])){\n\t\t\t\t$upload_filesize = (integer) $options[self::OSS_CONTENT_TYPE];\n\t\t\t}\n\t\t\telse{\n\t\t\t\t$upload_filesize = filesize($options[self::OSS_FILE_UPLOAD]);\n\n\t\t\t\tif ($upload_filesize !== false){\n\t\t\t\t\t$upload_filesize -= $upload_position;\n\t\t\t\t}\n\t\t\t}\t\t\t\n\t\t}\n\t\t\n\t\tif ($upload_position === false || !isset($upload_filesize) || $upload_filesize === false || $upload_filesize < 0){\n\t\t\tthrow new OSS_Exception('The size of `fileUpload` cannot be determined in ' . __FUNCTION__ . '().');\n\t\t}\n\t\t\n\t\t// 处理partSize\n\t\tif (isset($options[self::OSS_PART_SIZE])){\n\t\t\t// 小于5M\n\t\t\tif ((integer) $options[self::OSS_PART_SIZE] <= 5242880){\n\t\t\t\t$options[self::OSS_PART_SIZE] = 5242880; // 5 MB\n\t\t\t}\n\t\t\t// 大于500M\n\t\t\telseif ((integer) $options[self::OSS_PART_SIZE] > 524288000){\n\t\t\t\t$options[self::OSS_PART_SIZE] = 524288000; // 500 MB\n\t\t\t}\n\t\t}\n\t\telse{\n\t\t\t$options[self::OSS_PART_SIZE] = 52428800; // 50 MB\n\t\t}\n\n\t\t// 如果上传的文件小于partSize,则直接使用普通方式上传\n\t\tif ($upload_filesize < $options[self::OSS_PART_SIZE] && !isset($options['uploadId'])){\n\t\t\treturn $this->upload_file_by_file($bucket, $object, $options[self::OSS_FILE_UPLOAD]);\n\t\t}\t\n\n\t\t// 初始化multipart\n\t\tif (isset($options['uploadId'])){\n\t\t\t$upload_id = $options['uploadId'];\n\t\t}else{\n\t\t\t//初始化\n\t\t\t$upload = $this->initiate_multipart_upload($bucket, $object);\n\t\t\t\n\t\t\tif (!$upload->isOK()){\n\t\t\t\tthrow new OSS_Exception('Init multi-part upload failed...');\n\t\t\t}\n\t\t\t$xml = new SimpleXmlIterator($upload->body);\n\t\t\t$uploadId = (string)$xml->UploadId;\n\t\t}\t\t\n\n\t\t// 或的分片\n\t\t$pieces = $this->get_multipart_counts($upload_filesize, (integer) $options[self::OSS_PART_SIZE]);\n\n\t\t$response_upload_part = array();\n\t\tforeach ($pieces as $i => $piece){\n\t\t\t$response_upload_part[] = $this->upload_part($bucket, $object, $uploadId, array(\n\t\t\t\t//'expect' => '100-continue',\n\t\t\t\tself::OSS_FILE_UPLOAD => $options[self::OSS_FILE_UPLOAD],\n\t\t\t\t'partNumber' => ($i + 1),\n\t\t\t\tself::OSS_SEEK_TO => $upload_position + (integer) $piece[self::OSS_SEEK_TO],\n\t\t\t\tself::OSS_LENGTH => (integer) $piece[self::OSS_LENGTH],\n\t\t\t));\n\t\t}\n\t\t\n\t\t$upload_parts = array();\n\t\t$upload_part_result = true;\n\t\t\n\t\tforeach ($response_upload_part as $i=>$response){\n\t\t\t$upload_part_result = $upload_part_result && $response->isOk();\n\t\t}\n\t\t\n\t\tif(!$upload_part_result){\n\t\t\tthrow new OSS_Exception('any part upload failed...,pls try again');\n\t\t}\n\t\t\n\t\tforeach ($response_upload_part as $i=>$response){\n\t\t\t$upload_parts[] = array(\n\t\t\t\t'PartNumber' => ($i + 1),\n\t\t\t    'ETag' => (string) $response->header['etag']\n\t\t\t);\t\t\n\t\t}\n\t\t\t\t\n\t\treturn $this->complete_multipart_upload($bucket, $object, $uploadId, $upload_parts);\n\t}\n\t\n\t\n\t/**\n\t * 通过Multi-Part方式上传整个目录，其中的object默认为文件名\n\t * @param string $bucket (Required) \n\t * @param string $dir  (Required) 必选\n\t * @param boolean $recursive (Optional) 是否递归，如果为true，则递归读取所有目录，默认为不递归读取\n\t * @param string $exclude 需要过滤的文件\n\t * @param array $options (Optional) 关联数组\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-03-05\n\t * @return ResponseCore \n\t */\n\tpublic function create_mtu_object_by_dir($bucket,$dir,$recursive = false,$exclude = \".|..|.svn\",$options = null){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\tif($this->chk_chinese($dir)){\n\t\t\t$dir = iconv('utf-8','gbk',$dir);\n\t\t}\n\t\t\n\t\t//判断是否目录\n\t\tif(!is_dir($dir)){\n\t\t\tthrow new OSS_Exception($dir.' is not a directory...,pls check it');\n\t\t}\n\t\t\n\t\t$file_list_array = $this->read_dir($dir,$exclude,$recursive);\n\t\t\t\t\n\t\tif(!$file_list_array){\n\t\t\tthrow new OSS_Exception($dir.' is empty...');\n\t\t}\n\t\t\n\t\t$index = 1;\n\t\t\n\t\tforeach ($file_list_array as $item){\n\t\t\t$options = array(\n\t\t\t\tself::OSS_FILE_UPLOAD => $item['path'],\n\t\t\t\tself::OSS_PART_SIZE => 5242880,\n\t\t\t);\t\t\t\n\t\t\t\n\t\t\techo $index++.\". \";\n\t\t\t$response = $this->create_mpu_object($bucket, $item['file'],$options);\n\t\t\tif($response->isOK()){\n\t\t\t\techo \"Upload file {\".$item['path'].\" } successful..\\n\";\n\t\t\t}else{\n\t\t\t\techo \"Upload file {\".$item['path'].\" } failed..\\n\";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\t\n\t/**\n\t * 通过multi-part方式上传目录(优化版)\n\t * $options = array(\n\t * \t\t'bucket' \t=>  (Required)\n\t * \t\t'object' \t=>  (Optional)\n\t * \t\t'directory' =>  (Required)\n\t * \t\t'exclude'\t=>  (Optional)\n\t * \t\t'recursive' =>  (Optional)\n\t * )\n\t */\n\tpublic function batch_upload_file($options = NULL){\n\t\tif((NULL == $options) || !isset($options['bucket']) || empty($options['bucket']) || !isset($options['directory']) ||empty($options['directory']) ) {\n\t\t\tthrow new OSS_Exception('Bad Request',400);\n\t\t}\n\t\t\n\t\t$bucket = $options['bucket']; unset($options['bucket']);\n\t\t\n\t\t$directory = $options['directory']; unset($options['directory']);\n\t\tif($this->chk_chinese($directory)){\n\t\t\t$directory = iconv('utf-8','gbk',$directory);\n\t\t}\t\t\n\t\t\n\t\t//判断是否目录\n\t\tif(!is_dir($directory)){\n\t\t\tthrow new OSS_Exception($dir.' is not a directory...,pls check it');\n\t\t}\n\t\t\t\t\n\t\t$object = '';\n\t\tif(isset($options['object'])){\n\t\t\t$object = $options['object'];\n\t\t\tunset($options['object']);\t\n\t\t}\n\t\t\n\t\t$exclude = '.|..|.svn';\n\t\tif (isset($options['exclude']) && !empty($options['exclude'])){\n\t\t\t$exclude = $options['exclude'];\n\t\t\tunset($options['exclude']);\n\t\t}\n\t\t\n\t\t$recursive = false;\n\t\tif(isset($options['recursive']) && !empty($options['recursive'])){\n\t\t\tif(in_array($options['recursive'],array(true,false))){\n\t\t\t\t$recursive = $options['recursive'];\n\t\t\t}\n\t\t\tunset($options['recursive']);\n\t\t}\n\t\t\n\t\t//read directory\n\t\t$file_list_array = $this->read_dir($directory,$exclude,$recursive);\t\t\n\t\t\n\t\tif(!$file_list_array){\n\t\t\tthrow new OSS_Exception($directory.' is empty...');\n\t\t}\n\t\t\n\t\t$index = 1;\n\t\t\n\t\tforeach ($file_list_array as $item){\n\t\t\t$options = array(\n\t\t\t\tself::OSS_FILE_UPLOAD => $item['path'],\n\t\t\t\tself::OSS_PART_SIZE => 5242880,\n\t\t\t);\t\t\t\n\t\t\t\n\t\t\techo $index++.\". \";\n\t\t\t$response = $this->create_mpu_object($bucket, (!empty($object)?$object.'/':'').$item['file'],$options);\n\t\t\tif($response->isOK()){\n\t\t\t\techo \"Upload file {\".$item['path'].\" } successful..\\n\";\n\t\t\t}else{\n\t\t\t\techo \"Upload file {\".$item['path'].\" } failed..\\n\";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\t\t\n\t}\n\t\n\t\t\n\t/*%******************************************************************************************************%*/\n\t//Object Group相关操作\n\n\t/**\n\t * 创建Object Group\n\t * @param string $object_group (Required)  Object Group名称\n\t * @param string $bucket (Required) Bucket名称\n\t * @param array $object_arry (Required) object数组，所有的object必须在同一个bucket下\n\t * 其中$object 数组的格式如下:\n\t * $object = array(\n\t * \t\t$object1,\n\t * \t\t$object2,\n\t * \t\t...\n\t * )\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function create_object_group($bucket,$object_group  ,$object_arry,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object group\n\t\t$this->is_empty($object_group,OSS_OBJECT_GROUP_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'POST';\n\t\t$options[self::OSS_OBJECT] = $object_group;\n\t\t$options[self::OSS_CONTENT_TYPE] = 'txt/xml';  //重设Content-Type\n\t\t$options[self::OSS_SUB_RESOURCE] = 'group';\t   //设置?group\n\t\t$options[self::OSS_CONTENT] = $this->make_object_group_xml($bucket,$object_arry);   //格式化xml\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * 获取Object Group\n\t * @param string $object_group (Required)\n\t * @param string $bucket\t(Required)\n\t * @param array $options\t(Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function get_object_group($bucket,$object_group,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object group\n\t\t$this->is_empty($object_group,OSS_OBJECT_GROUP_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'GET';\n\t\t$options[self::OSS_OBJECT] = $object_group;\n\t\t//$options[self::OSS_OBJECT_GROUP] = true;\t   //设置?group\n\t\t//$options[self::OSS_CONTENT_TYPE] = 'txt/xml';  //重设Content-Type\n\t\t$options[self::OSS_HEADERS] = array(self::OSS_OBJECT_GROUP => self::OSS_OBJECT_GROUP);  //header中的x-oss-file-group不能为空，否则返回值错误\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * 获取Object Group 的Object List信息\n\t * @param string $object_group (Required)\n\t * @param string $bucket\t(Required)\n\t * @param array $options\t(Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function get_object_group_index($bucket,$object_group,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object group\n\t\t$this->is_empty($object_group,OSS_OBJECT_GROUP_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'GET';\n\t\t$options[self::OSS_OBJECT] = $object_group;\n\t\t$options[self::OSS_CONTENT_TYPE] = 'application/xml';  //重设Content-Type\n\t\t//$options[self::OSS_OBJECT_GROUP] = true;\t   //设置?group\n\t\t$options[self::OSS_HEADERS] = array(self::OSS_OBJECT_GROUP => self::OSS_OBJECT_GROUP);\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * 获得object group的meta信息\n\t * @param string $bucket (Required)\n\t * @param string $object_group (Required)\n\t * @param string $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function get_object_group_meta($bucket,$object_group,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object group\n\t\t$this->is_empty($object_group,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'HEAD';\n\t\t$options[self::OSS_OBJECT] = $object_group;\n\t\t$options[self::OSS_CONTENT_TYPE] = 'application/xml';  //重设Content-Type\n\t\t//$options[self::OSS_SUB_RESOURCE] = 'group';\t   //设置?group\n\t\t$options[self::OSS_HEADERS] = array(self::OSS_OBJECT_GROUP => self::OSS_OBJECT_GROUP);\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\t/**\n\t * 删除Object Group\n\t * @param string $bucket(Required)\n\t * @param string $object_group (Required)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-11-14\n\t * @return ResponseCore\n\t */\n\tpublic function delete_object_group($bucket,$object_group,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object group\n\t\t$this->is_empty($object_group,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_METHOD] = 'DELETE';\n\t\t$options[self::OSS_OBJECT] = $object_group;\n\n\t\t$response = $this->auth ( $options );\n\n\t\treturn $response;\n\t}\n\n\n\t/*%******************************************************************************************************%*/\n\t//带签名的url相关\n\n\t/**\n\t * 获取带签名的url\n\t * @param string $bucket (Required)\n\t * @param string $object (Required)\n\t * @param int\t $timeout (Optional)\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-21\n\t * @return string\n\t */\n\tpublic function get_sign_url($bucket,$object,$timeout = 60,$options = NULL){\n\t\t//options\n\t\t$this->validate_options($options);\n\n\t\tif(!$options){\n\t\t\t$options = array();\n\t\t}\n\n\t\t//bucket\n\t\t$this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);\n\n\t\t//object\n\t\t$this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);\n\n\t\t$options[self::OSS_BUCKET] = $bucket;\n\t\t$options[self::OSS_OBJECT] = $object;\n\t\t$options[self::OSS_METHOD] = self::OSS_HTTP_GET;\n\t\t$options[self::OSS_CONTENT_TYPE] = '';\n\n\t\t$timeout = time() + $timeout;\n\t\t$options[self::OSS_PREAUTH] = $timeout;\n\t\t$options[self::OSS_DATE] = $timeout;\n\n\t\treturn $this->auth($options);\n\t}\n\n\t/*%******************************************************************************************************%*/\n\t//日志相关\n\n\t/**\n\t * 记录日志\n\t * @param string $msg (Required)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-27\n\t * @return void\n\t */\n\tprivate function log($msg){\n\t\tif(defined('ALI_LOG_PATH') ){\n\t\t\t$log_path = ALI_LOG_PATH;\n\t\t\tif(empty($log_path) || !file_exists($log_path)){\n\t\t\t\tthrow new OSS_Exception($log_path.OSS_LOG_PATH_NOT_EXIST);\n\t\t\t}\n\t\t}else{\n\t\t\t$log_path = dirname(__FILE__).DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR;\n\t\t}\n\t\t\n\t\t//检测日志目录是否存在\n\t\tif(!file_exists($log_path)){\n\t\t\tthrow new OSS_Exception(OSS_LOG_PATH_NOT_EXIST);\n\t\t}\n\n\t\t$log_name = $log_path.'oss_sdk_php_'.date('Y-m-d').'.log';\n\n\t\tif(ALI_DISPLAY_LOG){\n\t\t\techo $msg.\"\\n<br/>\";\n\t\t}\n\t\t\n\t\tif(ALI_LOG){\n\t\t\tif(!error_log(date('Y-m-d H:i:s').\" : \".$msg.\"\\n\", 3,$log_name)){\n\t\t\t\tthrow new OSS_Exception(OSS_WRITE_LOG_TO_FILE_FAILED);\n\t\t\t}\n\t\t}\n\t}\n\n\n\t/*%******************************************************************************************************%*/\n\t//工具类相关\n\n\t/**\n\t * 生成query params\n\t * @param array $array 关联数组\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-03-04\n\t * @return string 返回诸如 key1=value1&key2=value2\n\t */\n\tpublic function to_query_string($options = array()){\n\t\t$temp = array();\n\t\t\n\t\tforeach ($options as $key => $value){\n\t\t\tif (is_string($key) && !is_array($value)){\n\t\t\t\t$temp[] = rawurlencode($key) . '=' . rawurlencode($value);\n\t\t\t}\n\t\t}\n\n\t\treturn implode('&', $temp);\n\t}\n\t\n\t/**\n\t * 转化十六进制的数据为base64\n\t *\n\t * @param string $str (Required) 要转化的字符串\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-03-20\n\t * @return string Base64-encoded string.\n\t */\n\tprivate function hex_to_base64($str){\n\t\t$result = '';\n\n\t\tfor ($i = 0; $i < strlen($str); $i += 2){\n\t\t\t$result .= chr(hexdec(substr($str, $i, 2)));\n\t\t}\n\n\t\treturn base64_encode($result);\n\t}\n\n\tprivate function s_replace($subject){\n\t\t$search = array('<','>','&','\\'','\"');\n\t\t$replace = array('&lt;','&gt;','&amp;','&apos;','&quot;');\n\t\treturn str_replace($search, $replace, $subject);\n\t}\n\t\n\t/**\n\t * 检测是否含有中文\n\t * @param string $subject\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-06-06\n\t * @return boolean\n\t */\n\tprivate function chk_chinese($str){\n\t\treturn preg_match('/[\\x80-\\xff]./', $str);\n\t}\n\t\n\t/**\n\t * 检测是否GB2312编码\n\t * @param string $str \n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-03-20\n\t * @return boolean false UTF-8编码  TRUE GB2312编码\n\t */\n\tfunction is_gb2312($str)  {  \n\t    for($i=0; $i<strlen($str); $i++) {  \n\t        $v = ord( $str[$i] );  \n\t        if( $v > 127) {  \n\t            if( ($v >= 228) && ($v <= 233) ){  \n\t                if( ($i+2) >= (strlen($str) - 1)) return true;  // not enough characters  \n\t                $v1 = ord( $str[$i+1] );  \n\t                $v2 = ord( $str[$i+2] );  \n\t                if( ($v1 >= 128) && ($v1 <=191) && ($v2 >=128) && ($v2 <= 191) )  \n\t                    return false;   //UTF-8编码  \n\t                else  \n\t                    return true;    //GB编码  \n\t            }  \n\t        }  \n\t    }  \n\t} \n\n\n\t/**\n\t * 检测是否GBK编码\n\t * @param string $str \n\t * @param boolean $gbk\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-06-04\n\t * @return boolean \n\t */\t\n\tprivate function check_char($str,$gbk = true){ \n\t    for($i=0; $i<strlen($str); $i++) {\n\t        $v = ord( $str[$i] );\n\t        if( $v > 127){\n\t            if( ($v >= 228) && ($v <= 233) ){\n\t                 if(($i+2)>= (strlen($str)-1)) return $gbk?true:FALSE;  // not enough characters\n\t                 $v1 = ord( $str[$i+1] ); $v2 = ord( $str[$i+2] );\n\t                 if($gbk){\n\t                      return (($v1 >= 128) && ($v1 <=191) && ($v2 >=128) && ($v2 <= 191))?FALSE:TRUE;//GBK\n\t                 }else{\n\t                      return (($v1 >= 128) && ($v1 <=191) && ($v2 >=128) && ($v2 <= 191))?TRUE:FALSE;\n\t                 }\n\t            }\n\t        }\n\t    }\n\t   return $gbk?TRUE:FALSE;\n\t}\n\n\n\t/**\n\t * 读取目录\n\t * @param string $dir (Required) 目录名\n\t * @param boolean $recursive (Optional) 是否递归，默认为false\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2012-03-05\n\t * @return array\n\t */\n\tprivate  function read_dir($dir,$exclude = \".|..|.svn\",$recursive = false){\n\t\tstatic $file_list_array = array();\n\t\t\n\t\t$exclude_array = explode(\"|\", $exclude);\n\t\t//读取目录\n\t\tif($handle = opendir($dir)){\n\t\t\twhile ( false !== ($file = readdir($handle))){\t\t\t\t\t\t\n\t\t\t\tif(!in_array(strtolower($file),$exclude_array)){\n\t\t\t\t\t$new_file = $dir.'/'.$file;\t\t\t\t\t\n\t\t\t\t\tif(is_dir($new_file) && $recursive){\n\t\t\t\t\t\t$this->read_dir($new_file,$exclude,$recursive);\n\t\t\t\t\t}else{\n\t\t\t\t\t\t$file_list_array[] = array(\n\t\t\t\t\t\t\t'path' => $new_file,\n\t\t\t\t\t\t\t'file' => $file,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tclosedir($handle);\t\t\t\n\t\t}\t\t\t\n\t\t\n\t\treturn $file_list_array;\n\t}\n\t\n\t\n\t/**\n\t * 转化object数组为固定个xml格式\n\t * @param string $bucket (Required)\n\t * @param array $object_array (Required)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-27\n\t * @return string\n\t */\n\tprivate function make_object_group_xml($bucket,$object_array){\n\t\t$xml = '';\n\t\t$xml .= '<CreateFileGroup>';\n\n\t\tif($object_array){\n\t\t\tif(count($object_array) > self::OSS_MAX_OBJECT_GROUP_VALUE){\n\t\t\t\tthrow new OSS_Exception(OSS_OBJECT_GROUP_TOO_MANY_OBJECT, '-401');\n\t\t\t}\n\t\t\t$index = 1;\n\t\t\tforeach ($object_array as $key=>$value){\n\t\t\t\t$object_meta = (array)$this->get_object_meta($bucket, $value);\n\t\t\t\tif(isset($object_meta) && isset($object_meta['status']) && isset($object_meta['header']) && isset($object_meta['header']['etag']) && $object_meta['status'] == 200){\n\t\t\t\t\t$xml .= '<Part>';\n\t\t\t\t\t$xml .= '<PartNumber>'.intval($index).'</PartNumber>';\n\t\t\t\t\t$xml .= '<PartName>'.$value.'</PartName>';\n\t\t\t\t\t$xml .= '<ETag>'.$object_meta['header']['etag'].'</ETag>';\n\t\t\t\t\t$xml .= '</Part>';\n\n\t\t\t\t\t$index++;\n\t\t\t\t}\n\t\t\t}\n\t\t}else{\n\t\t\tthrow new OSS_Exception(OSS_OBJECT_ARRAY_IS_EMPTY, '-400');\n\t\t}\n\n\t\t$xml .= '</CreateFileGroup>';\n\n\t\treturn $xml;\n\t}\n\n\t/**\n\t * 检验bucket名称是否合法\n\t * bucket的命名规范：\n\t * 1. 只能包括小写字母，数字\n\t * 2. 必须以小写字母或者数字开头\n\t * 3. 长度必须在3-63字节之间\n\t * @param string $bucket (Required)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-27\n\t * @return boolean\n\t */\n\tprivate function validate_bucket($bucket){\n\t\t$pattern = '/^[a-z0-9][a-z0-9-]{2,62}$/';\n\t\tif (! preg_match ( $pattern, $bucket )) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 检验object名称是否合法\n\t * object命名规范:\n\t * 1. 规则长度必须在1-1023字节之间\n\t * 2. 使用UTF-8编码\n\t * @param string $object (Required)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-27\n\t * @return boolean\n\t */\n\tprivate function validate_object($object){\n\t\t$pattern = '/^.{1,1023}$/';\n\t\tif (empty ( $object ) || ! preg_match ( $pattern, $object )) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 检验$options\n\t * @param array $options (Optional)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-27\n\t * @return boolean \n\t */\n\tprivate function validate_options($options){\n\t\t//$options\n\t\tif ($options != NULL && ! is_array ( $options )) {\n\t\t\tthrow new OSS_Exception ($options.':'.OSS_OPTIONS_MUST_BE_ARRAY);\n\t\t}\n\t}\n\n\t/**\n\t * 检测上传文件的内容\n\t * @param array $options (Optional)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since  2011-12-27\n\t * @return string\n\t */\n\tprivate function validate_content($options){\n\t\tif(isset($options[self::OSS_CONTENT])){\n\t\t\tif($options[self::OSS_CONTENT] == '' || !is_string($options[self::OSS_CONTENT])){\n\t\t\t\tthrow new OSS_Exception(OSS_INVALID_HTTP_BODY_CONTENT,'-600');\n\t\t\t}\n\t\t}else{\n\t\t\tthrow new OSS_Exception(OSS_NOT_SET_HTTP_CONTENT, '-601');\n\t\t}\n\t}\n\n\t/**\n\t * 验证文件长度\n\t * @param array $options (Optional)\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-27\n\t * @return void\n\t */\n\tprivate function validate_content_length($options){\n\t\tif(isset($options[self::OSS_LENGTH]) && is_numeric($options[self::OSS_LENGTH])){\n\t\t\tif( ! $options[self::OSS_LENGTH] > 0){\n\t\t\t\tthrow new OSS_Exception(OSS_CONTENT_LENGTH_MUST_MORE_THAN_ZERO, '-602');\n\t\t\t}\n\t\t}else{\n\t\t\tthrow new OSS_Exception(OSS_INVALID_CONTENT_LENGTH, '-602');\n\t\t}\n\t}\n\n\t/**\n\t * 校验BUCKET/OBJECT/OBJECT GROUP是否为空\n\t * @param  string $name (Required)\n\t * @param  string $errMsg (Required)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @since 2011-12-27\n\t * @return void\n\t */\n\tprivate function is_empty($name,$errMsg){\n\t\tif(empty($name)){\n\t\t\tthrow new OSS_Exception($errMsg);\n\t\t}\n\t}\n\n\t/**\n\t * 设置http header\n\t * @param string $key (Required)\n\t * @param string $value (Required)\n\t * @param array $options (Required)\n\t * @throws OSS_Exception\n\t * @author xiaobing.meng@alibaba-inc.com\n\t * @return void\n\t */\n\tprivate static function set_options_header($key, $value, &$options) {\n\t\tif (isset ( $options [self::OSS_HEADERS] )) {\n\t\t\tif (! is_array ( $options [self::OSS_HEADERS] )) {\n\t\t\t\tthrow new OSS_Exception(OSS_INVALID_OPTION_HEADERS, '-600');\n\t\t\t}\n\t\t} else {\n\t\t\t$options [self::OSS_HEADERS] = array ();\n\t\t}\n\n\t\t$options [self::OSS_HEADERS] [$key] = $value;\n\t} \t\n}\n"
  },
  {
    "path": "AliUpload/lib/zh.inc.php",
    "content": "<?php\n/*%*************************************************************************************%*/\n//access id & access key 相关\ndefine('NOT_SET_OSS_ACCESS_ID', '未设置OSS服务的ACCESS ID');\ndefine('NOT_SET_OSS_ACCESS_KEY', '未设置OSS服务的ACCESS KEY');\ndefine('NOT_SET_OSS_ACCESS_ID_AND_ACCESS_KEY', '没有设置ACCESS ID & ACCESS KEY');\ndefine('OSS_ACCESS_ID_OR_ACCESS_KEY_EMPTY', 'ACCESS ID或ACCESS KEY为空');\n\n/*%*************************************************************************************%*/\n//OSS语言包以及文件相关\ndefine('OSS_LANG_FILE_NOT_EXIST', 'OSS语言包文件不存在');\ndefine('OSS_CONFIG_FILE_NOT_EXIST',OSS_API_PATH.DIRECTORY_SEPARATOR.'conf.inc.php不存在');\ndefine('OSS_UTILS_FILE_NOT_EXIST',OSS_API_PATH.DIRECTORY_SEPARATOR.'util'.DIRECTORY_SEPARATOR.'utils.php不存在');\ndefine('OSS_CURL_EXTENSION_MUST_BE_LOAD','系统没有安装CURL扩展');\ndefine('OSS_NO_ANY_EXTENSIONS_LOADED','系统没有安装任何扩展,请检查系统配置');\n\n\n/*%*************************************************************************************%*/\n//日志文件相关\ndefine('OSS_WRITE_LOG_TO_FILE_FAILED','日志写入失败,请检查日志文件是否存在或者日志文件的权限');\ndefine('OSS_LOG_PATH_NOT_EXIST','日志路径不存在');\n\n/*%**************************************************************************************%*/\n//OSS bucket操作相关\ndefine('OSS_OPTIONS_MUST_BE_ARRAY', '$option必须为数组');\ndefine('OSS_GET_BUCKET_LIST_SUCCESS','获取Bucket列表成功!');\ndefine('OSS_GET_BUCKET_LIST_FAILED', '获取Bucket列表失败!');\ndefine('OSS_CREATE_BUCKET_SUCCESS', '创建Bucket成功');\ndefine('OSS_CREATE_BUCKET_FAILED', '创建Bucket失败');\ndefine('OSS_DELETE_BUCKET_SUCCESS', '删除Bucket成功');\ndefine('OSS_DELETE_BUCKET_FAILED', '删除Bucket失败');\ndefine('OSS_BUCKET_NAME_INVALID', '未通过Bucket名称规则校验');\ndefine('OSS_GET_BUCKET_ACL_SUCCESS','获取Bucket ACL成功');\ndefine('OSS_GET_BUCKET_ACL_FAILED','获取Bucket ACL失败');\ndefine('OSS_SET_BUCKET_ACL_SUCCESS','设置Bucket ACL成功');\ndefine('OSS_SET_BUCKET_ACL_FAILED','设置Bucket ACL失败');\ndefine('OSS_ACL_INVALID','ACL不在允许范围,目前仅允许(private,public-read,public-read-write三种权限)');\ndefine('OSS_BUCKET_IS_NOT_ALLOWED_EMPTY', 'Bucket不允许为空');\n\n/*%****************************************************************************************%*/\n//OSS object操作相关\ndefine('OSS_GET_OBJECT_LIST_SUCCESS','获得OBJECT列表成功');\ndefine('OSS_GET_OBJECT_LIST_FAILED','获得OBJECT列表失败');\ndefine('OSS_CREATE_OBJECT_DIR_SUCCESS','创建OBJECT目录成功');\ndefine('OSS_CREATE_OBJECT_DIR_FAILED','创建OBJECT目录失败');\ndefine('OSS_DELETE_OBJECT_SUCCESS','删除OBJECT成功');\ndefine('OSS_DELETE_OBJECT_FAILED','删除OBJECT失败');\ndefine('OSS_UPLOAD_FILE_BY_CONTENT_SUCCESS','通过Http Body上传文件成功');\ndefine('OSS_UPLOAD_FILE_BY_CONTENT_FAILED','通过Http Body上传文件失败');\ndefine('OSS_GET_OBJECT_META_SUCCESS','获得OBJECT META成功');\ndefine('OSS_GET_OBJECT_META_FAILED','获得OBJECT META失败');\ndefine('OSS_OBJECT_NAME_INVALID','未通过Object名称规则校验');\ndefine('OSS_OBJECT_IS_NOT_ALLOWED_EMPTY','Object不允许为空');\ndefine('OSS_INVALID_HTTP_BODY_CONTENT','Http Body的内容非法');\ndefine('OSS_GET_OBJECT_SUCCESS','获得Object成功');\ndefine('OSS_GET_OBJECT_FAILED','获得Object失败');\ndefine('OSS_OBJECT_EXIST','Object存在');\ndefine('OSS_OBJECT_NOT_EXIST','Object不存在');\ndefine('OSS_NOT_SET_HTTP_CONTENT','为设置Http Body');\ndefine('OSS_INVALID_CONTENT_LENGTH','非法的Content-Length值');\ndefine('OSS_CONTENT_LENGTH_MUST_MORE_THAN_ZERO','Content-Length必须大于0');\ndefine('OSS_UPLOAD_FILE_NOT_EXIST','上传文件不存在');\ndefine('OSS_COPY_OBJECT_SUCCESS','拷贝Object成功');\ndefine('OSS_COPY_OBJECT_FAILED', '拷贝Object失败');\ndefine('OSS_FILE_NOT_EXIST','文件不存在');\ndefine('OSS_FILE_PATH_IS_NOT_ALLOWED_EMPTY', '上传文件路径为空');\n\n/*%****************************************************************************************%*/\n//OSS object Group操作相关\ndefine('OSS_CREATE_OBJECT_GROUP_SUCCESS','创建Object Group成功');\ndefine('OSS_CREATE_OBJECT_GROUP_FAILED','创建Object Group失败');\ndefine('OSS_GET_OBJECT_GROUP_SUCCESS','获取Object Group成功');\ndefine('OSS_GET_OBJECT_GROUP_FAILED','获取Object Group失败');\ndefine('OSS_GET_OBJECT_GROUP_INDEX_SUCCESS','获取Object Group Index成功');\ndefine('OSS_GET_OBJECT_GROUP_INDEX_FAILED','获取Object Group Index失败');\ndefine('OSS_GET_OBJECT_GROUP_META_SUCCESS','获取Object Group Group Meta成功');\ndefine('OSS_GET_OBJECT_GROUP_META_FAILED','获取Object Group Group Meta失败');\ndefine('OSS_DELETE_OBJECT_GROUP_SUCCESS','删除Object Group Group成功');\ndefine('OSS_DELETE_OBJECT_GROUP_FAILED','删除Object Group Group失败');\ndefine('OSS_OBJECT_GROUP_IS_NOT_ALLOWED_EMPTY', 'Object Group不允许为空');\ndefine('OSS_OBJECT_ARRAY_IS_EMPTY','创建Object Group的Object不允许为空');\ndefine('OSS_OBJECT_GROUP_TOO_MANY_OBJECT','每个Object Group最多包含1000个Object');\n\n/*%****************************************************************************************%*/\n//OSS Multi-Part Upload相关\ndefine('OSS_INITIATE_MULTI_PART_SUCCESS', '初始化Multi-Part Upload成功');\ndefine('OSS_INITIATE_MULTI_PART_FAILED', '初始化Multi-Part Upload失败');\n\n/*%*******************************************************************************************%*/\n//其他\ndefine('OSS_INVALID_OPTION_HEADERS', 'OPTIONS不是数组');\n\n\n\n\n\n"
  },
  {
    "path": "Avartar.php",
    "content": "<?php\n\n\n/**\n * 头像代理修改插件\n * \n * @package Avartar\n * @author loftor\n * @version 1.0.0 Beta\n * @link http://loftor.com/\n */\nclass Avartar implements Typecho_Plugin_Interface\n{\n\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Abstract_Comments')->gravatar = array('Avartar', 'gravatar');\n        return _t('启用成功，请进行相应设置！');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $http = new Typecho_Widget_Helper_Form_Element_Text('http', NULL, 'http://gravatar.duoshuo.com',\n            _t('http代理地址'), _t('请填写http代理地址!'));\n        $form->addInput($http);\n        \n        $https = new Typecho_Widget_Helper_Form_Element_Text('https', NULL, 'https://secure.gravatar.com',\n            _t('https代理地址'), _t('请填写https代理地址!'));\n        $form->addInput($https);\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n\n    /**\n     * 输出用户头像\n     *\n     * @access public\n     * @param array $file 上传的文件\n     * @return mixed\n     */\n    public static function gravatar($size, $rating, $default, $ctx)\n    {\n        $mailHash = NULL;\n        if (!empty($ctx->mail)) {\n            $mailHash = md5(strtolower($ctx->mail));\n        }\n        $options = Typecho_Widget::widget('Widget_Options');\n        if ($ctx->request->isSecure()) {\n            $host=$options->plugin('Avartar')->https;\n        } else {\n            $host=$options->plugin('Avartar')->http;\n        }\n\n        $url = $host . '/avatar/';\n\n        if (!empty($ctx->mail)) {\n            $url .= $mailHash;\n        }\n\n        $url .= '?s=' . $size;\n        $url .= '&amp;r=' . $rating;\n        $url .= '&amp;d=' . $default;\n\n        echo '<img class=\"avatar\" src=\"' . $url . '\" alt=\"' .\n        $ctx->author . '\" width=\"' . $size . '\" height=\"' . $size . '\" />';\n    }\n}"
  },
  {
    "path": "B3logForHacPai/Action.php",
    "content": "<?php ! defined('__TYPECHO_ROOT_DIR__') and exit();\n\nclass B3logForHacPai_Action extends Typecho_Widget\n{\n\n    /**\n     * 构造函数\n     *\n     * @param mixed $request\n     * @param mixed $response\n     * @param null $params\n     */\n    public function __construct($request, $response, $params = NULL)\n    {\n        parent::__construct($request, $response, $params);\n\n\n    }\n\n    /**\n     * Article receiver (from B3log Symphony).\n     *\n     */\n    public function articleReceiver(){\n\n        //print_r($_POST);\n    }\n\n    /**\n     * Comment receiver (from B3log Symphony).\n     *\n     */\n    public function commentReceiver(){\n        if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) {\n            $GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents(\"php://input\");\n        }\n        if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {\n            $GLOBALS['HTTP_RAW_POST_DATA'] = trim($GLOBALS['HTTP_RAW_POST_DATA']);\n        }\n\n        $result = json_decode($GLOBALS['HTTP_RAW_POST_DATA']);\n        if($result->client->key == Typecho_Widget::widget('Widget_Options')->plugin('B3logForHacPai')->b3logKey) {\n            $post = Typecho_Db::get()->fetchRow(Typecho_Db::get()->select('authorId')->from('table.contents')->where('cid = ?', $result->comment->articleId));\n\n            if ($post) {\n                $comment = array(\n                    'cid' => $result->comment->articleId,\n                    'created' => Helper::options()->gmtTime,\n                    'text' => $result->comment->content,\n                    'author' => $result->comment->authorName,\n                    'mail' => $result->comment->authorEmail,\n                    'url' => $result->comment->authorURL,\n                    'agent' => $this->request->getAgent(),\n                    'ip' => $this->request->getIp(),\n                    'ownerId' => $post['authorId'],\n                    'type' => 'comment',\n                    'status' => 'approved',\n                );\n                //print_r($result->comment->articleid);\n                //$article = Typecho_Widget::widget('Widget_Users_Author@' . $this->cid, array('cid' => $result->comment->articleId));\n                Typecho_Widget::widget('Widget_Feedback')->insert($comment);\n            }\n        }\n    }\n\n\n\n}\n"
  },
  {
    "path": "B3logForHacPai/LICENSE.txt",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "B3logForHacPai/Plugin.php",
    "content": "<?php\nif (!defined('__TYPECHO_ROOT_DIR__')) exit;\n//如果没有json库，加载兼容包\n! extension_loaded('json') and include('libs/compat_json.php');\n/**\n * 黑客派社区实时同步插件\n * \n * @package B3log for HacPai\n * @author DT27\n * @version 1.0.0\n * @link https://dt27.org/B3log-for-HacPai/\n */\nclass B3logForHacPai_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishPublish =\n            array('B3logForHacPai_Plugin', 'finishPublish');\n        Typecho_Plugin::factory('Widget_Feedback')->finishComment =\n            array('B3logForHacPai_Plugin', 'finishComment');\n\n        // 创建路由\n        // from HacPai\n        Helper::addRoute('b3log.hacpai.article', '/b3log-hacpai/article', 'B3logForHacPai_Action', 'articleReceiver');\n        Helper::addRoute('b3log.hacpai.comment', '/b3log-hacpai/comment', 'B3logForHacPai_Action', 'commentReceiver');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){\n        Helper::removeRoute('b3log.hacpai.article');\n        Helper::removeRoute('b3log.hacpai.comment');\n    }\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $b3logKey = new Typecho_Widget_Helper_Form_Element_Text('b3logKey', NULL, NULL,\n            _t('B3log Key'), _t('请填写黑客派社区中设置的 B3log Key，并在社区中设置接收接口。<a href=\"https://hacpai.com/settings#soloKey\" target=\"_blank\">点此设置</a><br>\n客户端收文及更新接口：<strong style=\"color: red;\">'.Helper::options()->siteUrl.'b3log-hacpai/article</strong><br>客户端收评接口：<strong style=\"color: red;\">'.Helper::options()->siteUrl.'b3log-hacpai/comment</strong>'));\n        $form->addInput($b3logKey->addRule('required', _t('必须填写 B3log Key')));\n\n        $b3logTitle = new Typecho_Widget_Helper_Form_Element_Text('b3logTitle', NULL, Helper::options()->title,\n            _t('博客标题'), _t('请填写本博客标题'));\n        $form->addInput($b3logTitle);\n\n        $b3logHost = new Typecho_Widget_Helper_Form_Element_Text('b3logHost', NULL, Helper::options()->siteUrl,\n            _t('博客地址'), _t('请填写本博客地址，需包括 http 且末尾无斜杠，例如：<strong style=\"color: red;\">https://dt27.org</strong>'));\n        $form->addInput($b3logHost);\n        Typecho_Widget::widget('Widget_User')->to($user);\n        $b3logEmail = new Typecho_Widget_Helper_Form_Element_Text('b3logEmail', NULL, $user->mail,\n            _t('博客邮箱'), _t('请填写本博客邮箱'));\n        $form->addInput($b3logEmail);\n\n\n        $isHacPai = new Typecho_Widget_Helper_Form_Element_Radio('isHacPai',\n            array(\n                '1' => '是',\n                '0' => '否',\n            ),'1', _t('是否启用同步功能'), NULL);\n        $form->addInput($isHacPai);\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 发布文章\n     * \n     * @access public\n     * @return void\n     */\n    public static function finishPublish($contents, $edit)\n    {\n        $b3log = Typecho_Widget::widget('Widget_Options')->plugin('B3logForHacPai');\n        if($b3log->isHacPai == 1) {\n            $postData = array(\n                \"article\" => array(\n                    \"id\" => $edit->cid,\n                    \"title\" => $contents['title'],\n                    \"permalink\" => substr($edit->permalink,strlen($b3log->b3logHost)),//substr($str,4) [article.permalink] should start with /, for example, /hello-world\n                    \"tags\" => $contents['tags'],\n                    \"content\" => $contents['text'],\n                ),\n                \"client\" => array(\n                    \"title\" => $b3log->b3logTitle,\n                    \"host\" => $b3log->b3logHost,\n                    \"email\" => $b3log->b3logEmail,\n                    \"key\" => $b3log->b3logKey,\n                ));\n            $postString = json_encode($postData);\n            $ch = curl_init('http://rhythm.b3log.org/api/article');\n            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\n            curl_setopt($ch, CURLOPT_POSTFIELDS,$postString);\n            curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);\n            curl_setopt($ch, CURLOPT_HTTPHEADER, array(\n                    'Content-Type: application/json',\n                    'Content-Length: ' . strlen($postString))\n            );\n            $result = curl_exec($ch);\n        }\n        return $contents;\n    }\n    /**\n     * 发布评论\n     *\n     * @access public\n     * @return void\n     */\n    public static function finishComment($comment)\n    {\n        $b3log = Typecho_Widget::widget('Widget_Options')->plugin('B3logForHacPai');\n        if ($b3log->isHacPai == 1) {\n            $postData = array(\n                \"comment\" => array(\n                    \"id\" => $comment->coid,\n                    \"articleId\" => $comment->cid,\n                    \"content\" => $comment->text,\n                    \"authorName\" => $comment->author,\n                    \"authorEmail\" => $comment->mail,\n                ),\n                \"client\" => array(\n                    \"title\" => $b3log->b3logTitle,\n                    \"host\" => $b3log->b3logHost,\n                    \"email\" => $b3log->b3logEmail,\n                    \"key\" => $b3log->b3logKey,\n                ));\n            $postString = json_encode($postData);\n            $ch = curl_init('http://rhythm.b3log.org/api/comment');\n            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\n            curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);\n            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n            curl_setopt($ch, CURLOPT_HTTPHEADER, array(\n                    'Content-Type: application/json',\n                    'Content -Length: ' . strlen($postString))\n            );\n            $result = curl_exec($ch);\n            //print_r($result);exit;\n        }\n        return $comment;\n    }\n}\n"
  },
  {
    "path": "B3logForHacPai/README.md",
    "content": "# [B3logForHacPai](https://dt27.org/php/b3log-hacpai-typecho/)\n**黑客派社区实时同步插件 For Typecho**\n\n基于[B3log理念][1]，整合 [Typecho][2] 博客与 [黑客派][3] 社区，实现内容及评论互相实时同步。丰富博客与社区内容。\n\n## Features&Todo \n* [x] 博客发布博文 -> 社区发布帖子\n* [x] 博客更新博文 -> 社区更新帖子\n* [x] 博客发布评论 -> 社区发布回帖\n* [x] 社区发布回帖 -> 博客发布评论\n\n###### Plugin License\n> Copyright © 2016 [DT27](https://dt27.org)  \n> License: [GNU General Public License v3.0](http://www.gnu.org/licenses/gpl-3.0.html)\n [1]: https://hacpai.com/b3log\n [2]: http://typecho.org/\n [3]: https://hacpai.com/"
  },
  {
    "path": "B3logForHacPai/libs/compat_json.php",
    "content": "<?php\nif ( !class_exists( 'Services_JSON' ) ) :\n/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\n/**\n * Converts to and from JSON format.\n *\n * JSON (JavaScript Object Notation) is a lightweight data-interchange\n * format. It is easy for humans to read and write. It is easy for machines\n * to parse and generate. It is based on a subset of the JavaScript\n * Programming Language, Standard ECMA-262 3rd Edition - December 1999.\n * This feature can also be found in  Python. JSON is a text format that is\n * completely language independent but uses conventions that are familiar\n * to programmers of the C-family of languages, including C, C++, C#, Java,\n * JavaScript, Perl, TCL, and many others. These properties make JSON an\n * ideal data-interchange language.\n *\n * This package provides a simple encoder and decoder for JSON notation. It\n * is intended for use with client-side Javascript applications that make\n * use of HTTPRequest to perform server communication functions - data can\n * be encoded into JSON notation for use in a client-side javascript, or\n * decoded from incoming Javascript requests. JSON format is native to\n * Javascript, and can be directly eval()'ed with no further parsing\n * overhead\n *\n * All strings should be in ASCII or UTF-8 format!\n *\n * LICENSE: Redistribution and use in source and binary forms, with or\n * without modification, are permitted provided that the following\n * conditions are met: Redistributions of source code must retain the\n * above copyright notice, this list of conditions and the following\n * disclaimer. Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *\n * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED\n * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN\n * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\n * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n *\n * @category\n * @package\t\tServices_JSON\n * @author\t\tMichal Migurski <mike-json@teczno.com>\n * @author\t\tMatt Knapp <mdknapp[at]gmail[dot]com>\n * @author\t\tBrett Stimmerman <brettstimmerman[at]gmail[dot]com>\n * @copyright\t2005 Michal Migurski\n * @version     CVS: $Id: JSON.php 288200 2009-09-09 15:41:29Z alan_k $\n * @license\t\thttp://www.opensource.org/licenses/bsd-license.php\n * @link\t\thttp://pear.php.net/pepr/pepr-proposal-show.php?id=198\n */\n\n/**\n * Marker constant for Services_JSON::decode(), used to flag stack state\n */\ndefine('SERVICES_JSON_SLICE', 1);\n\n/**\n * Marker constant for Services_JSON::decode(), used to flag stack state\n */\ndefine('SERVICES_JSON_IN_STR',  2);\n\n/**\n * Marker constant for Services_JSON::decode(), used to flag stack state\n */\ndefine('SERVICES_JSON_IN_ARR',  3);\n\n/**\n * Marker constant for Services_JSON::decode(), used to flag stack state\n */\ndefine('SERVICES_JSON_IN_OBJ',  4);\n\n/**\n * Marker constant for Services_JSON::decode(), used to flag stack state\n */\ndefine('SERVICES_JSON_IN_CMT', 5);\n\n/**\n * Behavior switch for Services_JSON::decode()\n */\ndefine('SERVICES_JSON_LOOSE_TYPE', 16);\n\n/**\n * Behavior switch for Services_JSON::decode()\n */\ndefine('SERVICES_JSON_SUPPRESS_ERRORS', 32);\n\n/**\n * Converts to and from JSON format.\n *\n * Brief example of use:\n *\n * <code>\n * // create a new instance of Services_JSON\n * $json = new Services_JSON();\n *\n * // convert a complexe value to JSON notation, and send it to the browser\n * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));\n * $output = $json->encode($value);\n *\n * print($output);\n * // prints: [\"foo\",\"bar\",[1,2,\"baz\"],[3,[4]]]\n *\n * // accept incoming POST data, assumed to be in JSON notation\n * $input = file_get_contents('php://input', 1000000);\n * $value = $json->decode($input);\n * </code>\n */\nclass Services_JSON\n{\n /**\n\t* constructs a new JSON instance\n\t*\n\t* @param int $use object behavior flags; combine with boolean-OR\n\t*\n\t*\t\t\t\t\t\tpossible values:\n\t*\t\t\t\t\t\t- SERVICES_JSON_LOOSE_TYPE:  loose typing.\n\t*\t\t\t\t\t\t\t\t\"{...}\" syntax creates associative arrays\n\t*\t\t\t\t\t\t\t\tinstead of objects in decode().\n\t*\t\t\t\t\t\t- SERVICES_JSON_SUPPRESS_ERRORS:  error suppression.\n\t*\t\t\t\t\t\t\t\tValues which can't be encoded (e.g. resources)\n\t*\t\t\t\t\t\t\t\tappear as NULL instead of throwing errors.\n\t*\t\t\t\t\t\t\t\tBy default, a deeply-nested resource will\n\t*\t\t\t\t\t\t\t\tbubble up with an error, so all return values\n\t*\t\t\t\t\t\t\t\tfrom encode() should be checked with isError()\n\t*/\n\tfunction Services_JSON($use = 0)\n\t{\n\t\t$this->use = $use;\n\t}\n\n /**\n\t* convert a string from one UTF-16 char to one UTF-8 char\n\t*\n\t* Normally should be handled by mb_convert_encoding, but\n\t* provides a slower PHP-only method for installations\n\t* that lack the multibye string extension.\n\t*\n\t* @param\tstring  $utf16  UTF-16 character\n\t* @return string  UTF-8 character\n\t* @access private\n\t*/\n\tfunction utf162utf8($utf16)\n\t{\n\t\t// oh please oh please oh please oh please oh please\n\t\tif(function_exists('mb_convert_encoding')) {\n\t\t\treturn mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');\n\t\t}\n\n\t\t$bytes = (ord($utf16[0]) << 8) | ord($utf16[1]);\n\n\t\tswitch(true) {\n\t\t\tcase ((0x7F & $bytes) == $bytes):\n\t\t\t\t// this case should never be reached, because we are in ASCII range\n\t\t\t\t// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\treturn chr(0x7F & $bytes);\n\n\t\t\tcase (0x07FF & $bytes) == $bytes:\n\t\t\t\t// return a 2-byte UTF-8 character\n\t\t\t\t// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\treturn chr(0xC0 | (($bytes >> 6) & 0x1F))\n\t\t\t\t\t. chr(0x80 | ($bytes & 0x3F));\n\n\t\t\tcase (0xFFFF & $bytes) == $bytes:\n\t\t\t\t// return a 3-byte UTF-8 character\n\t\t\t\t// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\treturn chr(0xE0 | (($bytes >> 12) & 0x0F))\n\t\t\t\t\t. chr(0x80 | (($bytes >> 6) & 0x3F))\n\t\t\t\t\t. chr(0x80 | ($bytes & 0x3F));\n\t\t}\n\n\t\t// ignoring UTF-32 for now, sorry\n\t\treturn '';\n\t}\n\n /**\n\t* convert a string from one UTF-8 char to one UTF-16 char\n\t*\n\t* Normally should be handled by mb_convert_encoding, but\n\t* provides a slower PHP-only method for installations\n\t* that lack the multibye string extension.\n\t*\n\t* @param\tstring  $utf8 UTF-8 character\n\t* @return string  UTF-16 character\n\t* @access private\n\t*/\n\tfunction utf82utf16($utf8)\n\t{\n\t\t// oh please oh please oh please oh please oh please\n\t\tif(function_exists('mb_convert_encoding')) {\n\t\t\treturn mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');\n\t\t}\n\n\t\tswitch(strlen($utf8)) {\n\t\t\tcase 1:\n\t\t\t\t// this case should never be reached, because we are in ASCII range\n\t\t\t\t// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\treturn $utf8;\n\n\t\t\tcase 2:\n\t\t\t\t// return a UTF-16 character from a 2-byte UTF-8 char\n\t\t\t\t// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\treturn chr(0x07 & (ord($utf8[0]) >> 2))\n\t\t\t\t\t. chr((0xC0 & (ord($utf8[0]) << 6))\n\t\t\t\t\t\t| (0x3F & ord($utf8[1])));\n\n\t\t\tcase 3:\n\t\t\t\t// return a UTF-16 character from a 3-byte UTF-8 char\n\t\t\t\t// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\treturn chr((0xF0 & (ord($utf8[0]) << 4))\n\t\t\t\t\t\t| (0x0F & (ord($utf8[1]) >> 2)))\n\t\t\t\t\t. chr((0xC0 & (ord($utf8[1]) << 6))\n\t\t\t\t\t\t| (0x7F & ord($utf8[2])));\n\t\t}\n\n\t\t// ignoring UTF-32 for now, sorry\n\t\treturn '';\n\t}\n\n /**\n\t* encodes an arbitrary variable into JSON format (and sends JSON Header)\n\t*\n\t* @param\tmixed $var\tany number, boolean, string, array, or object to be encoded.\n\t*\t\t\t\t\t\tsee argument 1 to Services_JSON() above for array-parsing behavior.\n\t*\t\t\t\t\t\tif var is a strng, note that encode() always expects it\n\t*\t\t\t\t\t\tto be in ASCII or UTF-8 format!\n\t*\n\t* @return mixed JSON string representation of input var or an error if a problem occurs\n\t* @access public\n\t*/\n\tfunction encode($var)\n\t{\n\t\theader('Content-type: application/json');\n\t\treturn $this->_encode($var);\n\t}\n\t/**\n\t* encodes an arbitrary variable into JSON format without JSON Header - warning - may allow CSS!!!!)\n\t*\n\t* @param\tmixed $var\tany number, boolean, string, array, or object to be encoded.\n\t*\t\t\t\t\t\tsee argument 1 to Services_JSON() above for array-parsing behavior.\n\t*\t\t\t\t\t\tif var is a strng, note that encode() always expects it\n\t*\t\t\t\t\t\tto be in ASCII or UTF-8 format!\n\t*\n\t* @return mixed JSON string representation of input var or an error if a problem occurs\n\t* @access public\n\t*/\n\tfunction encodeUnsafe($var)\n\t{\n\t\treturn $this->_encode($var);\n\t}\n\t/**\n\t* PRIVATE CODE that does the work of encodes an arbitrary variable into JSON format\n\t*\n\t* @param\tmixed $var\tany number, boolean, string, array, or object to be encoded.\n\t*\t\t\t\t\t\tsee argument 1 to Services_JSON() above for array-parsing behavior.\n\t*\t\t\t\t\t\tif var is a strng, note that encode() always expects it\n\t*\t\t\t\t\t\tto be in ASCII or UTF-8 format!\n\t*\n\t* @return mixed JSON string representation of input var or an error if a problem occurs\n\t* @access public\n\t*/\n\tfunction _encode($var)\n\t{\n\n\t\tswitch (gettype($var)) {\n\t\t\tcase 'boolean':\n\t\t\t\treturn $var ? 'true' : 'false';\n\n\t\t\tcase 'NULL':\n\t\t\t\treturn 'null';\n\n\t\t\tcase 'integer':\n\t\t\t\treturn (int) $var;\n\n\t\t\tcase 'double':\n\t\t\tcase 'float':\n\t\t\t\treturn (float) $var;\n\n\t\t\tcase 'string':\n\t\t\t\t// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT\n\t\t\t\t$ascii = '';\n\t\t\t\t$strlen_var = strlen($var);\n\n\t\t\t/*\n\t\t\t\t* Iterate over every character in the string,\n\t\t\t\t* escaping with a slash or encoding to UTF-8 where necessary\n\t\t\t\t*/\n\t\t\t\tfor ($c = 0; $c < $strlen_var; ++$c) {\n\n\t\t\t\t\t$ord_var_c = ord($var[$c]);\n\n\t\t\t\t\tswitch (true) {\n\t\t\t\t\t\tcase $ord_var_c == 0x08:\n\t\t\t\t\t\t\t$ascii .= '\\b';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase $ord_var_c == 0x09:\n\t\t\t\t\t\t\t$ascii .= '\\t';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase $ord_var_c == 0x0A:\n\t\t\t\t\t\t\t$ascii .= '\\n';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase $ord_var_c == 0x0C:\n\t\t\t\t\t\t\t$ascii .= '\\f';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase $ord_var_c == 0x0D:\n\t\t\t\t\t\t\t$ascii .= '\\r';\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase $ord_var_c == 0x22:\n\t\t\t\t\t\tcase $ord_var_c == 0x2F:\n\t\t\t\t\t\tcase $ord_var_c == 0x5C:\n\t\t\t\t\t\t\t// double quote, slash, slosh\n\t\t\t\t\t\t\t$ascii .= '\\\\'.$var[$c];\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):\n\t\t\t\t\t\t\t// characters U-00000000 - U-0000007F (same as ASCII)\n\t\t\t\t\t\t\t$ascii .= $var[$c];\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase (($ord_var_c & 0xE0) == 0xC0):\n\t\t\t\t\t\t\t// characters U-00000080 - U-000007FF, mask 110XXXXX\n\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\tif ($c+1 >= $strlen_var) {\n\t\t\t\t\t\t\t\t$c += 1;\n\t\t\t\t\t\t\t\t$ascii .= '?';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$char = pack('C*', $ord_var_c, ord($var[$c + 1]));\n\t\t\t\t\t\t\t$c += 1;\n\t\t\t\t\t\t\t$utf16 = $this->utf82utf16($char);\n\t\t\t\t\t\t\t$ascii .= sprintf('\\u%04s', bin2hex($utf16));\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase (($ord_var_c & 0xF0) == 0xE0):\n\t\t\t\t\t\t\tif ($c+2 >= $strlen_var) {\n\t\t\t\t\t\t\t\t$c += 2;\n\t\t\t\t\t\t\t\t$ascii .= '?';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// characters U-00000800 - U-0000FFFF, mask 1110XXXX\n\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\t$char = pack('C*', $ord_var_c,\n\t\t\t\t\t\t\t\t\t\t@ord($var[$c + 1]),\n\t\t\t\t\t\t\t\t\t\t@ord($var[$c + 2]));\n\t\t\t\t\t\t\t$c += 2;\n\t\t\t\t\t\t\t$utf16 = $this->utf82utf16($char);\n\t\t\t\t\t\t\t$ascii .= sprintf('\\u%04s', bin2hex($utf16));\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase (($ord_var_c & 0xF8) == 0xF0):\n\t\t\t\t\t\t\tif ($c+3 >= $strlen_var) {\n\t\t\t\t\t\t\t\t$c += 3;\n\t\t\t\t\t\t\t\t$ascii .= '?';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// characters U-00010000 - U-001FFFFF, mask 11110XXX\n\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\t$char = pack('C*', $ord_var_c,\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 1]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 2]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 3]));\n\t\t\t\t\t\t\t$c += 3;\n\t\t\t\t\t\t\t$utf16 = $this->utf82utf16($char);\n\t\t\t\t\t\t\t$ascii .= sprintf('\\u%04s', bin2hex($utf16));\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase (($ord_var_c & 0xFC) == 0xF8):\n\t\t\t\t\t\t\t// characters U-00200000 - U-03FFFFFF, mask 111110XX\n\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\tif ($c+4 >= $strlen_var) {\n\t\t\t\t\t\t\t\t$c += 4;\n\t\t\t\t\t\t\t\t$ascii .= '?';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$char = pack('C*', $ord_var_c,\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 1]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 2]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 3]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 4]));\n\t\t\t\t\t\t\t$c += 4;\n\t\t\t\t\t\t\t$utf16 = $this->utf82utf16($char);\n\t\t\t\t\t\t\t$ascii .= sprintf('\\u%04s', bin2hex($utf16));\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase (($ord_var_c & 0xFE) == 0xFC):\n\t\t\t\t\t\tif ($c+5 >= $strlen_var) {\n\t\t\t\t\t\t\t\t$c += 5;\n\t\t\t\t\t\t\t\t$ascii .= '?';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// characters U-04000000 - U-7FFFFFFF, mask 1111110X\n\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\t$char = pack('C*', $ord_var_c,\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 1]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 2]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 3]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 4]),\n\t\t\t\t\t\t\t\t\t\tord($var[$c + 5]));\n\t\t\t\t\t\t\t$c += 5;\n\t\t\t\t\t\t\t$utf16 = $this->utf82utf16($char);\n\t\t\t\t\t\t\t$ascii .= sprintf('\\u%04s', bin2hex($utf16));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn  '\"'.$ascii.'\"';\n\n\t\t\tcase 'array':\n\t\t\t/*\n\t\t\t\t* As per JSON spec if any array key is not an integer\n\t\t\t\t* we must treat the the whole array as an object. We\n\t\t\t\t* also try to catch a sparsely populated associative\n\t\t\t\t* array with numeric keys here because some JS engines\n\t\t\t\t* will create an array with empty indexes up to\n\t\t\t\t* max_index which can cause memory issues and because\n\t\t\t\t* the keys, which may be relevant, will be remapped\n\t\t\t\t* otherwise.\n\t\t\t\t*\n\t\t\t\t* As per the ECMA and JSON specification an object may\n\t\t\t\t* have any string as a property. Unfortunately due to\n\t\t\t\t* a hole in the ECMA specification if the key is a\n\t\t\t\t* ECMA reserved word or starts with a digit the\n\t\t\t\t* parameter is only accessible using ECMAScript's\n\t\t\t\t* bracket notation.\n\t\t\t\t*/\n\n\t\t\t\t// treat as a JSON object\n\t\t\t\tif (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {\n\t\t\t\t\t$properties = array_map(array($this, 'name_value'),\n\t\t\t\t\t\t\t\t\t\t\tarray_keys($var),\n\t\t\t\t\t\t\t\t\t\t\tarray_values($var));\n\n\t\t\t\t\tforeach($properties as $property) {\n\t\t\t\t\t\tif(Services_JSON::isError($property)) {\n\t\t\t\t\t\t\treturn $property;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn '{' . join(',', $properties) . '}';\n\t\t\t\t}\n\n\t\t\t\t// treat it like a regular array\n\t\t\t\t$elements = array_map(array($this, '_encode'), $var);\n\n\t\t\t\tforeach($elements as $element) {\n\t\t\t\t\tif(Services_JSON::isError($element)) {\n\t\t\t\t\t\treturn $element;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn '[' . join(',', $elements) . ']';\n\n\t\t\tcase 'object':\n\t\t\t\t$vars = get_object_vars($var);\n\n\t\t\t\t$properties = array_map(array($this, 'name_value'),\n\t\t\t\t\t\t\t\t\t\tarray_keys($vars),\n\t\t\t\t\t\t\t\t\t\tarray_values($vars));\n\n\t\t\t\tforeach($properties as $property) {\n\t\t\t\t\tif(Services_JSON::isError($property)) {\n\t\t\t\t\t\treturn $property;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn '{' . join(',', $properties) . '}';\n\n\t\t\tdefault:\n\t\t\t\treturn ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)\n\t\t\t\t\t? 'null'\n\t\t\t\t\t: new Services_JSON_Error(gettype($var).\" can not be encoded as JSON string\");\n\t\t}\n\t}\n\n /**\n\t* array-walking function for use in generating JSON-formatted name-value pairs\n\t*\n\t* @param\tstring  $name name of key to use\n\t* @param\tmixed $value  reference to an array element to be encoded\n\t*\n\t* @return string  JSON-formatted name-value pair, like '\"name\":value'\n\t* @access private\n\t*/\n\tfunction name_value($name, $value)\n\t{\n\t\t$encoded_value = $this->_encode($value);\n\n\t\tif(Services_JSON::isError($encoded_value)) {\n\t\t\treturn $encoded_value;\n\t\t}\n\n\t\treturn $this->_encode(strval($name)) . ':' . $encoded_value;\n\t}\n\n /**\n\t* reduce a string by removing leading and trailing comments and whitespace\n\t*\n\t* @param\t$str\tstring\tstring value to strip of comments and whitespace\n\t*\n\t* @return string  string value stripped of comments and whitespace\n\t* @access private\n\t*/\n\tfunction reduce_string($str)\n\t{\n\t\t$str = preg_replace(array(\n\n\t\t\t\t// eliminate single line comments in '// ...' form\n\t\t\t\t'#^\\s*//(.+)$#m',\n\n\t\t\t\t// eliminate multi-line comments in '/* ... */' form, at start of string\n\t\t\t\t'#^\\s*/\\*(.+)\\*/#Us',\n\n\t\t\t\t// eliminate multi-line comments in '/* ... */' form, at end of string\n\t\t\t\t'#/\\*(.+)\\*/\\s*$#Us'\n\n\t\t\t), '', $str);\n\n\t\t// eliminate extraneous space\n\t\treturn trim($str);\n\t}\n\n /**\n\t* decodes a JSON string into appropriate variable\n\t*\n\t* @param\tstring  $str\tJSON-formatted string\n\t*\n\t* @return mixed number, boolean, string, array, or object\n\t*\t\t\t\tcorresponding to given JSON input string.\n\t*\t\t\t\tSee argument 1 to Services_JSON() above for object-output behavior.\n\t*\t\t\t\tNote that decode() always returns strings\n\t*\t\t\t\tin ASCII or UTF-8 format!\n\t* @access public\n\t*/\n\tfunction decode($str)\n\t{\n\t\t$str = $this->reduce_string($str);\n\n\t\tswitch (strtolower($str)) {\n\t\t\tcase 'true':\n\t\t\t\treturn true;\n\n\t\t\tcase 'false':\n\t\t\t\treturn false;\n\n\t\t\tcase 'null':\n\t\t\t\treturn null;\n\n\t\t\tdefault:\n\t\t\t\t$m = array();\n\n\t\t\t\tif (is_numeric($str)) {\n\t\t\t\t\t// Lookie-loo, it's a number\n\n\t\t\t\t\t// This would work on its own, but I'm trying to be\n\t\t\t\t\t// good about returning integers where appropriate:\n\t\t\t\t\t// return (float)$str;\n\n\t\t\t\t\t// Return float or int, as appropriate\n\t\t\t\t\treturn ((float)$str == (integer)$str)\n\t\t\t\t\t\t? (integer)$str\n\t\t\t\t\t\t: (float)$str;\n\n\t\t\t\t} elseif (preg_match('/^(\"|\\').*(\\1)$/s', $str, $m) && $m[1] == $m[2]) {\n\t\t\t\t\t// STRINGS RETURNED IN UTF-8 FORMAT\n\t\t\t\t\t$delim = substr($str, 0, 1);\n\t\t\t\t\t$chrs = substr($str, 1, -1);\n\t\t\t\t\t$utf8 = '';\n\t\t\t\t\t$strlen_chrs = strlen($chrs);\n\n\t\t\t\t\tfor ($c = 0; $c < $strlen_chrs; ++$c) {\n\n\t\t\t\t\t\t$substr_chrs_c_2 = substr($chrs, $c, 2);\n\t\t\t\t\t\t$ord_chrs_c = ord($chrs[$c]);\n\n\t\t\t\t\t\tswitch (true) {\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\b':\n\t\t\t\t\t\t\t\t$utf8 .= chr(0x08);\n\t\t\t\t\t\t\t\t++$c;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\t':\n\t\t\t\t\t\t\t\t$utf8 .= chr(0x09);\n\t\t\t\t\t\t\t\t++$c;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\n':\n\t\t\t\t\t\t\t\t$utf8 .= chr(0x0A);\n\t\t\t\t\t\t\t\t++$c;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\f':\n\t\t\t\t\t\t\t\t$utf8 .= chr(0x0C);\n\t\t\t\t\t\t\t\t++$c;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\r':\n\t\t\t\t\t\t\t\t$utf8 .= chr(0x0D);\n\t\t\t\t\t\t\t\t++$c;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\\\\"':\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\\\\\'':\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\\\\\\\':\n\t\t\t\t\t\t\tcase $substr_chrs_c_2 == '\\\\/':\n\t\t\t\t\t\t\t\tif (($delim == '\"' && $substr_chrs_c_2 != '\\\\\\'') ||\n\t\t\t\t\t\t\t\t($delim == \"'\" && $substr_chrs_c_2 != '\\\\\"')) {\n\t\t\t\t\t\t\t\t\t$utf8 .= $chrs[++$c];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase preg_match('/\\\\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):\n\t\t\t\t\t\t\t\t// single, escaped unicode character\n\t\t\t\t\t\t\t\t$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))\n\t\t\t\t\t\t\t\t\t. chr(hexdec(substr($chrs, ($c + 4), 2)));\n\t\t\t\t\t\t\t\t$utf8 .= $this->utf162utf8($utf16);\n\t\t\t\t\t\t\t\t$c += 5;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):\n\t\t\t\t\t\t\t\t$utf8 .= $chrs[$c];\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase ($ord_chrs_c & 0xE0) == 0xC0:\n\t\t\t\t\t\t\t\t// characters U-00000080 - U-000007FF, mask 110XXXXX\n\t\t\t\t\t\t\t\t//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\t\t$utf8 .= substr($chrs, $c, 2);\n\t\t\t\t\t\t\t\t++$c;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase ($ord_chrs_c & 0xF0) == 0xE0:\n\t\t\t\t\t\t\t\t// characters U-00000800 - U-0000FFFF, mask 1110XXXX\n\t\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\t\t$utf8 .= substr($chrs, $c, 3);\n\t\t\t\t\t\t\t\t$c += 2;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase ($ord_chrs_c & 0xF8) == 0xF0:\n\t\t\t\t\t\t\t\t// characters U-00010000 - U-001FFFFF, mask 11110XXX\n\t\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\t\t$utf8 .= substr($chrs, $c, 4);\n\t\t\t\t\t\t\t\t$c += 3;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase ($ord_chrs_c & 0xFC) == 0xF8:\n\t\t\t\t\t\t\t\t// characters U-00200000 - U-03FFFFFF, mask 111110XX\n\t\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\t\t$utf8 .= substr($chrs, $c, 5);\n\t\t\t\t\t\t\t\t$c += 4;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase ($ord_chrs_c & 0xFE) == 0xFC:\n\t\t\t\t\t\t\t\t// characters U-04000000 - U-7FFFFFFF, mask 1111110X\n\t\t\t\t\t\t\t\t// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8\n\t\t\t\t\t\t\t\t$utf8 .= substr($chrs, $c, 6);\n\t\t\t\t\t\t\t\t$c += 5;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn $utf8;\n\n\t\t\t\t} elseif (preg_match('/^\\[.*\\]$/s', $str) || preg_match('/^\\{.*\\}$/s', $str)) {\n\t\t\t\t\t// array, or object notation\n\n\t\t\t\t\tif ($str[0] == '[') {\n\t\t\t\t\t\t$stk = array(SERVICES_JSON_IN_ARR);\n\t\t\t\t\t\t$arr = array();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ($this->use & SERVICES_JSON_LOOSE_TYPE) {\n\t\t\t\t\t\t\t$stk = array(SERVICES_JSON_IN_OBJ);\n\t\t\t\t\t\t\t$obj = array();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$stk = array(SERVICES_JSON_IN_OBJ);\n\t\t\t\t\t\t\t$obj = new stdClass();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tarray_push($stk, array('what'  => SERVICES_JSON_SLICE,\n\t\t\t\t\t\t\t\t\t\t'where' => 0,\n\t\t\t\t\t\t\t\t\t\t'delim' => false));\n\n\t\t\t\t\t$chrs = substr($str, 1, -1);\n\t\t\t\t\t$chrs = $this->reduce_string($chrs);\n\n\t\t\t\t\tif ($chrs == '') {\n\t\t\t\t\t\tif (reset($stk) == SERVICES_JSON_IN_ARR) {\n\t\t\t\t\t\t\treturn $arr;\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn $obj;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t//print(\"\\nparsing {$chrs}\\n\");\n\n\t\t\t\t\t$strlen_chrs = strlen($chrs);\n\n\t\t\t\t\tfor ($c = 0; $c <= $strlen_chrs; ++$c) {\n\n\t\t\t\t\t\t$top = end($stk);\n\t\t\t\t\t\t$substr_chrs_c_2 = substr($chrs, $c, 2);\n\n\t\t\t\t\t\tif (($c == $strlen_chrs) || (($chrs[$c] == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {\n\t\t\t\t\t\t\t// found a comma that is not inside a string, array, etc.,\n\t\t\t\t\t\t\t// OR we've reached the end of the character list\n\t\t\t\t\t\t\t$slice = substr($chrs, $top['where'], ($c - $top['where']));\n\t\t\t\t\t\t\tarray_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));\n\t\t\t\t\t\t\t//print(\"Found split at {$c}: \".substr($chrs, $top['where'], (1 + $c - $top['where'])).\"\\n\");\n\n\t\t\t\t\t\t\tif (reset($stk) == SERVICES_JSON_IN_ARR) {\n\t\t\t\t\t\t\t\t// we are in an array, so just push an element onto the stack\n\t\t\t\t\t\t\t\tarray_push($arr, $this->decode($slice));\n\n\t\t\t\t\t\t\t} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {\n\t\t\t\t\t\t\t\t// we are in an object, so figure\n\t\t\t\t\t\t\t\t// out the property name and set an\n\t\t\t\t\t\t\t\t// element in an associative array,\n\t\t\t\t\t\t\t\t// for now\n\t\t\t\t\t\t\t\t$parts = array();\n\n\t\t\t\t\t\t\t\tif (preg_match('/^\\s*([\"\\'].*[^\\\\\\][\"\\'])\\s*:\\s*(\\S.*),?$/Uis', $slice, $parts)) {\n\t\t\t\t\t\t\t\t\t// \"name\":value pair\n\t\t\t\t\t\t\t\t\t$key = $this->decode($parts[1]);\n\t\t\t\t\t\t\t\t\t$val = $this->decode($parts[2]);\n\n\t\t\t\t\t\t\t\t\tif ($this->use & SERVICES_JSON_LOOSE_TYPE) {\n\t\t\t\t\t\t\t\t\t\t$obj[$key] = $val;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t$obj->$key = $val;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} elseif (preg_match('/^\\s*(\\w+)\\s*:\\s*(\\S.*),?$/Uis', $slice, $parts)) {\n\t\t\t\t\t\t\t\t\t// name:value pair, where name is unquoted\n\t\t\t\t\t\t\t\t\t$key = $parts[1];\n\t\t\t\t\t\t\t\t\t$val = $this->decode($parts[2]);\n\n\t\t\t\t\t\t\t\t\tif ($this->use & SERVICES_JSON_LOOSE_TYPE) {\n\t\t\t\t\t\t\t\t\t\t$obj[$key] = $val;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t$obj->$key = $val;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} elseif ((($chrs[$c] == '\"') || ($chrs[$c] == \"'\")) && ($top['what'] != SERVICES_JSON_IN_STR)) {\n\t\t\t\t\t\t\t// found a quote, and we are not inside a string\n\t\t\t\t\t\t\tarray_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs[$c]));\n\t\t\t\t\t\t\t//print(\"Found start of string at {$c}\\n\");\n\n\t\t\t\t\t\t} elseif (($chrs[$c] == $top['delim']) &&\n\t\t\t\t\t\t\t\t($top['what'] == SERVICES_JSON_IN_STR) &&\n\t\t\t\t\t\t\t\t((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\\\'))) % 2 != 1)) {\n\t\t\t\t\t\t\t// found a quote, we're in a string, and it's not escaped\n\t\t\t\t\t\t\t// we know that it's not escaped becase there is _not_ an\n\t\t\t\t\t\t\t// odd number of backslashes at the end of the string so far\n\t\t\t\t\t\t\tarray_pop($stk);\n\t\t\t\t\t\t\t//print(\"Found end of string at {$c}: \".substr($chrs, $top['where'], (1 + 1 + $c - $top['where'])).\"\\n\");\n\n\t\t\t\t\t\t} elseif (($chrs[$c] == '[') &&\n\t\t\t\t\t\t\t\tin_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {\n\t\t\t\t\t\t\t// found a left-bracket, and we are in an array, object, or slice\n\t\t\t\t\t\t\tarray_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));\n\t\t\t\t\t\t\t//print(\"Found start of array at {$c}\\n\");\n\n\t\t\t\t\t\t} elseif (($chrs[$c] == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {\n\t\t\t\t\t\t\t// found a right-bracket, and we're in an array\n\t\t\t\t\t\t\tarray_pop($stk);\n\t\t\t\t\t\t\t//print(\"Found end of array at {$c}: \".substr($chrs, $top['where'], (1 + $c - $top['where'])).\"\\n\");\n\n\t\t\t\t\t\t} elseif (($chrs[$c] == '{') &&\n\t\t\t\t\t\t\t\tin_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {\n\t\t\t\t\t\t\t// found a left-brace, and we are in an array, object, or slice\n\t\t\t\t\t\t\tarray_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));\n\t\t\t\t\t\t\t//print(\"Found start of object at {$c}\\n\");\n\n\t\t\t\t\t\t} elseif (($chrs[$c] == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {\n\t\t\t\t\t\t\t// found a right-brace, and we're in an object\n\t\t\t\t\t\t\tarray_pop($stk);\n\t\t\t\t\t\t\t//print(\"Found end of object at {$c}: \".substr($chrs, $top['where'], (1 + $c - $top['where'])).\"\\n\");\n\n\t\t\t\t\t\t} elseif (($substr_chrs_c_2 == '/*') &&\n\t\t\t\t\t\t\t\tin_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {\n\t\t\t\t\t\t\t// found a comment start, and we are in an array, object, or slice\n\t\t\t\t\t\t\tarray_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));\n\t\t\t\t\t\t\t$c++;\n\t\t\t\t\t\t\t//print(\"Found start of comment at {$c}\\n\");\n\n\t\t\t\t\t\t} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {\n\t\t\t\t\t\t\t// found a comment end, and we're in one now\n\t\t\t\t\t\t\tarray_pop($stk);\n\t\t\t\t\t\t\t$c++;\n\n\t\t\t\t\t\t\tfor ($i = $top['where']; $i <= $c; ++$i)\n\t\t\t\t\t\t\t\t$chrs = substr_replace($chrs, ' ', $i, 1);\n\n\t\t\t\t\t\t\t//print(\"Found end of comment at {$c}: \".substr($chrs, $top['where'], (1 + $c - $top['where'])).\"\\n\");\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif (reset($stk) == SERVICES_JSON_IN_ARR) {\n\t\t\t\t\t\treturn $arr;\n\n\t\t\t\t\t} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {\n\t\t\t\t\t\treturn $obj;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t* @todo Ultimately, this should just call PEAR::isError()\n\t*/\n\tfunction isError($data, $code = null)\n\t{\n\t\tif (class_exists('pear')) {\n\t\t\treturn PEAR::isError($data, $code);\n\t\t} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||\n\t\t\t\t\t\t\t\tis_subclass_of($data, 'services_json_error'))) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\nif (class_exists('PEAR_Error')) {\n\n\tclass Services_JSON_Error extends PEAR_Error\n\t{\n\t\tfunction Services_JSON_Error($message = 'unknown error', $code = null,\n\t\t\t\t\t\t\t\t\t$mode = null, $options = null, $userinfo = null)\n\t\t{\n\t\t\tparent::PEAR_Error($message, $code, $mode, $options, $userinfo);\n\t\t}\n\t}\n\n} else {\n\n\t/**\n\t* @todo Ultimately, this class shall be descended from PEAR_Error\n\t*/\n\tclass Services_JSON_Error\n\t{\n\t\tfunction Services_JSON_Error($message = 'unknown error', $code = null,\n\t\t\t\t\t\t\t\t\t$mode = null, $options = null, $userinfo = null)\n\t\t{\n\n\t\t}\n\t}\n\n}\nendif;\n\n\n/**\n * 为了兼容低版本的php而增加的函数集\n * json从5.2.0开始支持，wordpress 2.9开始提供json函数的兼容性代码\n */\nif ( !function_exists('json_encode') ) {\n\tfunction json_encode( $string ) {\n\t\tglobal $wp_json;\n\n\t\tif ( !is_a($wp_json, 'Services_JSON') ) {\n\t\t\t$wp_json = new Services_JSON();\n\t\t}\n\n\t\treturn $wp_json->encodeUnsafe( $string );\n\t}\n}\n\nif ( !function_exists('json_decode') ) {\n\tfunction json_decode( $string, $assoc_array = false ) {\n\t\tglobal $wp_json;\n\n\t\tif ( !is_a($wp_json, 'Services_JSON') ) {\n\t\t\t$wp_json = new Services_JSON();\n\t\t}\n\n\t\t$res = $wp_json->decode( $string );\n\t\tif ( $assoc_array )\n\t\t\t$res = _json_decode_object_helper( $res );\n\t\treturn $res;\n\t}\n\tfunction _json_decode_object_helper($data) {\n\t\tif ( is_object($data) )\n\t\t\t$data = get_object_vars($data);\n\t\treturn is_array($data) ? array_map(__FUNCTION__, $data) : $data;\n\t}\n}\n"
  },
  {
    "path": "BlockComment/Plugin.php",
    "content": "<?php\n/**\n * 增加评论黑名单（根据 IP 地址过滤）\n * \n * @package Block Comment\n * @author 明城\n * @version 0.0.1\n * @link http://typecho.org\n */\nclass BlockComment_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Feedback')->comment   = array('BlockComment_Plugin', 'filter');\n        Typecho_Plugin::factory('Widget_Feedback')->trackback = array('BlockComment_Plugin', 'filter');\n        Typecho_Plugin::factory('Widget_XmlRpc')->pingback    = array('BlockComment_Plugin', 'filter');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $hosts = new Typecho_Widget_Helper_Form_Element_Textarea('hosts', NULL, NULL, \n            _t('地址列表'), _t('每行单个地址，请仔细匹配以免误封杀'));\n\n        $form->addInput($hosts);\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n\n    \n    /**\n     * 标记评论状态时的插件接口\n     * \n     * @access public\n     * @param array $comment 评论数据的结构体\n     * @param Typecho_Widget $commentWidget 评论组件\n     * @param string $status 评论状态\n     * @return void\n     */\n    public static function mark($comment, $commentWidget, $status)\n    {\n        if ('spam' == $comment['status'] && $status != 'spam') {\n            self::filter($comment, $commentWidget, NULL, 'submit-ham');\n        } else if ('spam' != $comment['status'] && $status == 'spam') {\n            self::filter($comment, $commentWidget, NULL, 'submit-spam');\n        }\n    }\n    \n    /**\n     * 评论过滤器\n     * \n     * @access public\n     * @param array $comment 评论结构\n     * @param Typecho_Widget $post 被评论的文章\n     * @param array $result 返回的结果上下文\n     * @param string $api api地址\n     * @return void\n     */\n    public static function filter($comment, $post, $result, $api = 'comment-check')\n    {\n        $comment = empty($result) ? $comment : $result;\n    \n        $options = Typecho_Widget::widget('Widget_Options');\n        $hosts   = $options->plugin('BlockComment')->hosts;\n        \n        $data = array(\n            'blog'                  =>  $options->siteUrl,\n            'user_ip'               =>  $comment['ip'],\n            'user_agent'            =>  $comment['agent'],\n            'referrer'              =>  Typecho_Request::getInstance()->getReferer(),\n            'permalink'             =>  $post->permalink,\n            'comment_type'          =>  $comment['type'],\n            'comment_author'        =>  $comment['author'],\n            'comment_author_email'  =>  $comment['mail'],\n            'comment_author_url'    =>  $comment['url'],\n            'comment_content'       =>  $comment['text']\n        );\n\n        foreach(split(\"\\n\", $hosts) as $key => $value){\n            $value = trim($value);\n            if (strlen($value)) {\n                $regex = sprintf(\"/^%s/i\", preg_quote($value));\n\n                // 如果提交者符合指定的 IP，则扔进垃圾评论中\n                if (preg_match($regex, $data['user_ip'])) {\n                    $comment['status'] = 'spam';\n                    break;\n                }\n            }\n        }\n\n        return $comment;\n    }\n}\n"
  },
  {
    "path": "ConnectToTwitter/OAuth.php",
    "content": "<?php\n// vim: foldmethod=marker\n\n/* Generic exception class\n */\nclass OAuthException extends Exception {/*{{{*/\n  // pass\n}/*}}}*/\n\nclass OAuthConsumer {/*{{{*/\n  public $key;\n  public $secret;\n\n  function __construct($key, $secret, $callback_url=NULL) {/*{{{*/\n    $this->key = $key;\n    $this->secret = $secret;\n    $this->callback_url = $callback_url;\n  }/*}}}*/\n\n  function __toString() {/*{{{*/\n    return \"OAuthConsumer[key=$this->key,secret=$this->secret]\";\n  }/*}}}*/\n}/*}}}*/\n\nclass OAuthToken {/*{{{*/\n  // access tokens and request tokens\n  public $key;\n  public $secret;\n\n  /**\n   * key = the token\n   * secret = the token secret\n   */\n  function __construct($key, $secret) {/*{{{*/\n    $this->key = $key;\n    $this->secret = $secret;\n  }/*}}}*/\n\n  /**\n   * generates the basic string serialization of a token that a server\n   * would respond to request_token and access_token calls with\n   */\n  function to_string() {/*{{{*/\n    return \"oauth_token=\" . OAuthUtil::urlencode_rfc3986($this->key) .\n        \"&oauth_token_secret=\" . OAuthUtil::urlencode_rfc3986($this->secret);\n  }/*}}}*/\n\n  function __toString() {/*{{{*/\n    return $this->to_string();\n  }/*}}}*/\n}/*}}}*/\n\nclass OAuthSignatureMethod {/*{{{*/\n  public function check_signature(&$request, $consumer, $token, $signature) {\n    $built = $this->build_signature($request, $consumer, $token);\n    return $built == $signature;\n  }\n}/*}}}*/\n\nclass OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {/*{{{*/\n  function get_name() {/*{{{*/\n    return \"HMAC-SHA1\";\n  }/*}}}*/\n\n  public function build_signature($request, $consumer, $token) {/*{{{*/\n    $base_string = $request->get_signature_base_string();\n    $request->base_string = $base_string;\n\n    $key_parts = array(\n      $consumer->secret,\n      ($token) ? $token->secret : \"\"\n    );\n\n    $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);\n    $key = implode('&', $key_parts);\n\n    return base64_encode( hash_hmac('sha1', $base_string, $key, true));\n  }/*}}}*/\n}/*}}}*/\n\nclass OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {/*{{{*/\n  public function get_name() {/*{{{*/\n    return \"PLAINTEXT\";\n  }/*}}}*/\n\n  public function build_signature($request, $consumer, $token) {/*{{{*/\n    $sig = array(\n      OAuthUtil::urlencode_rfc3986($consumer->secret)\n    );\n\n    if ($token) {\n      array_push($sig, OAuthUtil::urlencode_rfc3986($token->secret));\n    } else {\n      array_push($sig, '');\n    }\n\n    $raw = implode(\"&\", $sig);\n    // for debug purposes\n    $request->base_string = $raw;\n\n    return OAuthUtil::urlencode_rfc3986($raw);\n  }/*}}}*/\n}/*}}}*/\n\nclass OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {/*{{{*/\n  public function get_name() {/*{{{*/\n    return \"RSA-SHA1\";\n  }/*}}}*/\n\n  protected function fetch_public_cert(&$request) {/*{{{*/\n    // not implemented yet, ideas are:\n    // (1) do a lookup in a table of trusted certs keyed off of consumer\n    // (2) fetch via http using a url provided by the requester\n    // (3) some sort of specific discovery code based on request\n    //\n    // either way should return a string representation of the certificate\n    throw Exception(\"fetch_public_cert not implemented\");\n  }/*}}}*/\n\n  protected function fetch_private_cert(&$request) {/*{{{*/\n    // not implemented yet, ideas are:\n    // (1) do a lookup in a table of trusted certs keyed off of consumer\n    //\n    // either way should return a string representation of the certificate\n    throw Exception(\"fetch_private_cert not implemented\");\n  }/*}}}*/\n\n  public function build_signature(&$request, $consumer, $token) {/*{{{*/\n    $base_string = $request->get_signature_base_string();\n    $request->base_string = $base_string;\n\n    // Fetch the private key cert based on the request\n    $cert = $this->fetch_private_cert($request);\n\n    // Pull the private key ID from the certificate\n    $privatekeyid = openssl_get_privatekey($cert);\n\n    // Sign using the key\n    $ok = openssl_sign($base_string, $signature, $privatekeyid);\n\n    // Release the key resource\n    openssl_free_key($privatekeyid);\n\n    return base64_encode($signature);\n  } /*}}}*/\n\n  public function check_signature(&$request, $consumer, $token, $signature) {/*{{{*/\n    $decoded_sig = base64_decode($signature);\n\n    $base_string = $request->get_signature_base_string();\n\n    // Fetch the public key cert based on the request\n    $cert = $this->fetch_public_cert($request);\n\n    // Pull the public key ID from the certificate\n    $publickeyid = openssl_get_publickey($cert);\n\n    // Check the computed signature against the one passed in the query\n    $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);\n\n    // Release the key resource\n    openssl_free_key($publickeyid);\n\n    return $ok == 1;\n  } /*}}}*/\n}/*}}}*/\n\nclass OAuthRequest {/*{{{*/\n  private $parameters;\n  private $http_method;\n  private $http_url;\n  // for debug purposes\n  public $base_string;\n  public static $version = '1.0';\n\n  function __construct($http_method, $http_url, $parameters=NULL) {/*{{{*/\n    @$parameters or $parameters = array();\n    $this->parameters = $parameters;\n    $this->http_method = $http_method;\n    $this->http_url = $http_url;\n  }/*}}}*/\n\n\n  /**\n   * attempt to build up a request from what was passed to the server\n   */\n  public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {/*{{{*/\n    $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != \"on\") ? 'http' : 'https';\n    @$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];\n    @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];\n\n    $request_headers = OAuthRequest::get_headers();\n\n    // let the library user override things however they'd like, if they know\n    // which parameters to use then go for it, for example XMLRPC might want to\n    // do this\n    if ($parameters) {\n      $req = new OAuthRequest($http_method, $http_url, $parameters);\n    } else {\n      // collect request parameters from query string (GET) and post-data (POST) if appropriate (note: POST vars have priority)\n      $req_parameters = $_GET;\n      if ($http_method == \"POST\" && @strstr($request_headers[\"Content-Type\"], \"application/x-www-form-urlencoded\") ) {\n        $req_parameters = array_merge($req_parameters, $_POST);\n      }\n\n      // next check for the auth header, we need to do some extra stuff\n      // if that is the case, namely suck in the parameters from GET or POST\n      // so that we can include them in the signature\n      if (@substr($request_headers['Authorization'], 0, 6) == \"OAuth \") {\n        $header_parameters = OAuthRequest::split_header($request_headers['Authorization']);\n        $parameters = array_merge($req_parameters, $header_parameters);\n        $req = new OAuthRequest($http_method, $http_url, $parameters);\n      } else $req = new OAuthRequest($http_method, $http_url, $req_parameters);\n    }\n\n    return $req;\n  }/*}}}*/\n\n  /**\n   * pretty much a helper function to set up the request\n   */\n  public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {/*{{{*/\n    @$parameters or $parameters = array();\n    $defaults = array(\"oauth_version\" => OAuthRequest::$version,\n                      \"oauth_nonce\" => OAuthRequest::generate_nonce(),\n                      \"oauth_timestamp\" => OAuthRequest::generate_timestamp(),\n                      \"oauth_consumer_key\" => $consumer->key);\n    $parameters = array_merge($defaults, $parameters);\n\n    if ($token) {\n      $parameters['oauth_token'] = $token->key;\n    }\n    return new OAuthRequest($http_method, $http_url, $parameters);\n  }/*}}}*/\n\n  public function set_parameter($name, $value) {/*{{{*/\n    $this->parameters[$name] = $value;\n  }/*}}}*/\n\n  public function get_parameter($name) {/*{{{*/\n    return isset($this->parameters[$name]) ? $this->parameters[$name] : null;\n  }/*}}}*/\n\n  public function get_parameters() {/*{{{*/\n    return $this->parameters;\n  }/*}}}*/\n\n  /**\n   * Returns the normalized parameters of the request\n   *\n   * This will be all (except oauth_signature) parameters,\n   * sorted first by key, and if duplicate keys, then by\n   * value.\n   *\n   * The returned string will be all the key=value pairs\n   * concated by &.\n   *\n   * @return string\n   */\n  public function get_signable_parameters() {/*{{{*/\n    // Grab all parameters\n    $params = $this->parameters;\n\n    // Remove oauth_signature if present\n    if (isset($params['oauth_signature'])) {\n      unset($params['oauth_signature']);\n    }\n\n    // Urlencode both keys and values\n    $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));\n    $values = OAuthUtil::urlencode_rfc3986(array_values($params));\n    $params = array_combine($keys, $values);\n\n    // Sort by keys (natsort)\n    uksort($params, 'strcmp');\n\n    // Generate key=value pairs\n    $pairs = array();\n    foreach ($params as $key=>$value ) {\n      if (is_array($value)) {\n        // If the value is an array, it's because there are multiple\n        // with the same key, sort them, then add all the pairs\n        natsort($value);\n        foreach ($value as $v2) {\n          $pairs[] = $key . '=' . $v2;\n        }\n      } else {\n        $pairs[] = $key . '=' . $value;\n      }\n    }\n\n    // Return the pairs, concated with &\n    return implode('&', $pairs);\n  }/*}}}*/\n\n  /**\n   * Returns the base string of this request\n   *\n   * The base string defined as the method, the url\n   * and the parameters (normalized), each urlencoded\n   * and the concated with &.\n   */\n  public function get_signature_base_string() {/*{{{*/\n    $parts = array(\n      $this->get_normalized_http_method(),\n      $this->get_normalized_http_url(),\n      $this->get_signable_parameters()\n    );\n\n    $parts = OAuthUtil::urlencode_rfc3986($parts);\n\n    return implode('&', $parts);\n  }/*}}}*/\n\n  /**\n   * just uppercases the http method\n   */\n  public function get_normalized_http_method() {/*{{{*/\n    return strtoupper($this->http_method);\n  }/*}}}*/\n\n  /**\n   * parses the url and rebuilds it to be\n   * scheme://host/path\n   */\n  public function get_normalized_http_url() {/*{{{*/\n    $parts = parse_url($this->http_url);\n\n    $port = @$parts['port'];\n    $scheme = $parts['scheme'];\n    $host = $parts['host'];\n    $path = @$parts['path'];\n\n    $port or $port = ($scheme == 'https') ? '443' : '80';\n\n    if (($scheme == 'https' && $port != '443')\n        || ($scheme == 'http' && $port != '80')) {\n      $host = \"$host:$port\";\n    }\n    return \"$scheme://$host$path\";\n  }/*}}}*/\n\n  /**\n   * builds a url usable for a GET request\n   */\n  public function to_url() {/*{{{*/\n    $out = $this->get_normalized_http_url() . \"?\";\n    $out .= $this->to_postdata();\n    return $out;\n  }/*}}}*/\n\n  /**\n   * builds the data one would send in a POST request\n   *\n   * TODO(morten.fangel):\n   * this function might be easily replaced with http_build_query()\n   * and corrections for rfc3986 compatibility.. but not sure\n   */\n  public function to_postdata() {/*{{{*/\n    $total = array();\n    foreach ($this->parameters as $k => $v) {\n      if (is_array($v)) {\n        foreach ($v as $va) {\n          $total[] = OAuthUtil::urlencode_rfc3986($k) . \"[]=\" . OAuthUtil::urlencode_rfc3986($va);\n        }\n      } else {\n        $total[] = OAuthUtil::urlencode_rfc3986($k) . \"=\" . OAuthUtil::urlencode_rfc3986($v);\n      }\n    }\n    $out = implode(\"&\", $total);\n    return $out;\n  }/*}}}*/\n\n  /**\n   * builds the Authorization: header\n   */\n  public function to_header() {/*{{{*/\n    $out ='Authorization: OAuth realm=\"\"';\n    $total = array();\n    foreach ($this->parameters as $k => $v) {\n      if (substr($k, 0, 5) != \"oauth\") continue;\n      if (is_array($v)) throw new OAuthException('Arrays not supported in headers');\n      $out .= ',' . OAuthUtil::urlencode_rfc3986($k) . '=\"' . OAuthUtil::urlencode_rfc3986($v) . '\"';\n    }\n    return $out;\n  }/*}}}*/\n\n  public function __toString() {/*{{{*/\n    return $this->to_url();\n  }/*}}}*/\n\n\n  public function sign_request($signature_method, $consumer, $token) {/*{{{*/\n    $this->set_parameter(\"oauth_signature_method\", $signature_method->get_name());\n    $signature = $this->build_signature($signature_method, $consumer, $token);\n    $this->set_parameter(\"oauth_signature\", $signature);\n  }/*}}}*/\n\n  public function build_signature($signature_method, $consumer, $token) {/*{{{*/\n    $signature = $signature_method->build_signature($this, $consumer, $token);\n    return $signature;\n  }/*}}}*/\n\n  /**\n   * util function: current timestamp\n   */\n  private static function generate_timestamp() {/*{{{*/\n    return time();\n  }/*}}}*/\n\n  /**\n   * util function: current nonce\n   */\n  private static function generate_nonce() {/*{{{*/\n    $mt = microtime();\n    $rand = mt_rand();\n\n    return md5($mt . $rand); // md5s look nicer than numbers\n  }/*}}}*/\n\n  /**\n   * util function for turning the Authorization: header into\n   * parameters, has to do some unescaping\n   */\n  private static function split_header($header) {/*{{{*/\n    $pattern = '/(([-_a-z]*)=(\"([^\"]*)\"|([^,]*)),?)/';\n    $offset = 0;\n    $params = array();\n    while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {\n      $match = $matches[0];\n      $header_name = $matches[2][0];\n      $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];\n      $params[$header_name] = OAuthUtil::urldecode_rfc3986( $header_content );\n      $offset = $match[1] + strlen($match[0]);\n    }\n\n    if (isset($params['realm'])) {\n       unset($params['realm']);\n    }\n\n    return $params;\n  }/*}}}*/\n\n  /**\n   * helper to try to sort out headers for people who aren't running apache\n   */\n  private static function get_headers() {/*{{{*/\n    if (function_exists('apache_request_headers')) {\n      // we need this to get the actual Authorization: header\n      // because apache tends to tell us it doesn't exist\n      return apache_request_headers();\n    }\n    // otherwise we don't have apache and are just going to have to hope\n    // that $_SERVER actually contains what we need\n    $out = array();\n    foreach ($_SERVER as $key => $value) {\n      if (substr($key, 0, 5) == \"HTTP_\") {\n        // this is chaos, basically it is just there to capitalize the first\n        // letter of every word that is not an initial HTTP and strip HTTP\n        // code from przemek\n        $key = str_replace(\" \", \"-\", ucwords(strtolower(str_replace(\"_\", \" \", substr($key, 5)))));\n        $out[$key] = $value;\n      }\n    }\n    return $out;\n  }/*}}}*/\n}/*}}}*/\n\nclass OAuthServer {/*{{{*/\n  protected $timestamp_threshold = 300; // in seconds, five minutes\n  protected $version = 1.0;             // hi blaine\n  protected $signature_methods = array();\n\n  protected $data_store;\n\n  function __construct($data_store) {/*{{{*/\n    $this->data_store = $data_store;\n  }/*}}}*/\n\n  public function add_signature_method($signature_method) {/*{{{*/\n    $this->signature_methods[$signature_method->get_name()] =\n        $signature_method;\n  }/*}}}*/\n\n  // high level functions\n\n  /**\n   * process a request_token request\n   * returns the request token on success\n   */\n  public function fetch_request_token(&$request) {/*{{{*/\n    $this->get_version($request);\n\n    $consumer = $this->get_consumer($request);\n\n    // no token required for the initial token request\n    $token = NULL;\n\n    $this->check_signature($request, $consumer, $token);\n\n    $new_token = $this->data_store->new_request_token($consumer);\n\n    return $new_token;\n  }/*}}}*/\n\n  /**\n   * process an access_token request\n   * returns the access token on success\n   */\n  public function fetch_access_token(&$request) {/*{{{*/\n    $this->get_version($request);\n\n    $consumer = $this->get_consumer($request);\n\n    // requires authorized request token\n    $token = $this->get_token($request, $consumer, \"request\");\n\n\n    $this->check_signature($request, $consumer, $token);\n\n    $new_token = $this->data_store->new_access_token($token, $consumer);\n\n    return $new_token;\n  }/*}}}*/\n\n  /**\n   * verify an api call, checks all the parameters\n   */\n  public function verify_request(&$request) {/*{{{*/\n    $this->get_version($request);\n    $consumer = $this->get_consumer($request);\n    $token = $this->get_token($request, $consumer, \"access\");\n    $this->check_signature($request, $consumer, $token);\n    return array($consumer, $token);\n  }/*}}}*/\n\n  // Internals from here\n  /**\n   * version 1\n   */\n  private function get_version(&$request) {/*{{{*/\n    $version = $request->get_parameter(\"oauth_version\");\n    if (!$version) {\n      $version = 1.0;\n    }\n    if ($version && $version != $this->version) {\n      throw new OAuthException(\"OAuth version '$version' not supported\");\n    }\n    return $version;\n  }/*}}}*/\n\n  /**\n   * figure out the signature with some defaults\n   */\n  private function get_signature_method(&$request) {/*{{{*/\n    $signature_method =\n        @$request->get_parameter(\"oauth_signature_method\");\n    if (!$signature_method) {\n      $signature_method = \"PLAINTEXT\";\n    }\n    if (!in_array($signature_method,\n                  array_keys($this->signature_methods))) {\n      throw new OAuthException(\n        \"Signature method '$signature_method' not supported try one of the following: \" . implode(\", \", array_keys($this->signature_methods))\n      );\n    }\n    return $this->signature_methods[$signature_method];\n  }/*}}}*/\n\n  /**\n   * try to find the consumer for the provided request's consumer key\n   */\n  private function get_consumer(&$request) {/*{{{*/\n    $consumer_key = @$request->get_parameter(\"oauth_consumer_key\");\n    if (!$consumer_key) {\n      throw new OAuthException(\"Invalid consumer key\");\n    }\n\n    $consumer = $this->data_store->lookup_consumer($consumer_key);\n    if (!$consumer) {\n      throw new OAuthException(\"Invalid consumer\");\n    }\n\n    return $consumer;\n  }/*}}}*/\n\n  /**\n   * try to find the token for the provided request's token key\n   */\n  private function get_token(&$request, $consumer, $token_type=\"access\") {/*{{{*/\n    $token_field = @$request->get_parameter('oauth_token');\n    $token = $this->data_store->lookup_token(\n      $consumer, $token_type, $token_field\n    );\n    if (!$token) {\n      throw new OAuthException(\"Invalid $token_type token: $token_field\");\n    }\n    return $token;\n  }/*}}}*/\n\n  /**\n   * all-in-one function to check the signature on a request\n   * should guess the signature method appropriately\n   */\n  private function check_signature(&$request, $consumer, $token) {/*{{{*/\n    // this should probably be in a different method\n    $timestamp = @$request->get_parameter('oauth_timestamp');\n    $nonce = @$request->get_parameter('oauth_nonce');\n\n    $this->check_timestamp($timestamp);\n    $this->check_nonce($consumer, $token, $nonce, $timestamp);\n\n    $signature_method = $this->get_signature_method($request);\n\n    $signature = $request->get_parameter('oauth_signature');\n    $valid_sig = $signature_method->check_signature(\n      $request,\n      $consumer,\n      $token,\n      $signature\n    );\n\n    if (!$valid_sig) {\n      throw new OAuthException(\"Invalid signature\");\n    }\n  }/*}}}*/\n\n  /**\n   * check that the timestamp is new enough\n   */\n  private function check_timestamp($timestamp) {/*{{{*/\n    // verify that timestamp is recentish\n    $now = time();\n    if ($now - $timestamp > $this->timestamp_threshold) {\n      throw new OAuthException(\"Expired timestamp, yours $timestamp, ours $now\");\n    }\n  }/*}}}*/\n\n  /**\n   * check that the nonce is not repeated\n   */\n  private function check_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/\n    // verify that the nonce is uniqueish\n    $found = $this->data_store->lookup_nonce($consumer, $token, $nonce, $timestamp);\n    if ($found) {\n      throw new OAuthException(\"Nonce already used: $nonce\");\n    }\n  }/*}}}*/\n\n\n\n}/*}}}*/\n\nclass OAuthDataStore {/*{{{*/\n  function lookup_consumer($consumer_key) {/*{{{*/\n    // implement me\n  }/*}}}*/\n\n  function lookup_token($consumer, $token_type, $token) {/*{{{*/\n    // implement me\n  }/*}}}*/\n\n  function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/\n    // implement me\n  }/*}}}*/\n\n  function new_request_token($consumer) {/*{{{*/\n    // return a new token attached to this consumer\n  }/*}}}*/\n\n  function new_access_token($token, $consumer) {/*{{{*/\n    // return a new access token attached to this consumer\n    // for the user associated with this token if the request token\n    // is authorized\n    // should also invalidate the request token\n  }/*}}}*/\n\n}/*}}}*/\n\n\n/*  A very naive dbm-based oauth storage\n */\nclass SimpleOAuthDataStore extends OAuthDataStore {/*{{{*/\n  private $dbh;\n\n  function __construct($path = \"oauth.gdbm\") {/*{{{*/\n    $this->dbh = dba_popen($path, 'c', 'gdbm');\n  }/*}}}*/\n\n  function __destruct() {/*{{{*/\n    dba_close($this->dbh);\n  }/*}}}*/\n\n  function lookup_consumer($consumer_key) {/*{{{*/\n    $rv = dba_fetch(\"consumer_$consumer_key\", $this->dbh);\n    if ($rv === FALSE) {\n      return NULL;\n    }\n    $obj = unserialize($rv);\n    if (!($obj instanceof OAuthConsumer)) {\n      return NULL;\n    }\n    return $obj;\n  }/*}}}*/\n\n  function lookup_token($consumer, $token_type, $token) {/*{{{*/\n    $rv = dba_fetch(\"${token_type}_${token}\", $this->dbh);\n    if ($rv === FALSE) {\n      return NULL;\n    }\n    $obj = unserialize($rv);\n    if (!($obj instanceof OAuthToken)) {\n      return NULL;\n    }\n    return $obj;\n  }/*}}}*/\n\n  function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/\n    if (dba_exists(\"nonce_$nonce\", $this->dbh)) {\n      return TRUE;\n    } else {\n      dba_insert(\"nonce_$nonce\", \"1\", $this->dbh);\n      return FALSE;\n    }\n  }/*}}}*/\n\n  function new_token($consumer, $type=\"request\") {/*{{{*/\n    $key = md5(time());\n    $secret = time() + time();\n    $token = new OAuthToken($key, md5(md5($secret)));\n    if (!dba_insert(\"${type}_$key\", serialize($token), $this->dbh)) {\n      throw new OAuthException(\"doooom!\");\n    }\n    return $token;\n  }/*}}}*/\n\n  function new_request_token($consumer) {/*{{{*/\n    return $this->new_token($consumer, \"request\");\n  }/*}}}*/\n\n  function new_access_token($token, $consumer) {/*{{{*/\n\n    $token = $this->new_token($consumer, 'access');\n    dba_delete(\"request_\" . $token->key, $this->dbh);\n    return $token;\n  }/*}}}*/\n}/*}}}*/\n\nclass OAuthUtil {/*{{{*/\n  public static function urlencode_rfc3986($input) {/*{{{*/\n  if (is_array($input)) {\n    return array_map(array('OAuthUtil','urlencode_rfc3986'), $input);\n  } else if (is_scalar($input)) {\n    return str_replace('+', ' ',\n                         str_replace('%7E', '~', rawurlencode($input)));\n  } else {\n    return '';\n  }\n  }/*}}}*/\n\n\n  // This decode function isn't taking into consideration the above\n  // modifications to the encoding process. However, this method doesn't\n  // seem to be used anywhere so leaving it as is.\n  public static function urldecode_rfc3986($string) {/*{{{*/\n    return rawurldecode($string);\n  }/*}}}*/\n}/*}}}*/"
  },
  {
    "path": "ConnectToTwitter/Plugin.php",
    "content": "<?php\n/**\n * 支持用twitter帐号在blog中留言并同步到twitter上\n * \n * @package Connect to Twittter\n * @author blankyao\n * @version 1.0.0 Beta\n * @link http://www.blankyao.cn\n * @todo 文章自动推送到twitter twitter帐号注册\n */\n\ninclude 'twitterOAuth.php';\n\nclass ConnectToTwitter_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate() {\n        Typecho_Plugin::factory('Widget_Feedback')->finishComment = array('ConnectToTwitter_Plugin', 'postToTwitter');\n        Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('ConnectToTwitter_Plugin', 'initComment');\n    }\n \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate() {\n    \n    }\n\n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $consumerKey = new Typecho_Widget_Helper_Form_Element_Text('consumerKey', NULL, '',\n        _t('Consumer Key'), _t('Your application consumer key from Twitter.com. '));\n        $form->addInput($consumerKey->addRule('required', _t('You must give the Consumer Key from Twitter.com')));\n        \n        $consumerSecret = new Typecho_Widget_Helper_Form_Element_Text('consumerSecret', NULL, '',\n        _t('Consumer Secret'), _t('Your application consumer secret from Twitter.com. '));\n        $form->addInput($consumerSecret->addRule('required', _t('You must give the Consumer Key from Twitter.com')));\n    }\n\n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n\n    public static function initComment($api)\n    {\n        session_start();\n        $options = Typecho_Widget::widget('Widget_Options');\n        $config = $options->plugin('ConnectToTwitter');\n\n        //发送请求到twitter\n        if(isset($api->request->connect_to_twitter))\n        {\n            $to = new TwitterOAuth($config->consumerKey, $config->consumerSecret);\n\n            $tok = $to->getRequestToken();\n            \n            Typecho_Cookie::set('oauth_request_token', $tok['oauth_token']);\n            Typecho_Cookie::set('oauth_request_token_secret', $tok['oauth_token_secret']);\n\n            /* Build the authorization URL */\n            $request_link = $to->getAuthorizeURL($tok['oauth_token']);\n            header('Location:'.$request_link);\n        }\n\n        //从twitter返回\n        if(isset($api->request->oauth_token)) {\n            if(Typecho_Cookie::get('oauth_request_token') && Typecho_Cookie::get('oauth_request_token_secret'))\n            {\n                $to = new TwitterOAuth($config->consumerKey, $config->consumerSecret, Typecho_Cookie::get('oauth_request_token'), Typecho_Cookie::get('oauth_request_token_secret'));\n\n                $tok = $to->getAccessToken();\n\n                Typecho_Cookie::set('oauth_access_token', $tok['oauth_token'], time()+60*60*24*30);\n                Typecho_Cookie::set('oauth_access_token_secret', $tok['oauth_token_secret'], time()+60*60*24*30);\n\n                $info_json = $to->OAuthRequest('https://twitter.com/account/verify_credentials.json', array(), 'GET');\n                $info = Typecho_Json::decode($info_json, true);\n\n                self::twitterLogin($info, $api);\n            }\n        }\n    }\n\n    //登录，暂时做为setcookie,以后要和用户帐号相关联\n    public static function twitterLogin($info, $api)\n    {\n        if (!empty($info['screen_name'])) {\n            Typecho_Cookie::set('__typecho_remember_author', $info['screen_name'], time()+60*60*24*30);\n        }\n        \n        if (!empty($info['url'])) {\n            Typecho_Cookie::set('__typecho_remember_url',  $info['url'], time()+60*60*24*30);\n        }\n    }\n\n    //发送信息到twitter\n    public static function postToTwitter($api)\n    {\n        if(Typecho_Cookie::get('oauth_access_token') && Typecho_Cookie::get('oauth_access_token_secret') && $api->request->post_to_twitter) {\n            $options = Typecho_Widget::widget('Widget_Options');\n            $config = $options->plugin('ConnectToTwitter');\n            $to = new TwitterOAuth($config->consumerKey, $config->consumerSecret, Typecho_Cookie::get('oauth_access_token'), Typecho_Cookie::get('oauth_access_token_secret'));\n\n            $url_array = array();\n            $url_array = explode('?', $api->request->getReferer());\n            $url = $url_array[0] . '#comment-' . $api->coid;\n            $post = $api->text . '  ( from ' . $url . '  ) ';\n            $twitter = $to->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $post), 'POST');\n        }\n        return $comment;\n    }\n\n    function showButton()\n    {\n        if(Typecho_Cookie::get('oauth_access_token') && Typecho_Cookie::get('oauth_access_token_secret')) {\n            echo '<p><input type=\"checkbox\" checked=\"\" value=\"yes\" id=\"post_to_twitter\" name=\"post_to_twitter\"/><label for=\"post_to_twitter\">同时把留言更新到你的 Twitter</label></p>';\n        } else {\n            echo '<p><a href=\"?connect_to_twitter=yes\"><img src=\"http://s3.amazonaws.com/static.whitleymedia/twitconnect.png\" /></a></p>';\n        }\n    }\n}\n"
  },
  {
    "path": "ConnectToTwitter/twitterOAuth.php",
    "content": "<?php\n/*\n * Abraham Williams (abraham@abrah.am) http://abrah.am\n *\n * Basic lib to work with Twitter's OAuth beta. This is untested and should not\n * be used in production code. Twitter's beta could change at anytime.\n *\n * Code based on:\n * Fire Eagle code - http://github.com/myelin/fireeagle-php-lib\n * twitterlibphp - http://github.com/poseurtech/twitterlibphp\n */\n\n/* Load OAuth lib. You can find it at http://oauth.net */\nrequire_once('OAuth.php');\n\n/**\n * Twitter OAuth class\n */\nclass TwitterOAuth {/*{{{*/\n  /* Contains the last HTTP status code returned */\n  private $http_status;\n\n  /* Contains the last API call */\n  private $last_api_call;\n\n  /* Set up the API root URL */\n  public static $TO_API_ROOT = \"https://twitter.com\";\n\n  /**\n   * Set API URLS\n   */\n  function requestTokenURL() { return self::$TO_API_ROOT.'/oauth/request_token'; }\n  function authorizeURL() { return self::$TO_API_ROOT.'/oauth/authorize'; }\n  function accessTokenURL() { return self::$TO_API_ROOT.'/oauth/access_token'; }\n\n  /**\n   * Debug helpers\n   */\n  function lastStatusCode() { return $this->http_status; }\n  function lastAPICall() { return $this->last_api_call; }\n\n  /**\n   * construct TwitterOAuth object\n   */\n  function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {/*{{{*/\n    $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();\n    $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);\n    if (!empty($oauth_token) && !empty($oauth_token_secret)) {\n      $this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);\n    } else {\n      $this->token = NULL;\n    }\n  }/*}}}*/\n\n\n  /**\n   * Get a request_token from Twitter\n   *\n   * @returns a key/value array containing oauth_token and oauth_token_secret\n   */\n  function getRequestToken() {/*{{{*/\n    $r = $this->oAuthRequest($this->requestTokenURL());\n    $token = $this->oAuthParseResponse($r);\n    $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);\n    return $token;\n  }/*}}}*/\n\n  /**\n   * Parse a URL-encoded OAuth response\n   *\n   * @return a key/value array\n   */\n  function oAuthParseResponse($responseString) {\n    $r = array();\n    foreach (explode('&', $responseString) as $param) {\n      $pair = explode('=', $param, 2);\n      if (count($pair) != 2) continue;\n      $r[urldecode($pair[0])] = urldecode($pair[1]);\n    }\n    return $r;\n  }\n\n  /**\n   * Get the authorize URL\n   *\n   * @returns a string\n   */\n  function getAuthorizeURL($token) {/*{{{*/\n    if (is_array($token)) $token = $token['oauth_token'];\n    return $this->authorizeURL() . '?oauth_token=' . $token;\n  }/*}}}*/\n\n  /**\n   * Exchange the request token and secret for an access token and\n   * secret, to sign API calls.\n   *\n   * @returns array(\"oauth_token\" => the access token,\n   *                \"oauth_token_secret\" => the access secret)\n   */\n  function getAccessToken($token = NULL) {/*{{{*/\n    $r = $this->oAuthRequest($this->accessTokenURL());\n    $token = $this->oAuthParseResponse($r);\n    $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);\n    return $token;\n  }/*}}}*/\n\n  /**\n   * Format and sign an OAuth / API request\n   */\n  function oAuthRequest($url, $args = array(), $method = NULL) {/*{{{*/\n    if (empty($method)) $method = empty($args) ? \"GET\" : \"POST\";\n    $req = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $args);\n    $req->sign_request($this->sha1_method, $this->consumer, $this->token);\n    switch ($method) {\n    case 'GET': return $this->http($req->to_url());\n    case 'POST': return $this->http($req->get_normalized_http_url(), $req->to_postdata());\n    }\n  }/*}}}*/\n\n  /**\n   * Make an HTTP request\n   *\n   * @return API results\n   */\n  function http($url, $post_data = null) {/*{{{*/\n    $ch = curl_init();\n    if (defined(\"CURL_CA_BUNDLE_PATH\")) curl_setopt($ch, CURLOPT_CAINFO, CURL_CA_BUNDLE_PATH);\n    curl_setopt($ch, CURLOPT_URL, $url);\n    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);\n    curl_setopt($ch, CURLOPT_TIMEOUT, 30);\n    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\n    //////////////////////////////////////////////////\n    ///// Set to 1 to verify Twitter's SSL Cert //////\n    //////////////////////////////////////////////////\n    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);\n    if (isset($post_data)) {\n      curl_setopt($ch, CURLOPT_POST, 1);\n      curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);\n    }\n    $response = curl_exec($ch);\n    $this->http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);\n    $this->last_api_call = $url;\n    curl_close ($ch);\n    return $response;\n  }/*}}}*/\n}/*}}}*/"
  },
  {
    "path": "Creole/Creole_Wiki.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Parse structured wiki text and render into arbitrary formats such as XHTML.\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Creole_Wiki.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * The baseline abstract parser class.\n */\nrequire_once 'Parse.inc.php';\n\n/**\n * The baseline abstract render class.\n */\nrequire_once 'Render.inc.php';\n\n/**\n * Parse structured wiki text and render into arbitrary formats such as XHTML.\n *\n * This is the \"master\" class for handling the management and convenience\n * functions to transform Wiki-formatted text.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: 1.2.0\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Creole_Wiki {\n    // *single newlines* are handled as in most wikis (ignored)\n    // if Newline is removed from rules, they will be handled as in word-processors (meaning a paragraph break)\n    protected $rules = array(\n        'Prefilter',\n        'Delimiter',\n        'Preformatted',\n        'Tt',\n        //'Trim',\n        'Break',\n        'Raw',\n\t\t'Box',\n        //'Footnote',\n        'Table',\n        'Newline',\n        'Blockquote',\n        'Newline',\n        //'Wikilink',\n        'Heading',\n        'Center',\n        'Horiz',\n        'List',\n        'Address',\n        'Paragraph',\n        'Superscript',\n        'Subscript',\n        'Underline',\n        'Strong',\n        'Tighten',\n        'Image',\n        'Url',\n        'Emphasis'\n    );\n\n\n    /**\n     *\n     * The list of rules to not-apply to the source text.\n     *\n     * @access public\n     *\n     * @var array\n     *\n     */\n    public $disable = array(\n        'Html',\n        'Include',\n        'Embed'\n    );\n\n\n    /**\n     *\n     * Custom configuration for rules at the parsing stage.\n     *\n     * In this array, the key is the parsing rule name, and the value is\n     * an array of key-value configuration pairs corresponding to the $conf\n     * property in the target parsing rule.\n     *\n     * For example:\n     *\n     * <code>\n     * $parseConf = array(\n     *     'Include' => array(\n     *         'base' => '/path/to/scripts/'\n     *     )\n     * );\n     * </code>\n     *\n     * Note that most default rules do not need any parsing configuration.\n     *\n     * @access public\n     *\n     * @var array\n     *\n     */\n    public $parseConf = array();\n\n\n    /**\n     *\n     * Custom configuration for rules at the rendering stage.\n     *\n     * Because rendering may be different for each target format, the\n     * first-level element in this array is always a format name (e.g.,\n     * 'Xhtml').\n     *\n     * Within that first level element, the subsequent elements match the\n     * $parseConf format. That is, the sub-key is the rendering rule name,\n     * and the sub-value is an array of key-value configuration pairs\n     * corresponding to the $conf property in the target rendering rule.\n     *\n     * @access public\n     *\n     * @var array\n     *\n     */\n    public $renderConf = array(\n        'Docbook' => array(),\n        'Latex' => array(),\n        'Pdf' => array(),\n        'Plain' => array(),\n        'Rtf' => array(),\n        'Xhtml' => array()\n    );\n\n\n    /**\n     *\n     * Custom configuration for the output format itself.\n     *\n     * Even though Text_Wiki will render the tokens from parsed text,\n     * the format itself may require some configuration.  For example,\n     * RTF needs to know font names and sizes, PDF requires page layout\n     * information, and DocBook needs a section hierarchy.  This array\n     * matches the $conf property of the the format-level renderer\n     * (e.g., Text_Wiki_Render_Xhtml).\n     *\n     * In this array, the key is the rendering format name, and the value is\n     * an array of key-value configuration pairs corresponding to the $conf\n     * property in the rendering format rule.\n     *\n     * @access public\n     *\n     * @var array\n     *\n     */\n    public $formatConf = array(\n        'Docbook' => array(),\n        'Latex' => array(),\n        'Pdf' => array(),\n        'Plain' => array(),\n        'Rtf' => array(),\n        'Xhtml' => array()\n    );\n\n\n    /**\n     *\n     * The delimiter for token numbers of parsed elements in source text.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     */\n    public $delim = \"\\xFF\";\n\n\n    /**\n     *\n     * The tokens generated by rules as the source text is parsed.\n     *\n     * As Text_Wiki applies rule classes to the source text, it will\n     * replace portions of the text with a delimited token number.  This\n     * is the array of those tokens, representing the replaced text and\n     * any options set by the parser for that replaced text.\n     *\n     * The tokens array is sequential; each element is itself a sequential\n     * array where element 0 is the name of the rule that generated the\n     * token, and element 1 is an associative array where the key is an\n     * option name and the value is an option value.\n     *\n     * @access private\n     *\n     * @var array\n     *\n     */\n    public $tokens = array();\n\n    /**\n     * How many tokens generated pro rules.\n     *\n     * Intended to load only necessary render objects\n     *\n     * @access private\n     * @var array\n     */\n    private $_countRulesTokens = array();\n\n\n    /**\n     *\n     * The source text to which rules will be applied.\n     *\n     * This text will be transformed in-place, which means that it will\n     * change as the rules are applied.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     */\n    public $source = '';\n\n    /**\n     * The output text\n     *\n     * @var string\n     */\n    protected $output = '';\n\n\n    /**\n     *\n     * Array of rule parsers.\n     *\n     * Text_Wiki creates one instance of every rule that is applied to\n     * the source text; this array holds those instances.  The array key\n     * is the rule name, and the array value is an instance of the rule\n     * class.\n     *\n     * @access private\n     *\n     * @var array\n     *\n     */\n\n    protected $parseObj = array();\n\n\n    /**\n     *\n     * Array of rule renderers.\n     *\n     * Text_Wiki creates one instance of every rule that is applied to\n     * the source text; this array holds those instances.  The array key\n     * is the rule name, and the array value is an instance of the rule\n     * class.\n     *\n     * @access private\n     *\n     * @var array\n     *\n     */\n    protected $renderObj = array();\n\n\n    /**\n     *\n     * Array of format renderers.\n     *\n     * @access private\n     *\n     * @var array\n     *\n     */\n    protected $formatObj = array();\n\n\n    /**\n     *\n     * Array of paths to search, in order, for parsing and rendering rules.\n     *\n     * @access private\n     *\n     * @var array\n     *\n     */\n    protected $path = array(\n        'parse' => array(),\n        'render' => array()\n    );\n\n\n\n    /**\n     *\n     * The directory separator character.\n     *\n     * @access private\n     *\n     * @var string\n     *\n     */\n    private $_dirSep = DIRECTORY_SEPARATOR;\n\n    /**\n     * Temporary configuration variable\n     *\n     * @var string\n     */\n    protected $renderingType = 'preg';\n\n    /**\n     * Stack of rendering callbacks\n     *\n     * @var Array\n     */\n    private $_renderCallbacks = array();\n\n    /**\n     * Current output block\n     *\n     * @var string\n     */\n    private $_block;\n\n    /**\n     * A stack of blocks\n     *\n     * @param Array\n     */\n    private $_blocks;\n\n    /**\n     *\n     * Constructor.\n     *\n     * **DEPRECATED**\n     * Please use the singleton() or factory() methods.\n     *\n     * @access public\n     *\n     * @param array $rules The set of rules to load for this object.  Defaults\n     *   to null, which will load the default ruleset for this parser.\n     */\n\n    function __construct($rules = null)\n    {\n        if (is_array($rules)) {\n            $this->rules = array();\n            foreach ($rules as $rule) {\n                $this->rules[] = ucfirst($rule);\n            }\n        }\n\n        /*\n        $this->addPath(\n            'parse',\n            $this->fixPath(dirname(__FILE__)) . 'Wiki/Parse/Default/'\n        );\n         */\n\n        $this->addPath(\n            'parse', $this->fixPath(dirname(__FILE__) . '/Parse/')\n        );\n\n        $this->addPath(\n            'render',\n            $this->fixPath(dirname(__FILE__) . '/Render/' )\n        );\n\n        $this->renderingType = 'char';\n        $this->setRenderConf('xhtml', 'center', 'css', 'center');\n        $this->setRenderConf('xhtml', 'url', 'target', null);\n    }\n\n\n    /**\n     * Singleton.\n     *\n     * This avoids instantiating multiple Text_Wiki instances where a number\n     * of objects are required in one call, e.g. to save memory in a\n     * CMS invironment where several parsers are required in a single page.\n     *\n     * $single = & singleton();\n     *\n     * or\n     *\n     * $single = & singleton('Parser', array('Prefilter', 'Delimiter', 'Code', 'Function',\n     *   'Html', 'Raw', 'Include', 'Embed', 'Anchor', 'Heading', 'Toc', 'Horiz',\n     *   'Break', 'Blockquote', 'List', 'Deflist', 'Table', 'Image', 'Phplookup',\n     *   'Center', 'Newline', 'Paragraph', 'Url', 'Freelink', 'Interwiki', 'Wikilink',\n     *   'Colortext', 'Strong', 'Bold', 'Emphasis', 'Italic', 'Underline', 'Tt',\n     *   'Superscript', 'Subscript', 'Revise', 'Tighten'));\n     *\n     * Call using a subset of this list.  The order of passing rulesets in the\n     * $rules array is important!\n     *\n     * After calling this, call $single->setParseConf(), setRenderConf() or setFormatConf()\n     * as usual for a constructed object of this class.\n     *\n     * The internal static array of singleton objects has no index on the parser\n     * rules, the only index is on the parser name.  So if you call this multiple\n     * times with different rules but the same parser name, you will get the same\n     * static parser object each time.\n     *\n     * @access public\n     * @static\n     * @since Method available since Release 1.1.0\n     * @param string $parser The parser to be used (defaults to 'Default').\n     * @param array $rules   The set of rules to instantiate the object. This\n     *    will only be used when the first call to singleton is made, if included\n     *    in further calls it will be effectively ignored.\n     * @return &object a reference to the Text_Wiki unique instantiation.\n     */\n    /*\n    public function &singleton($parser = 'Default', $rules = null)\n    {\n        static $only = array();\n        if (!isset($only[$parser])) {\n            $ret = & Text_Wiki::factory($parser, $rules);\n            if (Text_Wiki::isError($ret)) {\n                return $ret;\n            }\n            $only[$parser] =& $ret;\n        }\n        return $only[$parser];\n    }\n     */\n\n    /**\n     * Returns a Text_Wiki Parser class for the specified parser.\n     *\n     * @access public\n     * @static\n     * @param string $parser The name of the parse to instantiate\n     * you need to have Text_Wiki_XXX installed to use $parser = 'XXX', it's E_FATAL\n     * @param array $rules The rules to pass into the constructor\n     *    {@see Text_Wiki::singleton} for a list of rules\n     * @return Text_Wiki a Parser object extended from Text_Wiki\n     */\n    /*\n    public function &factory($parser = 'Default', $rules = null)\n    {\n        $class = 'Text_Wiki_' . ucfirst(strtolower($parser));\n        $file = str_replace('_', '/', $class).'.php';\n        if (!class_exists($class)) {\n            require_once $file;\n            if (!class_exists($class)) {\n                return Text_Wiki::error(\n                    'Class ' . $class . ' does not exist after requiring '. $file .\n                        ', install package ' . $class . \"\\n\");\n            }\n        }\n\n        $obj =& new $class($rules);\n        return $obj;\n    }\n     */\n\n    /**\n     *\n     * Set parser configuration for a specific rule and key.\n     *\n     * @access public\n     *\n     * @param string $rule The parse rule to set config for.\n     *\n     * @param array|string $arg1 The full config array to use for the\n     * parse rule, or a conf key in that array.\n     *\n     * @param string $arg2 The config value for the key.\n     *\n     * @return void\n     *\n     */\n    public function setParseConf($rule, $arg1, $arg2 = null)\n    {\n        $rule = ucwords(strtolower($rule));\n\n        if (! isset($this->parseConf[$rule])) {\n            $this->parseConf[$rule] = array();\n        }\n\n        // if first arg is an array, use it as the entire\n        // conf array for the rule.  otherwise, treat arg1\n        // as a key and arg2 as a value for the rule conf.\n        if (is_array($arg1)) {\n            $this->parseConf[$rule] = $arg1;\n        } else {\n            $this->parseConf[$rule][$arg1] = $arg2;\n        }\n    }\n\n\n    /**\n     *\n     * Get parser configuration for a specific rule and key.\n     *\n     * @access public\n     *\n     * @param string $rule The parse rule to get config for.\n     *\n     * @param string $key A key in the conf array; if null,\n     * returns the entire conf array.\n     *\n     * @return mixed The whole conf array if no key is specified,\n     * or the specific conf key value.\n     *\n     */\n    public function getParseConf($rule, $key = null)\n    {\n        $rule = ucwords(strtolower($rule));\n\n        // the rule does not exist\n        if (! isset($this->parseConf[$rule])) {\n            return null;\n        }\n\n        // no key requested, return the whole array\n        if (is_null($key)) {\n            return $this->parseConf[$rule];\n        }\n\n        // does the requested key exist?\n        if (isset($this->parseConf[$rule][$key])) {\n            // yes, return that value\n            return $this->parseConf[$rule][$key];\n        } else {\n            // no\n            return null;\n        }\n    }\n\n\n    /**\n     *\n     * Set renderer configuration for a specific format, rule, and key.\n     *\n     * @access public\n     *\n     * @param string $format The render format to set config for.\n     *\n     * @param string $rule The render rule to set config for in the format.\n     *\n     * @param array|string $arg1 The config array, or the config key\n     * within the render rule.\n     *\n     * @param string $arg2 The config value for the key.\n     *\n     * @return void\n     *\n     */\n\n    function setRenderConf($format, $rule, $arg1, $arg2 = null)\n    {\n        $format = ucwords(strtolower($format));\n        $rule = ucwords(strtolower($rule));\n\n        if (! isset($this->renderConf[$format])) {\n            $this->renderConf[$format] = array();\n        }\n\n        if (! isset($this->renderConf[$format][$rule])) {\n            $this->renderConf[$format][$rule] = array();\n        }\n\n        // if first arg is an array, use it as the entire\n        // conf array for the render rule.  otherwise, treat arg1\n        // as a key and arg2 as a value for the render rule conf.\n        if (is_array($arg1)) {\n            $this->renderConf[$format][$rule] = $arg1;\n        } else {\n            $this->renderConf[$format][$rule][$arg1] = $arg2;\n        }\n    }\n\n\n    /**\n     *\n     * Get renderer configuration for a specific format, rule, and key.\n     *\n     * @access public\n     *\n     * @param string $format The render format to get config for.\n     *\n     * @param string $rule The render format rule to get config for.\n     *\n     * @param string $key A key in the conf array; if null,\n     * returns the entire conf array.\n     *\n     * @return mixed The whole conf array if no key is specified,\n     * or the specific conf key value.\n     *\n     */\n\n    function getRenderConf($format, $rule, $key = null)\n    {\n        $format = ucwords(strtolower($format));\n        $rule = ucwords(strtolower($rule));\n\n        if (! isset($this->renderConf[$format]) ||\n            ! isset($this->renderConf[$format][$rule])) {\n                return null;\n            }\n\n        // no key requested, return the whole array\n        if (is_null($key)) {\n            return $this->renderConf[$format][$rule];\n        }\n\n        // does the requested key exist?\n        if (isset($this->renderConf[$format][$rule][$key])) {\n            // yes, return that value\n            return $this->renderConf[$format][$rule][$key];\n        } else {\n            // no\n            return null;\n        }\n\n    }\n\n    /**\n     *\n     * Set format configuration for a specific rule and key.\n     *\n     * @access public\n     *\n     * @param string $format The format to set config for.\n     *\n     * @param string $key The config key within the format.\n     *\n     * @param string $val The config value for the key.\n     *\n     * @return void\n     *\n     */\n\n    function setFormatConf($format, $arg1, $arg2 = null)\n    {\n        if (! is_array($this->formatConf[$format])) {\n            $this->formatConf[$format] = array();\n        }\n\n        // if first arg is an array, use it as the entire\n        // conf array for the format.  otherwise, treat arg1\n        // as a key and arg2 as a value for the format conf.\n        if (is_array($arg1)) {\n            $this->formatConf[$format] = $arg1;\n        } else {\n            $this->formatConf[$format][$arg1] = $arg2;\n        }\n    }\n\n\n\n    /**\n     *\n     * Get configuration for a specific format and key.\n     *\n     * @access public\n     *\n     * @param string $format The format to get config for.\n     *\n     * @param mixed $key A key in the conf array; if null,\n     * returns the entire conf array.\n     *\n     * @return mixed The whole conf array if no key is specified,\n     * or the specific conf key value.\n     *\n     */\n\n    function getFormatConf($format, $key = null)\n    {\n        // the format does not exist\n        if (! isset($this->formatConf[$format])) {\n            return null;\n        }\n\n        // no key requested, return the whole array\n        if (is_null($key)) {\n            return $this->formatConf[$format];\n        }\n\n        // does the requested key exist?\n        if (isset($this->formatConf[$format][$key])) {\n            // yes, return that value\n            return $this->formatConf[$format][$key];\n        } else {\n            // no\n            return null;\n        }\n    }\n\n\n    /**\n     *\n     * Inserts a rule into to the rule set.\n     *\n     * @access public\n     *\n     * @param string $name The name of the rule.  Should be different from\n     * all other keys in the rule set.\n     *\n     * @param string $tgt The rule after which to insert this new rule.  By\n     * default (null) the rule is inserted at the end; if set to '', inserts\n     * at the beginning.\n     *\n     * @return void\n     *\n     */\n\n    function insertRule($name, $tgt = null)\n    {\n        $name = ucwords(strtolower($name));\n        if (! is_null($tgt)) {\n            $tgt = ucwords(strtolower($tgt));\n        }\n\n        // does the rule name to be inserted already exist?\n        if (in_array($name, $this->rules)) {\n            // yes, return\n            return null;\n        }\n\n        // the target name is not null, and not '', but does not exist\n        // in the list of rules. this means we're trying to insert after\n        // a target key, but the target key isn't there.\n        if (! is_null($tgt) && $tgt != '' &&\n            ! in_array($tgt, $this->rules)) {\n                return false;\n            }\n\n        // if $tgt is null, insert at the end.  We know this is at the\n        // end (instead of resetting an existing rule) becuase we exited\n        // at the top of this method if the rule was already in place.\n        if (is_null($tgt)) {\n            $this->rules[] = $name;\n            return true;\n        }\n\n        // save a copy of the current rules, then reset the rule set\n        // so we can insert in the proper place later.\n        // where to insert the rule?\n        if ($tgt == '') {\n            // insert at the beginning\n            array_unshift($this->rules, $name);\n            return true;\n        }\n\n        // insert after the named rule\n        $tmp = $this->rules;\n        $this->rules = array();\n\n        foreach ($tmp as $val) {\n            $this->rules[] = $val;\n            if ($val == $tgt) {\n                $this->rules[] = $name;\n            }\n        }\n\n        return true;\n\n    }\n\n\n    /**\n     *\n     * Delete (remove or unset) a rule from the $rules property.\n     *\n     * @access public\n     *\n     * @param string $rule The name of the rule to remove.\n     *\n     * @return void\n     *\n     */\n\n    function deleteRule($name)\n    {\n        $name = ucwords(strtolower($name));\n        $key = array_search($name, $this->rules);\n        if ($key !== false) {\n            unset($this->rules[$key]);\n        }\n    }\n\n\n    /**\n     *\n     * Change from one rule to another in-place.\n     *\n     * @access public\n     *\n     * @param string $old The name of the rule to change from.\n     *\n     * @param string $new The name of the rule to change to.\n     *\n     * @return void\n     *\n     */\n\n    function changeRule($old, $new)\n    {\n        $old = ucwords(strtolower($old));\n        $new = ucwords(strtolower($new));\n        $key = array_search($old, $this->rules);\n        if ($key !== false) {\n            // delete the new name , case it was already there\n            $this->deleteRule($new);\n            $this->rules[$key] = $new;\n        }\n    }\n\n\n    /**\n     *\n     * Enables a rule so that it is applied when parsing.\n     *\n     * @access public\n     *\n     * @param string $rule The name of the rule to enable.\n     *\n     * @return void\n     *\n     */\n\n    function enableRule($name)\n    {\n        $name = ucwords(strtolower($name));\n        $key = array_search($name, $this->disable);\n        if ($key !== false) {\n            unset($this->disable[$key]);\n        }\n    }\n\n\n    /**\n     *\n     * Disables a rule so that it is not applied when parsing.\n     *\n     * @access public\n     *\n     * @param string $rule The name of the rule to disable.\n     *\n     * @return void\n     *\n     */\n\n    function disableRule($name)\n    {\n        $name = ucwords(strtolower($name));\n        $key = array_search($name, $this->disable);\n        if ($key === false) {\n            $this->disable[] = $name;\n        }\n    }\n\n\n    /**\n     *\n     * Parses and renders the text passed to it, and returns the results.\n     *\n     * First, the method parses the source text, applying rules to the\n     * text as it goes.  These rules will modify the source text\n     * in-place, replacing some text with delimited tokens (and\n     * populating the $this->tokens array as it goes).\n     *\n     * Next, the method renders the in-place tokens into the requested\n     * output format.\n     *\n     * Finally, the method returns the transformed text.  Note that the\n     * source text is transformed in place; once it is transformed, it is\n     * no longer the same as the original source text.\n     *\n     * @access public\n     *\n     * @param string $text The source text to which wiki rules should be\n     * applied, both for parsing and for rendering.\n     *\n     * @param string $format The target output format, typically 'xhtml'.\n     *  If a rule does not support a given format, the output from that\n     * rule is rule-specific.\n     *\n     * @return string The transformed wiki text.\n     *\n     */\n    function transform($text, $format = 'Xhtml')\n    {\n        $this->parse($text);\n        return $this->render($format);\n    }\n\n\n    /**\n     *\n     * Sets the $_source text property, then parses it in place and\n     * retains tokens in the $_tokens array property.\n     *\n     * @access public\n     *\n     * @param string $text The source text to which wiki rules should be\n     * applied, both for parsing and for rendering.\n     *\n     * @return void\n     *\n     */\n\n    function parse($text)\n    {\n        // set the object property for the source text\n        $this->source = $text;\n\n        // reset the tokens.\n        $this->tokens = array();\n        $this->_countRulesTokens = array();\n\n        // apply the parse() method of each requested rule to the source\n        // text.\n        foreach ($this->rules as $name) {\n            // do not parse the rules listed in $disable\n            if (! in_array($name, $this->disable)) {\n\n                // load the parsing object\n                $this->loadParseObj($name);\n\n                // load may have failed; only parse if\n                // an object is in the array now\n                if (is_object($this->parseObj[$name])) {\n                    $this->parseObj[$name]->parse();\n                }\n            }\n        }\n    }\n\n\n    /**\n     *\n     * Renders tokens back into the source text, based on the requested format.\n     *\n     * @access public\n     *\n     * @param string $format The target output format, typically 'xhtml'.\n     * If a rule does not support a given format, the output from that\n     * rule is rule-specific.\n     *\n     * @return string The transformed wiki text.\n     *\n     */\n\n    function render($format = 'Xhtml')\n    {\n        // the rendering method we're going to use from each rule\n        $format = ucwords(strtolower($format));\n\n        // the eventual output text\n        $this->output = '';\n\n        // when passing through the parsed source text, keep track of when\n        // we are in a delimited section\n        $in_delim = false;\n\n        // when in a delimited section, capture the token key number\n        $key = '';\n\n        // load the format object, or crap out if we can't find it\n        $result = $this->loadFormatObj($format);\n        if ($this->isError($result)) {\n            return $result;\n        }\n\n        /*\n         * hunked by feelinglucky..\n         // pre-rendering activity\n         if (is_object($this->formatObj[$format])) {\n             $this->output .= $this->formatObj[$format]->pre();\n    }\n         */\n        // load the render objects\n        foreach (array_keys($this->_countRulesTokens) as $rule) {\n            $this->loadRenderObj($format, $rule);\n        }\n\n\n        if ($this->renderingType == 'preg') {\n            $this->output = preg_replace_callback('/'.$this->delim.'(\\d+)'.$this->delim.'/',\n                array(&$this, '_renderToken'),\n                $this->source);\n\n            /*\n            //Damn strtok()! Why does it \"skip\" empty parts of the string. It's useless now!\n        } elseif ($this->renderingType == 'strtok') {\n            echo '<pre>'.htmlentities($this->source).'</pre>';\n            $t = strtok($this->source, $this->delim);\n            $inToken = true;\n            $i = 0;\n            while ($t !== false) {\n                echo 'Token: '.$i.'<pre>\"'.htmlentities($t).'\"</pre><br/><br/>';\n                if ($inToken) {\n                    //$this->output .= $this->renderObj[$this->tokens[$t][0]]->token($this->tokens[$t][1]);\n                } else {\n                    $this->output .= $t;\n                }\n                $inToken = !$inToken;\n                $t = strtok($this->delim);\n                ++$i;\n            }\n             */\n        } else {\n            // pass through the parsed source text character by character\n            $this->_block = '';\n            $tokenStack = array();\n            $k = strlen($this->source);\n\n            for ($i = 0; $i < $k; $i++) {\n\n                // the current character\n                $char = $this->source{$i};\n\n                // are alredy in a delimited section?\n                if ($in_delim) {\n\n                    // yes; are we ending the section?\n                    if ($char == $this->delim) {\n\n                        if (count($this->_renderCallbacks) == 0) {\n                            $this->output .= $this->_block;\n                            $this->_block = '';\n                        }\n\n                        if (isset($opts['type'])) {\n                            if ($opts['type'] == 'start') {\n                                array_push($tokenStack, $rule);\n                            } elseif ($opts['type'] == 'end') {\n                                if ($tokenStack[count($tokenStack) - 1] != $rule) {\n                                    return Text_Wiki::error('Unbalanced tokens, check your syntax');\n                                } else {\n                                    array_pop($tokenStack);\n                                }\n                            }\n                        }\n\n                        // yes, get the replacement text for the delimited\n                        // token number and unset the flag.\n                        $key = (int)$key;\n                        $rule = $this->tokens[$key][0];\n                        $opts = $this->tokens[$key][1];\n                        $this->_block .= $this->renderObj[$rule]->token($opts);\n                        $in_delim = false;\n\n                    } else {\n\n                        // no, add to the delimited token key number\n                        $key .= $char;\n\n                    }\n\n                } else {\n\n                    // not currently in a delimited section.\n                    // are we starting into a delimited section?\n                    if ($char == $this->delim) {\n                        // yes, reset the previous key and\n                        // set the flag.\n                        $key = '';\n                        $in_delim = true;\n\n                    } else {\n                        // no, add to the output as-is\n                        $this->_block .= $char;\n                    }\n                }\n            }\n        }\n\n        if (count($this->_renderCallbacks)) {\n            return $this->error('Render callbacks left over after processing finished');\n        }\n        /*\n        while (count($this->_renderCallbacks)) {\n            $this->popRenderCallback();\n        }\n         */\n        if (strlen($this->_block)) {\n            $this->output .= $this->_block;\n            $this->_block = '';\n        }\n\n/* tunk by feelinglucky\n        // post-rendering activity\n        if (is_object($this->formatObj[$format])) {\n            $this->output .= $this->formatObj[$format]->post();\n        }\n */\n\n        // return the rendered source text.\n        return $this->output;\n    }\n\n    /**\n     * Renders a token, for use only as an internal callback\n     *\n     * @param array Matches from preg_rpelace_callback, [1] is the token number\n     * @return string The rendered text for the token\n     * @access private\n     */\n    function _renderToken($matches) {\n        return $this->renderObj[$this->tokens[$matches[1]][0]]->token($this->tokens[$matches[1]][1]);\n    }\n\n    function registerRenderCallback($callback) {\n        $this->_blocks[] = $this->_block;\n        $this->_block = '';\n        $this->_renderCallbacks[] = $callback;\n    }\n\n    function popRenderCallback() {\n        if (count($this->_renderCallbacks) == 0) {\n            return Text_Wiki::error('Render callback popped when no render callbacks in stack');\n        } else {\n            $callback = array_pop($this->_renderCallbacks);\n            $this->_block = call_user_func($callback, $this->_block);\n            if (count($this->_blocks)) {\n                $parentBlock = array_pop($this->_blocks);\n                $this->_block = $parentBlock.$this->_block;\n            }\n            if (count($this->_renderCallbacks) == 0) {\n                $this->output .= $this->_block;\n                $this->_block = '';\n            }\n        }\n    }\n\n    /**\n     *\n     * Returns the parsed source text with delimited token placeholders.\n     *\n     * @access public\n     *\n     * @return string The parsed source text.\n     *\n     */\n\n    function getSource()\n    {\n        return $this->source;\n    }\n\n\n    /**\n     *\n     * Returns tokens that have been parsed out of the source text.\n     *\n     * @access public\n     *\n     * @param array $rules If an array of rule names is passed, only return\n     * tokens matching these rule names.  If no array is passed, return all\n     * tokens.\n     *\n     * @return array An array of tokens.\n     *\n     */\n\n    function getTokens($rules = null)\n    {\n        if (is_null($rules)) {\n            return $this->tokens;\n        } else {\n            settype($rules, 'array');\n            $result = array();\n            foreach ($this->tokens as $key => $val) {\n                if (in_array($val[0], $rules)) {\n                    $result[$key] = $val;\n                }\n            }\n            return $result;\n        }\n    }\n\n\n    /**\n     *\n     * Add a token to the Text_Wiki tokens array, and return a delimited\n     * token number.\n     *\n     * @access public\n     *\n     * @param array $options An associative array of options for the new\n     * token array element.  The keys and values are specific to the\n     * rule, and may or may not be common to other rule options.  Typical\n     * options keys are 'text' and 'type' but may include others.\n     *\n     * @param boolean $id_only If true, return only the token number, not\n     * a delimited token string.\n     *\n     * @return string|int By default, return the number of the\n     * newly-created token array element with a delimiter prefix and\n     * suffix; however, if $id_only is set to true, return only the token\n     * number (no delimiters).\n     *\n     */\n\n    function addToken($rule, $options = array(), $id_only = false)\n    {\n        // increment the token ID number.  note that if you parse\n        // multiple times with the same Text_Wiki object, the ID number\n        // will not reset to zero.\n        static $id;\n        if (! isset($id)) {\n            $id = 0;\n        } else {\n            $id ++;\n        }\n\n        // force the options to be an array\n        settype($options, 'array');\n\n        // add the token\n        $this->tokens[$id] = array(\n            0 => $rule,\n            1 => $options\n        );\n        if (!isset($this->_countRulesTokens[$rule])) {\n            $this->_countRulesTokens[$rule] = 1;\n        } else {\n            ++$this->_countRulesTokens[$rule];\n        }\n\n        // return a value\n        if ($id_only) {\n            // return the last token number\n            return $id;\n        } else {\n            // return the token number with delimiters\n            return $this->delim . $id . $this->delim;\n        }\n    }\n\n\n    /**\n     *\n     * Set or re-set a token with specific information, overwriting any\n     * previous rule name and rule options.\n     *\n     * @access public\n     *\n     * @param int $id The token number to reset.\n     *\n     * @param int $rule The rule name to use.\n     *\n     * @param array $options An associative array of options for the\n     * token array element.  The keys and values are specific to the\n     * rule, and may or may not be common to other rule options.  Typical\n     * options keys are 'text' and 'type' but may include others.\n     *\n     * @return void\n     *\n     */\n\n    function setToken($id, $rule, $options = array())\n    {\n        $oldRule = $this->tokens[$id][0];\n        // reset the token\n        $this->tokens[$id] = array(\n            0 => $rule,\n            1 => $options\n        );\n        if ($rule != $oldRule) {\n            if (!($this->_countRulesTokens[$oldRule]--)) {\n                unset($this->_countRulesTokens[$oldRule]);\n            }\n            if (!isset($this->_countRulesTokens[$rule])) {\n                $this->_countRulesTokens[$rule] = 1;\n            } else {\n                ++$this->_countRulesTokens[$rule];\n            }\n        }\n    }\n\n\n    /**\n     *\n     * Load a rule parser class file.\n     *\n     * @access public\n     *\n     * @return bool True if loaded, false if not.\n     *\n     */\n\n    function loadParseObj($rule)\n    {\n        $rule = ucwords(strtolower($rule));\n        $file = $rule . '.php';\n        $class = \"Text_Wiki_Parse_$rule\";\n\n        if (!Typecho_Common::isAvailableClass($class)) {\n            $loc = $this->findFile('parse', $file);\n\n            if ($loc) {\n                // found the class\n                include_once $loc;\n            } else {\n                // can't find the class\n                $this->parseObj[$rule] = null;\n                // can't find the class\n                return $this->error(\n                    \"Parse rule '$rule' not found\"\n                );\n            }\n        }\n\n        $this->parseObj[$rule] = new $class($this);\n    }\n\n\n    /**\n     *\n     * Load a rule-render class file.\n     *\n     * @access public\n     *\n     * @return bool True if loaded, false if not.\n     *\n     */\n\n    function loadRenderObj($format, $rule)\n    {\n        $format = ucwords(strtolower($format));\n        $rule = ucwords(strtolower($rule));\n        $file = \"$format/$rule.php\";\n        $class = \"Text_Wiki_Render_$format\" . \"_$rule\";\n\n        if (! Typecho_Common::isAvailableClass($class)) {\n            // load the class\n            $loc = $this->findFile('render', $file);\n            if ($loc) {\n                // found the class\n                include_once $loc;\n            } else {\n                // can't find the class\n                return $this->error(\n                    \"Render rule '$rule' in format '$format' not found\"\n                );\n            }\n        }\n\n        $this->renderObj[$rule] = new $class($this);\n    }\n\n\n    /**\n     *\n     * Load a format-render class file.\n     *\n     * @access public\n     *\n     * @return bool True if loaded, false if not.\n     *\n     */\n\n    function loadFormatObj($format)\n    {\n        $format = ucwords(strtolower($format));\n        $file = $format . '.php';\n        $class = \"Text_Wiki_Render_$format\";\n\n        if (! Typecho_Common::isAvailableClass($class)) {\n            $loc = $this->findFile('render', $file);\n            if ($loc) {\n                // found the class\n                include_once $loc;\n            } else {\n                // can't find the class\n                return $this->error(\n                    \"Rendering format class '$class' not found\"\n                );\n            }\n        }\n\n        $this->formatObj[$format] = new $class($this);\n    }\n\n\n    /**\n     *\n     * Add a path to a path array.\n     *\n     * @access public\n     *\n     * @param string $type The path-type to add (parse or render).\n     *\n     * @param string $dir The directory to add to the path-type.\n     *\n     * @return void\n     *\n     */\n\n    function addPath($type, $dir)\n    {\n        $dir = $this->fixPath($dir);\n        if (! isset($this->path[$type])) {\n            $this->path[$type] = array($dir);\n        } else {\n            array_unshift($this->path[$type], $dir);\n        }\n    }\n\n\n    /**\n     *\n     * Get the current path array for a path-type.\n     *\n     * @access public\n     *\n     * @param string $type The path-type to look up (plugin, filter, or\n     * template).  If not set, returns all path types.\n     *\n     * @return array The array of paths for the requested type.\n     *\n     */\n\n    function getPath($type = null)\n    {\n        if (is_null($type)) {\n            return $this->path;\n        } elseif (! isset($this->path[$type])) {\n            return array();\n        } else {\n            return $this->path[$type];\n        }\n    }\n\n\n    /**\n     *\n     * Searches a series of paths for a given file.\n     *\n     * @param array $type The type of paths to search (template, plugin,\n     * or filter).\n     *\n     * @param string $file The file name to look for.\n     *\n     * @return string|bool The full path and file name for the target file,\n     * or boolean false if the file is not found in any of the paths.\n     *\n     */\n\n    function findFile($type, $file)\n    {\n        // get the set of paths\n        $set = $this->getPath($type);\n\n        // start looping through them\n        foreach ($set as $path) {\n            $fullname = $path . $this->_dirSep . $file;\n            if (file_exists($fullname) && is_readable($fullname)) {\n                return realpath($fullname);\n            }\n        }\n\n        // could not find the file in the set of paths\n        return false;\n    }\n\n\n    /**\n     *\n     * Append a trailing '/' to paths, unless the path is empty.\n     *\n     * @access private\n     *\n     * @param string $path The file path to fix\n     *\n     * @return string The fixed file path\n     *\n     */\n    function fixPath($path)\n    {\n        if (realpath($path)){\n            return realpath($path); // . (is_dir($path) ? $this->_dirSep : '');\n        } else {\n            return '';\n        }\n\n        /*\n        $len = strlen($this->_dirSep);\n        if (! empty($path) &&\n            substr($path, -1 * $len, $len) != $this->_dirSep)    {\n            return realpath($path) . $this->_dirSep;\n        } else {\n            return realpath($path);\n        }\n         */\n    }\n\n\n    /**\n     *\n     * Simple error-object generator.\n     *\n     * @access public\n     *\n     * @param string $message The error message.\n     *\n     * @return object PEAR_Error\n     *\n     */\n\n    function &error($message)\n    {\n        /*\n        if (! class_exists('PEAR_Error')) {\n            include_once 'PEAR.php';\n        }\n         */\n        throw new Exception($message);\n        return false;\n        //return PEAR::throwError($message);\n    }\n\n\n    /**\n     *\n     * Simple error checker.\n     *\n     * @access public\n     *\n     * @param mixed $obj Check if this is a PEAR_Error object or not.\n     *\n     * @return bool True if a PEAR_Error, false if not.\n     *\n     */\n\n    function isError(&$obj)\n    {\n        return is_a($obj, 'PEAR_Error');\n    }\n\n\n    /**\n     * Constructor: just adds the path to Creole rules\n     *\n     * @access public\n     * @param array $rules The set of rules to load for this object.\n     */\n    function checkInnerTags(&$text) {\n        $started = array();\n        $i = false;\n        while (($i = strpos($text, $this->delim, $i)) !== false) {\n            $j = strpos($text, $this->delim, $i + 1);\n            $t = substr($text, $i + 1, $j - $i - 1);\n            $i = $j + 1;\n            $rule = strtolower($this->tokens[$t][0]);\n            $type = $this->tokens[$t][1]['type'];\n\n            if ($type == 'start') {\n                if (empty($started[$rule])) {\n                    $started[$rule] = 0;\n                }\n                $started[$rule] += 1;\n            }\n            else if ($type == 'end') {\n                if (! $started[$rule]) return false;\n\n                $started[$rule] -= 1;\n                if (! $started[$rule]) unset($started[$rule]);\n            }\n        }\n        return ! (count($started) > 0);\n    }\n\n    function restoreRaw($text) {\n        $i = false;\n        while (($i = strpos($text, $this->delim, $i)) !== false) {\n            $j = strpos($text, $this->delim, $i + 1);\n            $t = substr($text, $i + 1, $j - $i - 1);\n            $rule = strtolower($this->tokens[$t][0]);\n\n            if ($rule == 'raw') {\n                $text = str_replace($this->delim. $t. $this->delim, $this->tokens[$t][1]['text'], $text);\n            } else {\n                $i = $j + 1;\n            }\n        }\n        return $text;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/Address.php",
    "content": "<?php\n\n/**\n *\n * Parses for signatures.\n * This class implements a Text_Wiki rule to find sections of the source\n * text that are signatures. A signature is any line starting with exactly\n * two - signs.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Address.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Address extends Text_Wiki_Parse {\n\n    /**\n     *\n     * The regular expression used to find source text matching this\n     * rule.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     */\n\n    var $regex = '/^--([^-].*)$/m';\n\n    /**\n     *\n     * Generates a token entry for the matched text. Token options are:\n     *\n     * 'start' => The starting point of the signature.\n     *\n     * 'end' => The ending point of the signature.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return A delimited token number to be used as a placeholder in\n     * the source text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $start = $this->wiki->addToken(\n            $this->rule, array('type' => 'start')\n        );\n\n        $end = $this->wiki->addToken(\n            $this->rule, array('type' => 'end')\n        );\n\n        return \"\\n\" . $start . trim($matches[1]) . $end;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Blockquote.php",
    "content": "<?php\n\n/**\n *\n * Parse for block-quoted text.\n *\n * Find source text marked as a blockquote, identified by any number of\n * greater-than signs '>' at the start of the line, followed by an\n * optional space, and then the quote text; each '>' indicates an\n * additional level of quoting.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Blockquote.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Blockquote extends Text_Wiki_Parse {\n\n\n    /**\n    *\n    * Regex for parsing the source text.\n    *\n    * @access public\n    *\n    * @var string\n    *\n    * @see parse()\n    *\n    */\n\n    var $regex = '/\\n(([>:]).*\\n)(?!([>:]))/Us';\n\n\n    /**\n    *\n    * Generates a replacement for the matched text.\n    *\n    * Token options are:\n    *\n    * 'type' =>\n    *     'start' : the start of a blockquote\n    *     'end'   : the end of a blockquote\n    *\n    * 'level' => the indent level (0 for the first level, 1 for the\n    * second, etc)\n    *\n    * @access public\n    *\n    * @param array &$matches The array of matches from parse().\n    *\n    * @return A series of text and delimited tokens marking the different\n    * list text and list elements.\n    *\n    */\n\n    function process(&$matches)\n    {\n        // the replacement text we will return to parse()\n        $return = '';\n\n        // the list of post-processing matches\n        $list = array();\n\n        // $matches[1] is the text matched as a list set by parse();\n        // create an array called $list that contains a new set of\n        // matches for the various list-item elements.\n        preg_match_all(\n            '=^([>:]+)(.*?\\n)=ms',\n            $matches[1],\n            $list,\n            PREG_SET_ORDER\n        );\n\n        // a stack of starts and ends; we keep this so that we know what\n        // indent level we're at.\n        $stack = array();\n\n        // loop through each list-item element.\n        foreach ($list as $key => $val) {\n\n            // $val[0] is the full matched list-item line\n            // $val[1] is the number of initial '>' chars (indent level)\n            // $val[2] is the quote text\n\n            // we number levels starting at 1, not zero\n            $level = strlen($val[1]);\n\n            // get the text of the line\n            $text = trim($val[2]);\n\n            // add a level to the list?\n            while ($level > count($stack)) {\n                \n                $css = ($val[1][count($stack)] == ':') ? 'remark' : '';\n                \n                // the current indent level is greater than the number\n                // of stack elements, so we must be starting a new\n                // level.  push the new level onto the stack with a\n                // dummy value (boolean true)...\n                array_push($stack, true);\n\n                $return .= \"\\n\\n\";\n\n                // ...and add a start token to the return.\n                $return .= $this->wiki->addToken(\n                    $this->rule,\n                    array(\n                        'type' => 'start',\n                        'level' => $level - 1,\n                        'css' => $css\n                    )\n                );\n\n                $return .= \"\\n\\n\";\n            }\n\n            // remove a level?\n            while (count($stack) > $level) {\n\n                // as long as the stack count is greater than the\n                // current indent level, we need to end list types.\n                // continue adding end-list tokens until the stack count\n                // and the indent level are the same.\n                array_pop($stack);\n\n                $return .= \"\\n\\n\";\n\n                $return .= $this->wiki->addToken(\n                    $this->rule,\n                    array (\n                        'type' => 'end',\n                        'level' => count($stack)\n                    )\n                );\n\n                $return .= \"\\n\\n\";\n            }\n\n            // add the line text.\n            $return .= $text . \"\\n\";\n        }\n\n        // the last line may have been indented.  go through the stack\n        // and create end-tokens until the stack is empty.\n        $return .= \"\\n\\n\";\n\n        while (count($stack) > 0) {\n            array_pop($stack);\n\n            $return .= \"\\n\\n\";\n\n            $return .= $this->wiki->addToken(\n                $this->rule,\n                array (\n                    'type' => 'end',\n                    'level' => count($stack)\n                )\n            );\n\n            $return .= \"\\n\\n\";\n        }\n\n        // we're done!  send back the replacement text.\n        return \"\\n\\n$return\\n\\n\";\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Box.php",
    "content": "<?php\n\n/**\n* \n* Parses for bold text.\n* \n* @category Text\n* \n* @package Text_Wiki\n* \n* @author Justin Patrin <papercrane@reversefold.com>\n* @author Paul M. Jones <pmjones@php.net>\n* \n* @license LGPL\n* \n* @version $Id: Box.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n* \n*/\n\n/**\n* \n* Parses for bold text.\n* \n* This class implements a Text_Wiki_Rule to find source text marked for\n* strong emphasis (bold) as defined by text surrounded by three\n* single-quotes. On parsing, the text itself is left in place, but the\n* starting and ending instances of three single-quotes are replaced with\n* tokens.\n*\n* @category Text\n* \n* @package Text_Wiki\n* \n* @author Justin Patrin <papercrane@reversefold.com>\n* @author Paul M. Jones <pmjones@php.net>\n* \n*/\n\nclass Text_Wiki_Parse_Box extends Text_Wiki_Parse {\n    \n    \n    /**\n    * \n    * The regular expression used to parse the source text and find\n    * matches conforming to this rule.  Used by the parse() method.\n    * \n    * @access public\n    * \n    * @var string\n    * \n    * @see parse()\n    * \n    */\n    \n    var $regex =  '/\\n\\[\\d+\\].*/s';\n    \n    \n    /**\n    * \n    * Generates a replacement for the matched text.  Token options are:\n    * \n    * 'type' => ['start'|'end'] The starting or ending point of the\n    * emphasized text.  The text itself is left in the source.\n    * \n    * @access public\n    *\n    * @param array &$matches The array of matches from parse().\n    *\n    * @return A pair of delimited tokens to be used as a placeholder in\n    * the source text surrounding the text to be emphasized.\n    *\n    */\n    \n    function process(&$matches)\n    {\n        $start = $this->wiki->addToken($this->rule, array('type' => 'start', 'css' => 'footnotes'));\n        $end = $this->wiki->addToken($this->rule, array('type' => 'end'));\n        return $start . $matches[0] . \"\\n\" . $end . \"\\n\\n\";\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Break.php",
    "content": "<?php\n\n/**\n* \n* Parses for explicit line breaks.\n* \n* @category Text\n* \n* @package Text_Wiki\n* \n* @author Paul M. Jones <pmjones@php.net>\n* \n* @license LGPL\n* \n* @version $Id: Break.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n* \n*/\n\n/**\n* \n* Parses for explicit line breaks.\n* \n* This class implements a Text_Wiki_Parse to mark forced line breaks in the\n* source text.\n*\n* @category Text\n* \n* @package Text_Wiki\n* \n* @author Paul M. Jones <pmjones@php.net>\n* \n*/\n\nclass Text_Wiki_Parse_Break extends Text_Wiki_Parse {\n    \n    \n    /**\n    * \n    * The regular expression used to parse the source text and find\n    * matches conforming to this rule.  Used by the parse() method.\n    * \n    * @access public\n    * \n    * @var string\n    * \n    * @see parse()\n    * \n    */\n    \n    //var $regex = \"/[ \\n]*([\\\\\\][\\\\\\]|\\%\\%\\%)[ \\n]*/\";\n    var $regex = \"/ *([\\\\\\][\\\\\\]|\\%\\%\\%)\\n?/\";\n    \n    \n    /**\n    * \n    * Generates a replacement token for the matched text.\n    * \n    * @access public\n    *\n    * @param array &$matches The array of matches from parse().\n    *\n    * @return string A delimited token to be used as a placeholder in\n    * the source text.\n    *\n    */\n    \n    function process(&$matches)\n    {    \n        return $this->wiki->addToken($this->rule);\n    }\n}\n\n?>"
  },
  {
    "path": "Creole/Parse/Center.php",
    "content": "<?php\n\n/**\n *\n * Parses for centered text.\n *\n * This class implements a Text_Wiki_Parse to find source text marked to\n * be a center element, as defined by text on a line by itself prefixed\n * with an exclamation mark (!).\n * The centered text itself is left in the source, but is prefixed and\n * suffixed with delimited tokens marking its start and end.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Tomaiuolo Michele <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Center.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Center extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/^! *(.*?)$/m';\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * centered text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A pair of delimited tokens to be used as a\n     * placeholder in the source text surrounding the centered text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $start = $this->wiki->addToken(\n            $this->rule,\n            array(\n                'type' => 'start'\n            )\n        );\n\n        $end = $this->wiki->addToken(\n            $this->rule,\n            array(\n                'type' => 'end'\n            )\n        );\n\n        return $start . trim($matches[1]) . $end . \"\\n\\n\";\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/Delete.php",
    "content": "<?php\n\n/**\n *\n * Parses for italic text.\n *\n * This class implements a Text_Wiki_Parse to find source text marked for\n * underlined as defined by text surrounded by two '_'.\n * On parsing, the text itself is left in place, but the starting and ending\n * instances of two '^' are replaced with tokens.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n */\n\nclass Text_Wiki_Parse_Delete extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    //var $regex =  \"/__(.*?)__/\";\n    var $regex =  \"/(?:\\-\\-(.+?)\\-\\-|(?:(?<=[\\W-\\xFF])\\-(?![ \\-]))(.+?)(?:(?<![ \\-])\\_(?=[\\W-\\xFF])))/\";\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * superscript text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A pair of delimited tokens to be used as a\n     * placeholder in the source text surrounding the text to be\n     * superscripted.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $text = $matches[1] ? $matches[1] : $matches[2];\n\n        if (! $this->wiki->checkInnerTags($text)) {\n            return $matches[0];\n        }\n\n        $start = $this->wiki->addToken(\n            'Delete', // $this->rule,\n            array('type' => 'start')\n        );\n\n        $end = $this->wiki->addToken(\n            'Delete', // $this->rule,\n            array('type' => 'end')\n        );\n\n        return $start . $text . $end;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/Delimiter.php",
    "content": "<?php\n\n/**\n *\n * Parses for Text_Wiki delimiter characters already in the source text.\n *\n * This class implements a Text_Wiki_Parse to find instances of the delimiter\n * character already embedded in the source text; it extracts them and replaces\n * them with a delimited token, then renders them as the delimiter itself\n * when the target format is XHTML.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n *\n * @license LGPL\n *\n * @version $Id: Delimiter.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Delimiter extends Text_Wiki_Parse {\n\n    /**\n     *\n     * Constructor.  Overrides the Text_Wiki_Parse constructor so that we\n     * can set the $regex property dynamically (we need to include the\n     * Text_Wiki $delim character.\n     *\n     * @param object &$obj The calling \"parent\" Text_Wiki object.\n     *\n     * @param string $name The token name to use for this rule.\n     *\n     */\n\n    function Text_Wiki_Parse_Delimiter(&$obj)\n    {\n        parent::Text_Wiki_Parse($obj);\n        $this->regex = '/' . $this->wiki->delim . '/';\n    }\n\n\n    /**\n     *\n     * Generates a token entry for the matched text.  Token options are:\n     *\n     * 'text' => The full matched text.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return A delimited token number to be used as a placeholder in\n     * the source text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        return $this->wiki->addToken(\n            $this->rule,\n            array('text' => $this->wiki->delim)\n        );\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Emphasis.php",
    "content": "<?php\n\n/**\n *\n * Parses for italic text.\n *\n * This class implements a Text_Wiki_Parse to find source text marked for\n * emphasis (italics) as defined by text surrounded by two slashes.\n * On parsing, the text itself is left in place, but the starting and ending\n * instances of two single-quotes are replaced with tokens.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n */\n\nclass Text_Wiki_Parse_Emphasis extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    //var $regex =  \"/\\/\\/(.*?)\\/\\//\";\n    var $regex =  \"/(?:\\/\\/(.+?)\\/\\/|(?:(?<=[\\W_\\xFF])\\/(?![ \\/]))(.+?)(?:(?<![ \\/])\\/(?=[\\W_\\xFF])))/\";\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * emphasized text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A pair of delimited tokens to be used as a\n     * placeholder in the source text surrounding the text to be\n     * emphasized.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $text = $matches[1] ? $matches[1] : $matches[2];\n        \n        if (! $this->wiki->checkInnerTags($text)) {\n            return $matches[0];\n        }\n\n        $start = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'start')\n        );\n\n        $end = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'end')\n        );\n\n        return $start . $text . $end;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Footnote.php",
    "content": "<?php\n\n/**\n *\n * Parses for bold text.\n *\n * This class implements a Text_Wiki_Rule to find source text marked for\n * strong emphasis (bold) as defined by text surrounded by two\n * stars. On parsing, the text itself is left in place, but the\n * starting and ending instances of two stars are replaced with\n * tokens.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Footnote.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Footnote extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex =  \"/(\\n)*\\[([0-9]+)\\]/\";\n\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * emphasized text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return A pair of delimited tokens to be used as a placeholder in\n     * the source text surrounding the text to be emphasized.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $id = $matches[2];\n        \n        if ($matches[1] == \"\\n\") {\n            $matches[1] = \"\\n\\n\";\n            $name = \"fn$id\";\n            $href = \"#ref$id\";\n        }\n        else {\n            $name = \"ref$id\";\n            $href = \"#fn$id\";\n        }\n        \n        $token = $this->wiki->addToken(\n            'Url',\n            array('text' => \"[$id]\", 'href' => $href, 'name' => $name, 'type' => 'inline')\n        );\n\n        return $matches[1] . $token;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Heading.php",
    "content": "<?php\n\n/**\n *\n * Parses for heading text.\n *\n * This class implements a Text_Wiki_Parse to find source text marked to\n * be a heading element, as defined by text on a line by itself prefixed\n * with a number of equasl signs (=), determining the heading level.\n * Equal signs at the end of the line are silently removed.\n * The heading text itself is left in the source, but is prefixed and\n * suffixed with delimited tokens marking the start and end of the heading.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Tomaiuolo Michele <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Heading.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Heading extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/^(={1,6}) *(.*?) *=*$/m';\n\n    var $conf = array(\n        'id_prefix' => 'toc'\n    );\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * heading text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A pair of delimited tokens to be used as a\n     * placeholder in the source text surrounding the heading text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        // keep a running count for header IDs.  we use this later\n        // when constructing TOC entries, etc.\n        static $id;\n        if (! isset($id)) {\n            $id = 0;\n        }\n\n        $prefix = htmlspecialchars($this->getConf('id_prefix'));\n\n        $start = $this->wiki->addToken(\n            $this->rule,\n            array(\n                'type' => 'start',\n                'level' => strlen($matches[1]),\n                'text' => trim($matches[2]),\n                'id' => $prefix . $id ++\n            )\n        );\n\n        $end = $this->wiki->addToken(\n            $this->rule,\n            array(\n                'type' => 'end',\n                'level' => strlen($matches[1])\n            )\n        );\n\n        return $start . trim($matches[2]) . $end . \"\\n\\n\";\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/Horiz.php",
    "content": "<?php\n\n/**\n *\n * Parses for horizontal ruling lines.\n *\n * This class implements a Text_Wiki_Parse to find source text marked to\n * be a horizontal rule, as defined by four dashed on their own line.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n *\n * @license LGPL\n *\n * @version $Id: Horiz.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Horiz extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/^([-]{4,})$/m';\n\n\n    /**\n     *\n     * Generates a replacement token for the matched text.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A token marking the horizontal rule.\n     *\n     */\n\n    function process(&$matches)\n    {\n        return \"\\n\" . $this->wiki->addToken($this->rule) . \"\\n\";\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Image.php",
    "content": "<?php\n\n/**\n *\n * Parse for images in the source text.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Tomaiuolo Michele <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Image.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\n\nclass Text_Wiki_Parse_Image extends Text_Wiki_Parse {\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/{{(.*)(\\|(.*))?}}/U';\n\n\n    /**\n     *\n     * Generates a replacement token for the matched text.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A token marking the horizontal rule.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $src = trim($matches[1]);\n\t\t$src = ltrim($src, '/');\n        $alt = isset($matches[3]) ? trim($matches[3]) : null;\n        if (!$alt) $alt = $src;\n\n        return $this->wiki->addToken(\n            $this->rule,\n            array(\n                'src' => $src,\n                'attr' => array('alt' => $alt, 'title' => $alt)\n            )\n        );\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/List.php",
    "content": "<?php\n\n/**\n *\n * Parses for bulleted and numbered lists.\n *\n * This class implements a Text_Wiki_Parse to find source text marked as\n * a bulleted or numbered list.  In short, if a line starts with '*' then\n * it is a bullet list item; if a line starts with '#' then it is a\n * number list item.  Multiple * or # indicate an indented sub-list.\n * The list items must be on sequential lines, and are ended by blank lines.\n * Using a non-* non-# character at the beginning of a line ends the list.\n * Note that single newline characters may be eaten beforehand by other rules.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Justin Patrin <papercrane@reversefold.com>\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: List.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_List extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/\\n((\\*[^\\#\\-\\*]|\\-[^\\-\\d\\*\\#]|\\#[^\\#\\-\\*]).*?)\\n(?![\\*\\-#])/s';\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' =>\n     *     'bullet_start' : the start of a bullet list\n     *     'bullet_end'   : the end of a bullet list\n     *     'number_start' : the start of a number list\n     *     'number_end'   : the end of a number list\n     *     'item_start'   : the start of item text (bullet or number)\n     *     'item_end'     : the end of item text (bullet or number)\n     *     'unknown'      : unknown type of list or item\n     *\n     * 'level' => the indent level (0 for the first level, 1 for the\n     * second, etc)\n     *\n     * 'count' => the list item number at this level. not needed for\n     * xhtml, but very useful for PDF and RTF.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return A series of text and delimited tokens marking the different\n     * list text and list elements.\n     *\n     */\n\n    function process(&$matches)\n    {\n        // the replacement text we will return\n        $return = '';\n\n        // the list of post-processing matches\n        $list = array();\n\n        // a stack of list-start and list-end types; we keep this\n        // so that we know what kind of list we're working with\n        // (bullet or number) and what indent level we're at.\n        $stack = array();\n\n        // the item count is the number of list items for any\n        // given list-type on the stack\n        $itemcount = array();\n\n        // have we processed the very first list item?\n        $pastFirst = false;\n\n        // populate $list with this set of matches. $matches[1] is the\n        // text matched as a list set by parse().\n        preg_match_all(\n            '/^((\\*|\\-|#)+) *(.*?)$/ms',\n            $matches[1],\n            $list,\n            PREG_SET_ORDER\n        );\n        \n        if (count($list) === 1 && $matches[0][0] === '*' && $matches[0][1] !== ' ' && strpos($matches[0], '*', 1)) {\n            return $matches[0];\n        }\n\n        // loop through each list-item element.\n        foreach ($list as $key => $val) {\n            // $val[0] is the full matched list-item line\n            // $val[1] is the level (number)\n            // $val[2] is the type (* or #)\n            // $val[3] is the list item text\n\n            // how many levels are we indented? (1 means the \"root\"\n            // list level, no indenting.)\n            $stars = $val[1];\n            $level = strlen($stars);\n            $last = $stars[strlen($stars) - 1];\n\n            // get the list item type\n            if ($last == '*' || $last == '-') {\n                $type = 'bullet';\n            } elseif ($last == '#') {\n                $type = 'number';\n            } else {\n                $type = 'unknown';\n            }\n\n            // get the text of the list item\n            $text = $val[3];\n\n            // remove a level from the list?\n            while (count($stack) > $level || (count($stack) == $level && $type != $stack[$level - 1])) {\n\n                // so we don't keep counting the stack, we set up a temp\n                // var for the count.  -1 becuase we're going to pop the\n                // stack in the next command.  $tmp will then equal the\n                // current level of indent.\n                $tmp = count($stack) - 1;\n\n                // as long as the stack count is greater than the\n                // current indent level, we need to end list types.\n                // continue adding end-list tokens until the stack count\n                // and the indent level are the same.\n                $return .= $this->wiki->addToken(\n                    $this->rule,\n                    array (\n                        'type' => array_pop($stack) . '_list_end',\n                        'level' => $tmp\n                    )\n                );\n\n                // reset to the current (previous) list type so that\n                // the new list item matches the proper list type.\n                if ($tmp) {\n\t\t\t\t\t$oldtype = $stack[$tmp - 1];\n\t\t\t\t}\n\n                // reset the item count for the popped indent level\n                unset($itemcount[$tmp + 1]);\n            }\n\n            // add a level to the list?\n            if ($level > count($stack)) {\n\n                // the current indent level is greater than the\n                // number of stack elements, so we must be starting\n                // a new list.  push the new list type onto the\n                // stack...\n                array_push($stack, $type);\n\n                // ...and add a list-start token to the return.\n                $return .= $this->wiki->addToken(\n                    $this->rule,\n                    array(\n                        'type' => $type . '_list_start',\n                        'level' => $level - 1\n                    )\n                );\n            }\n\n            // add to the item count for this list (taking into account\n            // which level we are at).\n            if (! isset($itemcount[$level])) {\n                // first count\n                $itemcount[$level] = 0;\n            } else {\n                // increment count\n                $itemcount[$level]++;\n            }\n\n            // is this the very first item in the list?\n            if (! $pastFirst) {\n                $first = true;\n                $pastFirst = true;\n            } else {\n                $first = false;\n            }\n\n            // create a list-item starting token.\n            $start = $this->wiki->addToken(\n                $this->rule,\n                array(\n                    'type' => $type . '_item_start',\n                    'level' => $level,\n                    'count' => $itemcount[$level],\n                    'first' => $first\n                )\n            );\n\n            // create a list-item ending token.\n            $end = $this->wiki->addToken(\n                $this->rule,\n                array(\n                    'type' => $type . '_item_end',\n                    'level' => $level,\n                    'count' => $itemcount[$level]\n                )\n            );\n\n            // add the starting token, list-item text, and ending token\n            // to the return.\n            $return .= \"\\n\" . $start . $text . $end;\n        }\n\n        // the last list-item may have been indented.  go through the\n        // list-type stack and create end-list tokens until the stack\n        // is empty.\n        while (count($stack) > 0) {\n            $return .= $this->wiki->addToken(\n                $this->rule,\n                array (\n                    'type' => array_pop($stack) . '_list_end',\n                    'level' => count($stack)\n                )\n            );\n        }\n\n        // we're done!  send back the replacement text.\n        return \"\\n\\n\" . $return . \"\\n\\n\";\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Newline.php",
    "content": "<?php\n\n/**\n *\n * Parses for implied line breaks indicated by newlines.\n * Newlines are not considered if followed by another newline\n * or by one of these chars: * | - # = {\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Newline.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Newline extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    //var $regex = '/(?<!\\n)\\n(?![\\n\\#\\=\\|\\-\\>\\:]|\\*[^\\*\\#]|\\*+ )/m';\n    var $regex = '/(?<!\\n)\\n(?!\\n|\\#|\\*|\\=|\\||\\>|\\:|\\!|\\-\\D)/m';\n\n\n    /**\n     *\n     * Generates a replacement token for the matched text.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A delimited token to be used as a placeholder in\n     * the source text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        return ' '; // $this->wiki->addToken($this->rule);\n    }\n}\n\n?>"
  },
  {
    "path": "Creole/Parse/Paragraph.php",
    "content": "<?php\n\n/**\n *\n * Parses for paragraph blocks.\n * This class implements a Text_Wiki rule to find sections of the source\n * text that are paragraphs. A paragraph is any line not starting with a\n * token delimiter, followed by two newlines.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Paragraph.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Paragraph extends Text_Wiki_Parse {\n\n    /**\n     *\n     * The regular expression used to find source text matching this\n     * rule.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     */\n\n    var $regex = \"/^.+?\\n/m\"; // (?=[\\n\\-\\|#{=])\n\n    var $conf = array(\n        'skip' => array(\n            'address',\n            'box',\n            'blockquote',\n            'code',\n            'heading',\n            'center',\n            'horiz',\n            'deflist',\n            'table',\n            'list',\n            'paragraph',\n            'preformatted',\n            'toc'\n        )\n    );\n\n\n    /**\n     *\n     * Generates a token entry for the matched text. Token options are:\n     *\n     * 'start' => The starting point of the paragraph.\n     *\n     * 'end' => The ending point of the paragraph.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return A delimited token number to be used as a placeholder in\n     * the source text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $delim = $this->wiki->delim;\n\n        // was anything there?\n        if (trim($matches[0]) == '') {\n            return '';\n        }\n\n        // does the match start with a delimiter?\n        if (substr($matches[0], 0, 1) != $delim) {\n            // no.\n\n            $start = $this->wiki->addToken(\n                $this->rule, array('type' => 'start')\n            );\n\n            $end = $this->wiki->addToken(\n                $this->rule, array('type' => 'end')\n            );\n\n            return $start . trim($matches[0]) . $end;\n        }\n\n        // the line starts with a delimiter.  read in the delimited\n        // token number, check the token, and see if we should\n        // skip it.\n\n        // loop starting at the second character (we already know\n        // the first is a delimiter) until we find another\n        // delimiter; the text between them is a token key number.\n        $key = '';\n        $len = strlen($matches[0]);\n        for ($i = 1; $i < $len; $i++) {\n            $char = $matches[0]{$i};\n            if ($char == $delim) {\n                break;\n            } else {\n                $key .= $char;\n            }\n        }\n\n        // look at the token and see if it's skippable (if we skip,\n        // it will not be marked as a paragraph)\n        $token_type = strtolower($this->wiki->tokens[$key][0]);\n        $skip = $this->getConf('skip', array());\n\n        if (in_array($token_type, $skip)) {\n            // this type of token should not have paragraphs applied to it.\n            // return the entire matched text.\n            return $matches[0];\n        } else {\n\n            $start = $this->wiki->addToken(\n                $this->rule, array('type' => 'start')\n            );\n\n            $end = $this->wiki->addToken(\n                $this->rule, array('type' => 'end')\n            );\n\n            return $start . trim($matches[0]) . $end;\n        }\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Prefilter.php",
    "content": "<?php\n\n/**\n *\n * \"Pre-filter\" the source text.\n *\n * Convert DOS and Mac line endings to Unix, convert tabs to 4-spaces,\n * add newlines to the top and end of the source text.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Prefilter.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Prefilter extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * Simple parsing method.\n     *\n     * @access public\n     *\n     */\n\n    function parse()\n    {\n        // convert DOS line endings\n        $this->wiki->source = str_replace(\"\\r\\n\", \"\\n\",\n            $this->wiki->source);\n\n        // convert Macintosh line endings\n        $this->wiki->source = str_replace(\"\\r\", \"\\n\",\n            $this->wiki->source);\n\n        // convert tabs to four-spaces\n        $this->wiki->source = str_replace(\"\\t\", \"    \",\n            $this->wiki->source);\n\n        // add extra newlines at the top and end; this\n        // seems to help many rules.\n        $this->wiki->source = \"\\n\\n\" . $this->wiki->source . \"\\n\\n\";\n    }\n\n}\n?>"
  },
  {
    "path": "Creole/Parse/Preformatted.php",
    "content": "<?php\n\n/**\n *\n * Parses for preformatted text.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Tomaiuolo Michele <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Preformatted.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Preformatted extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule. Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/\\n{{{\\n(.*)\\n}}}\\n/Us';\n\n    /**\n     *\n     * Generates a replacement for the matched text. Token options are:\n     *\n     * 'text' => The preformatted text.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A token to be used as a placeholder\n     * in the source text for the preformatted text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        // > any line consisting of only indented three closing curly braces\n        // > will have one space removed from the indentation\n        // > -- http://www.wikicreole.org/wiki/AddNoWikiEscapeProposal\n        $find = \"/\\n( *) }}}/\";\n        $replace = \"\\n$1}}}\";\n        $matches[1] = preg_replace($find, $replace, $matches[1]);\n    \n        $token = $this->wiki->addToken(\n            $this->rule,\n            array('text' => $matches[1])\n        );\n        return \"\\n\\n\" . $token . \"\\n\\n\";\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/Raw.php",
    "content": "<?php\n\n/**\n *\n * Parses for monospaced inline text.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Tomaiuolo Michele <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Raw.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Raw extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/~~([^ \\n])/';\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * monospaced text.  The text itself is encapsulated into a Raw token.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A token to be used as a placeholder\n     * in the source text for the preformatted text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        return $this->wiki->addToken(\n            $this->rule,\n            array('text' => $matches[1], 'type' => 'escape')\n        );\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/Strong.php",
    "content": "<?php\n\n/**\n *\n * Parses for bold text.\n *\n * This class implements a Text_Wiki_Rule to find source text marked for\n * strong emphasis (bold) as defined by text surrounded by two\n * stars. On parsing, the text itself is left in place, but the\n * starting and ending instances of two stars are replaced with\n * tokens.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Strong.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Strong extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    //var $regex =  \"/\\*\\*(.*?)\\*\\*/\";\n    var $regex =  \"/(?:\\*\\*(.+?)\\*\\*|(?:(?<=[\\W_\\xFF])\\*(?![ \\*]))(.+?)(?:(?<![ \\*])\\*(?=[\\W_\\xFF])))/\";\n\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * emphasized text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return A pair of delimited tokens to be used as a placeholder in\n     * the source text surrounding the text to be emphasized.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $text = $matches[1] ? $matches[1] : $matches[2];\n        \n        if (! $this->wiki->checkInnerTags($text)) {\n            return $matches[0];\n        }\n\n        $start = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'start')\n        );\n\n        $end = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'end')\n        );\n\n        return $start . $text . $end;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Subscript.php",
    "content": "<?php\n\n/**\n *\n * Parses for italic text.\n *\n * This class implements a Text_Wiki_Parse to find source text marked for\n * superscript as defined by text surrounded by two '^'.\n * On parsing, the text itself is left in place, but the starting and ending\n * instances of two '^' are replaced with tokens.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n */\n\nclass Text_Wiki_Parse_Subscript extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex =  \"/\\,\\,(.*?)\\,\\,/\";\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * superscript text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A pair of delimited tokens to be used as a\n     * placeholder in the source text surrounding the text to be\n     * superscripted.\n     *\n     */\n\n    function process(&$matches)\n    {\n        if (! $this->wiki->checkInnerTags($matches[1])) {\n            return $matches[0];\n        }\n\n        $start = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'start')\n        );\n\n        $end = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'end')\n        );\n\n        return $start . $matches[1] . $end;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Superscript.php",
    "content": "<?php\n\n/**\n *\n * Parses for italic text.\n *\n * This class implements a Text_Wiki_Parse to find source text marked for\n * superscript as defined by text surrounded by two '^'.\n * On parsing, the text itself is left in place, but the starting and ending\n * instances of two '^' are replaced with tokens.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n */\n\nclass Text_Wiki_Parse_Superscript extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex =  \"/\\^\\^(.*?)\\^\\^/\";\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * superscript text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A pair of delimited tokens to be used as a\n     * placeholder in the source text surrounding the text to be\n     * superscripted.\n     *\n     */\n\n    function process(&$matches)\n    {\n        if (! $this->wiki->checkInnerTags($matches[1])) {\n            return $matches[0];\n        }\n\n        $start = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'start')\n        );\n\n        $end = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'end')\n        );\n\n        return $start . $matches[1] . $end;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Table.php",
    "content": "<?php\n\n/**\n *\n * Parses for table markup.\n *\n * This class implements a Text_Wiki_Parse to find source text marked as\n * a set of table rows, where a line start (and optionally ends) with a\n * single-pipe (|) and uses single-pipes to separate table cells.\n * The rows must be on sequential lines (no blank lines between them).\n * A blank line indicates the beginning of other text or another table.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n * @author Paul M. Jones <pmjones@php.net>\n *\n * @license LGPL\n *\n * @version $Id: Table.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\n\nclass Text_Wiki_Parse_Table extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/\\n((\\|).*)(\\n)(?!(\\|))/Us';\n\n\n    /**\n     *\n     * Generates a replacement for the matched text.\n     *\n     * Token options are:\n     *\n     * 'type' =>\n     *     'table_start' : the start of a bullet list\n     *     'table_end'   : the end of a bullet list\n     *     'row_start' : the start of a number list\n     *     'row_end'   : the end of a number list\n     *     'cell_start'   : the start of item text (bullet or number)\n     *     'cell_end'     : the end of item text (bullet or number)\n     *\n     * 'cols' => the number of columns in the table (for 'table_start')\n     *\n     * 'rows' => the number of rows in the table (for 'table_start')\n     *\n     * 'span' => column span (for 'cell_start')\n     *\n     * 'attr' => column attribute flag (for 'cell_start')\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return A series of text and delimited tokens marking the different\n     * table elements and cell text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        // our eventual return value\n        $return = '';\n\n        // the number of columns in the table\n        $num_cols = 0;\n\n        // the number of rows in the table\n        $num_rows = 0;\n\n        // rows are separated by newlines in the matched text\n        $rows = explode(\"\\n\", $matches[1]);\n\n        // loop through each row\n        foreach ($rows as $row) {\n\n            // increase the row count\n            $num_rows ++;\n\n            // remove first and last (optional) pipe\n            $row = substr($row, 1);\n            if ($row[strlen($row) - 1] == '|') {\n                $row = substr($row, 0, -1);\n            }\n\n            // cells are separated by pipes\n            $cells = explode(\"|\", $row);\n            \n            if (count($cells) == 1 && $cells[0][0] == '=' && ($num_rows == 1 || $num_rows == count($rows)) && ! $caption) {\n                $caption = trim(trim($cells[0], '='));\n            \n                // start the caption...\n                $return .= $this->wiki->addToken(\n                    $this->rule,\n                    array ('type' => 'caption_start')\n                );\n\n                // ...add the content...\n                $return .= $caption;\n\n                // ...and end the caption.\n                $return .= $this->wiki->addToken(\n                    $this->rule,\n                    array ('type' => 'caption_end')\n                );\n            }\n            else {\n\n                // update the column count\n                if (count($cells) > $num_cols) {\n                    $num_cols = count($cells);\n                }\n\n                // start a new row\n                $return .= $this->wiki->addToken(\n                    $this->rule,\n                    array('type' => 'row_start')\n                );\n\n                for ($i = 0; $i < count($cells); $i++) {\n                    $cell = $cells[$i];\n\n                    // by default, cells span only one column (their own)\n                    $span = 1;\n                    $attr = '';\n                    \n                    while ($i + 1 < count($cells) && ! strlen($cells[$i + 1])) {\n                        $i++;\n                        $span++;\n                    }\n\n                    if ($cell[0] == '=') {\n                        $attr = 'header';\n                        $cell = trim($cell, '=');\n                    }\n\n                    // start a new cell...\n                    $return .= $this->wiki->addToken(\n                        $this->rule,\n                        array (\n                            'type' => 'cell_start',\n                            'attr' => $attr,\n                            'span' => $span\n                        )\n                    );\n\n                    // ...add the content...\n                    $return .= trim($cell);\n\n                    // ...and end the cell.\n                    $return .= $this->wiki->addToken(\n                        $this->rule,\n                        array (\n                            'type' => 'cell_end',\n                            'attr' => $attr,\n                            'span' => $span\n                        )\n                    );\n                }\n\n                // end the row\n                $return .= $this->wiki->addToken(\n                    $this->rule,\n                    array('type' => 'row_end')\n                );\n            }\n        }\n\n        // we're done!\n        return\n            \"\\n\\n\".\n            $this->wiki->addToken(\n                $this->rule,\n                array(\n                    'type' => 'table_start',\n                    'rows' => $num_rows,\n                    'cols' => $num_cols\n                )\n            ).\n            $return.\n            $this->wiki->addToken(\n                $this->rule,\n                array(\n                    'type' => 'table_end'\n                )\n            ).\n            \"\\n\\n\";\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Tighten.php",
    "content": "<?php\n\n/**\n *\n * The rule removes all remaining newlines.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n *\n * @license LGPL\n *\n * @version $Id: Tighten.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\n\nclass Text_Wiki_Parse_Tighten extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * Apply tightening directly to the source text.\n     *\n     * @access public\n     *\n     */\n\n    function parse()\n    {\n        $this->wiki->source = str_replace(\"\\n\", '',\n            $this->wiki->source);\n    }\n}\n?>"
  },
  {
    "path": "Creole/Parse/Trim.php",
    "content": "<?php\n\n/**\n *\n * Trim lines in the source text and compress 3 or more newlines to\n * 2 newlines.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n */\n\nclass Text_Wiki_Parse_Trim extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * Simple parsing method.\n     *\n     * @access public\n     *\n     */\n\n    function parse()\n    {\n        // trim lines\n        $find = \"/ *\\n */\";\n        $replace = \"\\n\";\n        $this->wiki->source = preg_replace($find, $replace, $this->wiki->source);\n\n        // trim lines with only one dash or star\n        $find = \"/\\n[\\-\\*]\\n/\";\n        $replace = \"\\n\\n\";\n        $this->wiki->source = preg_replace($find, $replace, $this->wiki->source);\n\n        // finally, compress all instances of 3 or more newlines\n        // down to two newlines.\n        $find = \"/\\n{3,}/m\";\n        $replace = \"\\n\\n\";\n        $this->wiki->source = preg_replace($find, $replace, $this->wiki->source);\n            \n        // numbered lists\n        $find = \"/(\\n[\\*\\#]*)([\\d]+[\\.\\)]|[\\w]\\))/s\";\n        $replace = \"$1#\";\n        $this->wiki->source = preg_replace($find, $replace, $this->wiki->source);\n\n        // make ordinal numbers superscripted\n        $find = \"/([\\d])(st|nd|rd|th|er|e|re|ers|res|nds|de|des|re|me|res|mes|o|a)([\\W])/\";\n        $replace = \"$1^^$2^^$3\";\n        $this->wiki->source = preg_replace($find, $replace, $this->wiki->source);\n\n        // numbers in parentesis are footnotes and references\n        $find = \"/\\(([\\d][\\d]?)\\)/\";\n        $replace = \"[$1]\";\n        $this->wiki->source = preg_replace($find, $replace, $this->wiki->source);\n\n        // add hr before footnotes\n        $find = \"/(\\n+\\-\\-\\-\\-+\\n*)?(\\n\\[[\\d]+\\].*)/s\";\n        $replace = \"\\n\\n----\\n\\n$2\";\n        $this->wiki->source = preg_replace($find, $replace, $this->wiki->source);\n\n    }\n\n}\n?>"
  },
  {
    "path": "Creole/Parse/Tt.php",
    "content": "<?php\n\n/**\n *\n * Parses for monospaced inline text.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Tomaiuolo Michele <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Tt.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Tt extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    var $regex = '/{{{(.*?)}}}(?!}|{{{)/';\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * monospaced text.  The text itself is encapsulated into a Raw token.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A token to be used as a placeholder\n     * in the source text for the preformatted text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        // remove the sequence }}}{{{\n        $find = \"/}}}{{{/\";\n        $replace = \"\";\n        $matches[1] = preg_replace($find, $replace, $matches[1]);\n        \n        $start = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'start')\n        );\n\n        $raw = $this->wiki->addToken(\n            'Raw',\n            array('text' => $matches[1])\n        );\n\n        $end = $this->wiki->addToken(\n            $this->rule,\n            array('type' => 'end')\n        );\n\n        return $start . $raw . $end;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/Underline.php",
    "content": "<?php\n\n/**\n *\n * Parses for italic text.\n *\n * This class implements a Text_Wiki_Parse to find source text marked for\n * underlined as defined by text surrounded by two '_'.\n * On parsing, the text itself is left in place, but the starting and ending\n * instances of two '^' are replaced with tokens.\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Paul M. Jones <pmjones@php.net>\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n */\n\nclass Text_Wiki_Parse_Underline extends Text_Wiki_Parse {\n\n\n    /**\n     *\n     * The regular expression used to parse the source text and find\n     * matches conforming to this rule.  Used by the parse() method.\n     *\n     * @access public\n     *\n     * @var string\n     *\n     * @see parse()\n     *\n     */\n\n    //var $regex =  \"/__(.*?)__/\";\n    var $regex =  \"/(?:\\_\\_(.+?)\\_\\_|(?:(?<=[\\W_\\xFF])\\_(?![ \\_]))(.+?)(?:(?<![ \\_])\\_(?=[\\W_\\xFF])))/\";\n\n    /**\n     *\n     * Generates a replacement for the matched text.  Token options are:\n     *\n     * 'type' => ['start'|'end'] The starting or ending point of the\n     * superscript text.  The text itself is left in the source.\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A pair of delimited tokens to be used as a\n     * placeholder in the source text surrounding the text to be\n     * superscripted.\n     *\n     */\n\n    function process(&$matches)\n    {\n        $text = $matches[1] ? $matches[1] : $matches[2];\n\n        if (! $this->wiki->checkInnerTags($text)) {\n            return $matches[0];\n        }\n\n        $start = $this->wiki->addToken(\n            'Underline', // $this->rule,\n            array('type' => 'start')\n        );\n\n        $end = $this->wiki->addToken(\n            'Underline', // $this->rule,\n            array('type' => 'end')\n        );\n\n        return $start . $text . $end;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Parse/Url.php",
    "content": "<?php\n\n/**\n *\n * Parse for URLS in the source text.\n *\n * raw       -- http://example.com\n * no descr. -- [[http://example.com]]\n * described -- [[http://example.com|Example Description]]\n *\n * When rendering a URL token, this will convert URLs pointing to a .gif,\n * .jpg, or .png image into an inline <img /> tag (for the 'xhtml'\n * format).\n *\n * @category Text\n *\n * @package Text_Wiki\n *\n * @author Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license LGPL\n *\n * @version $Id: Url.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n */\n\nclass Text_Wiki_Parse_Url extends Text_Wiki_Parse {\n\n    /**\n     *\n     * Constructor.  Overrides the Text_Wiki_Parse constructor so that we\n     * can set the $regex property dynamically (we need to include the\n     * Text_Wiki $delim character).\n     *\n     * @param object &$obj The calling \"parent\" Text_Wiki object.\n     *\n     * @param string $name The token name to use for this rule.\n     *\n     */\n\n    function Text_Wiki_Parse_Url(&$obj)\n    {\n        parent::Text_Wiki_Parse($obj);\n        $this->regex = '/((?:\\[\\[ *((?:http:\\/\\/|https:\\/\\/|ftp:\\/\\/|mailto:|\\/)[^\\|\\]\\n ]*)( *\\| *([^\\]\\n]*))? *\\]\\])|((http:\\/\\/|https:\\/\\/|ftp:\\/\\/|mailto:)[^\\'\\\"\\n ' . $this->wiki->delim . ']*[A-Za-z0-9\\/\\?\\=\\&\\~\\_]))/';\n    }\n\n\n    /**\n     *\n     * Generates a replacement for the matched text.\n     *\n     * Token options are:\n     *\n     * 'href' => the URL link href portion\n     *\n     * 'text' => the displayed text of the URL link\n     *\n     * @access public\n     *\n     * @param array &$matches The array of matches from parse().\n     *\n     * @return string A token to be used as a placeholder\n     * in the source text for the preformatted text.\n     *\n     */\n\n    function process(&$matches)\n    {\n        if (isset($matches[2])) $href = trim($matches[2]);\n        if (isset($matches[4])) $text = trim($matches[4]);\n        if (isset($matches[5])) $rawurl = $matches[5];\n        if (empty($href)) $href = $rawurl;\n\n        if (empty($text)) {\n            $text = $href;\n            if (strpos($text, '/') === FALSE) {\n\t\t\t\t$text = str_replace('http://', '', $text);\n\t\t\t\t$text = str_replace('mailto:', '', $text);\n\t\t\t}\n            return $this->wiki->addToken(\n                $this->rule,\n                array(\n\t\t\t\t\t'type' => 'inline',\n                    'href' => $href,\n                    'text' => $text\n                )\n            );\n        } else {\n            return $this->wiki->addToken(\n                $this->rule,\n                array(\n                    'type' => 'start',\n                    'href' => $href,\n                    'text' => $text\n                )\n            ) . $text .\n            $this->wiki->addToken(\n                $this->rule,\n                array(\n                    'type' => 'end',\n                    'href' => $href,\n                    'text' => $text\n                )\n            );\n        }\n    }\n\n}\n?>"
  },
  {
    "path": "Creole/Parse.inc.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Baseline rule class for extension into a \"real\" parser component.\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Parse.inc.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * Baseline rule class for extension into a \"real\" parser component.\n *\n * Text_Wiki_Rule classes do not stand on their own; they are called by a\n * Text_Wiki object, typcially in the transform() method. Each rule class\n * performs three main activities: parse, process, and render.\n *\n * The parse() method takes a regex and applies it to the whole block of\n * source text at one time. Each match is sent as $matches to the\n * process() method.\n *\n * The process() method acts on the matched text from the source, and\n * then processes the source text is some way.  This may mean the\n * creation of a delimited token using addToken().  In every case, the\n * process() method returns the text that should replace the matched text\n * from parse().\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Parse {\n\n\n    /**\n    *\n    * Configuration options for this parser rule.\n    *\n    * @access public\n    *\n    * @var string\n    *\n    */\n\n    var $conf = array();\n\n\n    /**\n    *\n    * Regular expression to find matching text for this rule.\n    *\n    * @access public\n    *\n    * @var string\n    *\n    * @see parse()\n    *\n    */\n\n    var $regex = null;\n\n\n    /**\n    *\n    * The name of this rule for new token array elements.\n    *\n    * @access public\n    *\n    * @var string\n    *\n    */\n\n    var $rule = null;\n\n\n    /**\n    *\n    * A reference to the calling Text_Wiki object.\n    *\n    * This is needed so that each rule has access to the same source\n    * text, token set, URLs, interwiki maps, page names, etc.\n    *\n    * @access public\n    *\n    * @var object\n    */\n\n    var $wiki = null;\n\n\n    /**\n    *\n    * Constructor for this parser rule.\n    *\n    * @access public\n    *\n    * @param object &$obj The calling \"parent\" Text_Wiki object.\n    *\n    */\n\n    function Text_Wiki_Parse(&$obj)\n    {\n        // set the reference to the calling Text_Wiki object;\n        // this allows us access to the shared source text, token\n        // array, etc.\n        $this->wiki =& $obj;\n\n        // set the name of this rule; generally used when adding\n        // to the tokens array. strip off the Text_Wiki_Parse_ portion.\n        // text_wiki_parse_\n        // 0123456789012345\n        $tmp = substr(get_class($this), 16);\n        $this->rule = ucwords(strtolower($tmp));\n\n        // override config options for the rule if specified\n        if (isset($this->wiki->parseConf[$this->rule]) &&\n            is_array($this->wiki->parseConf[$this->rule])) {\n\n            $this->conf = array_merge(\n                $this->conf,\n                $this->wiki->parseConf[$this->rule]\n            );\n        }\n    }\n\n\n    /**\n    *\n    * Abstrct method to parse source text for matches.\n    *\n    * Applies the rule's regular expression to the source text, passes\n    * every match to the process() method, and replaces the matched text\n    * with the results of the processing.\n    *\n    * @access public\n    *\n    * @see Text_Wiki_Parse::process()\n    *\n    */\n\n    function parse()\n    {\n        $this->wiki->source = preg_replace_callback(\n            $this->regex,\n            array(&$this, 'process'),\n            $this->wiki->source\n        );\n    }\n\n\n    /**\n    *\n    * Abstract method to generate replacements for matched text.\n    *\n    * @access public\n    *\n    * @param array $matches An array of matches from the parse() method\n    * as generated by preg_replace_callback.  $matches[0] is the full\n    * matched string, $matches[1] is the first matched pattern,\n    * $matches[2] is the second matched pattern, and so on.\n    *\n    * @return string The processed text replacement; defaults to the\n    * full matched string (i.e., no changes to the text).\n    *\n    * @see Text_Wiki_Parse::parse()\n    *\n    */\n\n    function process(&$matches)\n    {\n        return $matches[0];\n    }\n\n\n    /**\n    *\n    * Simple method to safely get configuration key values.\n    *\n    * @access public\n    *\n    * @param string $key The configuration key.\n    *\n    * @param mixed $default If the key does not exist, return this value\n    * instead.\n    *\n    * @return mixed The configuration key value (if it exists) or the\n    * default value (if not).\n    *\n    */\n\n    function getConf($key, $default = null)\n    {\n        if (isset($this->conf[$key])) {\n            return $this->conf[$key];\n        } else {\n            return $default;\n        }\n    }\n\n\n    /**\n    *\n    * Extract 'attribute=\"value\"' portions of wiki markup.\n    *\n    * This kind of markup is typically used only in macros, but is useful\n    * anywhere.\n    *\n    * The syntax is pretty strict; there can be no spaces between the\n    * option name, the equals, and the first double-quote; the value\n    * must be surrounded by double-quotes.  You can escape characters in\n    * the value with a backslash, and the backslash will be stripped for\n    * you.\n    *\n    * @access public\n    *\n    * @param string $text The \"attributes\" portion of markup.\n    *\n    * @return array An associative array of key-value pairs where the\n    * key is the option name and the value is the option value.\n    *\n    */\n\n    function getAttrs($text)\n    {\n        // find the =\" sections;\n        $tmp = explode('=\"', trim($text));\n\n        // basic setup\n        $k = count($tmp) - 1;\n        $attrs = array();\n        $key = null;\n\n        // loop through the sections\n        foreach ($tmp as $i => $val) {\n\n            // first element is always the first key\n            if ($i == 0) {\n                $key = trim($val);\n                continue;\n            }\n\n            // find the last double-quote in the value.\n            // the part to the left is the value for the last key,\n            // the part to the right is the next key name\n            $pos = strrpos($val, '\"');\n            $attrs[$key] = stripslashes(substr($val, 0, $pos));\n            $key = trim(substr($val, $pos+1));\n\n        }\n\n        return $attrs;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Plugin.php",
    "content": "<?php\n/**\n * 使用 <a href=\"http://www.wikicreole.org/\" target=\"_blank\">Creole 语法</a>发布文章。改进版本支持中文（utf-8 编码）、并除去不必要的标签。\n * \n * @package Creole 解析器（改进版）\n * @author 明城<i.feelinglucky@gmail.com>\n * @version 0.2\n * @link http://www.gracecode.com/\n */\n\nrequire_once 'Creole/Creole_Wiki.php';\n\nclass Creole_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate() {\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->excerpt = array('Creole_Plugin', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->content = array('Creole_Plugin', 'parse');\n    }\n \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate() {\n    \n    }\n\n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n\n    }\n\n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n \n \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function parse($text, $widget, $lastResult) {\n        $text = empty($lastResult) ? $text : $lastResult;\n        $creole_parse = new Creole_Wiki;\n        return $creole_parse->transform(trim($text));\n    }\n}\n"
  },
  {
    "path": "Creole/Render/Plain/Anchor.php",
    "content": "<?php\n\n/**\n* \n* This class renders an anchor target name in XHTML.\n*\n* @author Manuel Holtgrewe <purestorm at ggnore dot net>\n*\n* @author Paul M. Jones <pmjones at ciaweb dot net>\n*\n* @package Text_Wiki\n*\n*/\n\nclass Text_Wiki_Render_Plain_Anchor extends Text_Wiki_Render {\n    \n    function token($options)\n    {\n        return $options['name'];\n    }\n}\n\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Blockquote.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Blockquote extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        $type = $options['type'];\n        $level = $options['level'];\n    \n        // set up indenting so that the results look nice; we do this\n        // in two steps to avoid str_pad mathematics.  ;-)\n        $pad = str_pad('', $level + 1, \"\\t\");\n        $pad = str_replace(\"\\t\", '    ', $pad);\n        \n        // starting\n        if ($type == 'start') {\n            return \"\\n$pad\";\n        }\n        \n        // ending\n        if ($type == 'end') {\n            return \"\\n$pad\";\n        }\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Bold.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Bold extends Text_Wiki_Render {\n\n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Box.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Box rule end renderer for Plain\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Box.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders a box drawn in Plain.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Plain_Box extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return '';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Break.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Break extends Text_Wiki_Render {\n\n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return \"\\n\";\n    }\n}\n\n?>"
  },
  {
    "path": "Creole/Render/Plain/Center.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Center extends Text_Wiki_Render {\n\n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Code.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Code extends Text_Wiki_Render {\n    \n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return \"\\n\" . $options['text'] . \"\\n\\n\";\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Colortext.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Colortext extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Deflist.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Deflist extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        $type = $options['type'];\n        $pad = \"    \";\n        \n        switch ($type) {\n        \n        case 'list_start':\n            return \"\\n\";\n            break;\n        \n        case 'list_end':\n            return \"\\n\\n\";\n            break;\n        \n        case 'term_start':\n        \n            // done!\n            return $pad;\n            break;\n        \n        case 'term_end':\n            return \"\\n\";\n            break;\n        \n        case 'narr_start':\n        \n            // done!\n            return $pad . $pad;\n            break;\n        \n        case 'narr_end':\n            return \"\\n\";\n            break;\n        \n        default:\n            return '';\n        \n        }\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Delete.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Delete extends Text_Wiki_Render {\n\n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Delimiter.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Delimiter extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Embed.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Embed extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return strip_tags($options['text']);\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Emphasis.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Emphasis extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Font.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * BBCode: extra Font rules renderer to size the text\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Font.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * Font rule render class (used for BBCode)\n * \n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n * @see        Text_Wiki::Text_Wiki_Render()\n */\nclass Text_Wiki_Render_Plain_Font extends Text_Wiki_Render {\n    \n    /**\n      * Renders a token into text matching the requested format.\n      * process the font size option \n      *\n      * @access public\n      * @param array $options The \"options\" portion of the token (second element).\n      * @return string The text rendered from the token options.\n      */\n    function token($options)\n    {\n        return;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Freelink.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Freelink extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return $options['text'];\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Function.php",
    "content": "<?php\n\n// $Id: Function.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n\nclass Text_Wiki_Render_Plain_Function extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        extract($options); // access, return, name, params, throws\n        \n        $output = \"$access $return $name ( \";\n        \n        foreach ($params as $key => $val) {\n            $output .= \"{$val['type']} {$val['descr']} {$val['default']} \";\n        }\n        \n        $output .= ') ';\n        \n        foreach ($throws as $key => $val) {\n            $output .= \"{$val['type']} {$val['descr']} \";\n        }\n        \n        return $output;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Heading.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Heading extends Text_Wiki_Render {\n    \n    function token($options)\n    {\n        if ($options['type'] == 'end') {\n            return \"\\n\\n\";\n        } else {\n            return \"\\n\";\n        }\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Horiz.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Horiz extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return \"\\n\";\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Html.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Html extends Text_Wiki_Render {\n    \n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return strip_tags($options['text']);\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Image.php",
    "content": "<?php\nclass Text_Wiki_Render_Plain_Image extends Text_Wiki_Render {\n\n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Include.php",
    "content": "<?php\nclass Text_Wiki_Render_Plain_Include extends Text_Wiki_Render {    \n    function token()\n    {\n        return '';\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Interwiki.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Interwiki extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        if (isset($options['url'])) {\n            // calculated by the parser (e.g. Mediawiki)\n            $href = $options['url'];\n        } else {\n            $href = $options['site'] . ':' . $options['page'];\n        }\n        return $options['text'] . ' (' . $href . ')';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Italic.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Italic extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/List.php",
    "content": "<?php\n\n\nclass Text_Wiki_Render_Plain_List extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * This rendering method is syntactically and semantically compliant\n    * with XHTML 1.1 in that sub-lists are part of the previous list item.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        // make nice variables (type, level, count)\n        extract($options);\n        \n        // set up indenting so that the results look nice; we do this\n        // in two steps to avoid str_pad mathematics.  ;-)\n        $pad = str_pad('', $level, \"\\t\");\n        $pad = str_replace(\"\\t\", '    ', $pad);\n                \n        switch ($type) {\n        \n        case 'bullet_list_start':\n            break;\n        \n        case 'bullet_list_end':\n            if ($level == 0) {\n                return \"\\n\\n\";\n            }\n            break;\n        \n        case 'number_list_start':\n            break;\n        \n        case 'number_list_end':\n            if ($level == 0) {\n                return \"\\n\\n\";\n            }\n            break;\n        \n        case 'bullet_item_start':\n        case 'number_item_start':\n            return \"\\n$pad\";\n            break;\n        \n        case 'bullet_item_end':\n        case 'number_item_end':\n        default:\n            // ignore item endings and all other types.\n            // item endings are taken care of by the other types\n            // depending on their place in the list.\n            return;\n            break;\n        }\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Newline.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Newline extends Text_Wiki_Render {\n    \n    \n    function token($options)\n    {\n        return \"\\n\";\n    }\n}\n\n?>"
  },
  {
    "path": "Creole/Render/Plain/Page.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Page rule end renderer for Plain\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Page.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders page markers in Plain.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Plain_Page extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return \"\\x0C\";\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Paragraph.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Paragraph extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        extract($options); //type\n        \n        if ($type == 'start') {\n            return '';\n        }\n        \n        if ($type == 'end') {\n            return \"\\n\\n\";\n        }\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Phplookup.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Phplookup extends Text_Wiki_Render {\n    \n    var $conf = array('target' => '_blank');\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return trim($options['text']);\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Plugin.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Plugin rule end renderer for Plain\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Plugin.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders wiki plugins in Plain. (empty)\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Plain_Plugin extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    * Plugins produce wiki markup so are processed by parsing, no tokens produced\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return '';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Prefilter.php",
    "content": "<?php\n/* vim: set expandtab tabstop=4 shiftwidth=4: */\n// +----------------------------------------------------------------------+\n// | PHP version 4                                                        |\n// +----------------------------------------------------------------------+\n// | Copyright (c) 1997-2003 The PHP Group                                |\n// +----------------------------------------------------------------------+\n// | This source file is subject to version 2.0 of the PHP license,       |\n// | that is bundled with this package in the file LICENSE, and is        |\n// | available through the world-wide-web at                              |\n// | http://www.php.net/license/2_02.txt.                                 |\n// | If you did not receive a copy of the PHP license and are unable to   |\n// | obtain it through the world-wide-web, please send a note to          |\n// | license@php.net so we can mail you a copy immediately.               |\n// +----------------------------------------------------------------------+\n// | Authors: Paul M. Jones <pmjones@php.net>                          |\n// +----------------------------------------------------------------------+\n//\n// $Id: Prefilter.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n\n\n/**\n* \n* This class implements a Text_Wiki_Render_Xhtml to \"pre-filter\" source text so\n* that line endings are consistently \\n, lines ending in a backslash \\\n* are concatenated with the next line, and tabs are converted to spaces.\n*\n* @author Paul M. Jones <pmjones@php.net>\n*\n* @package Text_Wiki\n*\n*/\n\nclass Text_Wiki_Render_Plain_Prefilter extends Text_Wiki_Render {\n    function token()\n    {\n        return '';\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Preformatted.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Preformatted rule end renderer for Plain\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Preformatted.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders preformated text in Plain.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Plain_Preformatted extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return $options['text'];\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Raw.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Raw extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return $options['text'];\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Revise.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Revise extends Text_Wiki_Render {\n    \n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Smiley.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Smiley rule Plain renderer\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Smiley.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * Smiley rule Plain render class\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n * @see        Text_Wiki::Text_Wiki_Render()\n */\nclass Text_Wiki_Render_Plain_Smiley extends Text_Wiki_Render {\n\n    /**\n      * Renders a token into text matching the requested format.\n      * process the Smileys\n      *\n      * @access public\n      * @param array $options The \"options\" portion of the token (second element).\n      * @return string The text rendered from the token options.\n      */\n    function token($options)\n    {\n        return $options['symbol'];\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Specialchar.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Specialchar rule end renderer for Plain\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Specialchar.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders special characters in Plain.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Plain_SpecialChar extends Text_Wiki_Render {\n\n    var $types = array('~bs~' => '\\\\',\n                       '~hs~' => ' ',\n                       '~amp~' => '&',\n                       '~ldq~' => '\"',\n                       '~rdq~' => '\"',\n                       '~lsq~' => \"'\",\n                       '~rsq~' => \"'\",\n                       '~c~' => '©',\n                       '~--~' => '-',\n                       '\" -- \"' => '-',\n                       '&quot; -- &quot;' => '-',\n                       '~lt~' => '<',\n                       '~gt~' => '>');\n\n    function token($options)\n    {\n        if (isset($this->types[$options['char']])) {\n            return $this->types[$options['char']];\n        } else {\n            return $options['char'];\n        }\n    }\n}\n\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Strong.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Strong extends Text_Wiki_Render {\n    \n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Subscript.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Subscript rule end renderer for Plain\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Subscript.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders subscript text in Plain.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Plain_Subscript extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return '';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Superscript.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Superscript extends Text_Wiki_Render {\n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Table.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Table extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        // make nice variable names (type, attr, span)\n        extract($options);\n\n        $pad = '    ';\n\n        switch ($type) {\n\n        case 'table_start':\n            return;\n            break;\n\n        case 'table_end':\n            return;\n            break;\n\n        case 'caption_start':\n            return;\n            break;\n\n        case 'caption_end':\n            return \"\\n\";\n            break;\n\n        case 'row_start':\n            return;\n            break;\n\n        case 'row_end':\n            return \" ||\\n\";\n            break;\n\n        case 'cell_start':\n            return \" || \";\n            break;\n\n        case 'cell_end':\n            return;\n            break;\n\n        default:\n            return '';\n\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Tighten.php",
    "content": "<?php\nclass Text_Wiki_Render_Plain_Tighten extends Text_Wiki_Render {\n    \n    \n    function token()\n    {\n        return '';\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Titlebar.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Titlebar rule end renderer for Plain\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Titlebar.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders a title bar in Plain.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Plain_Titlebar extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            return '***** ';\n        }\n\n        if ($options['type'] == 'end') {\n            return \" *****\\n\";\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Plain/Toc.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Toc extends Text_Wiki_Render {\n    \n    \n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        // type, count, level\n        extract($options);\n        \n        if ($type == 'item_start') {\n            \n            // build some indenting spaces for the text\n            $indent = ($level - 2) * 4;\n            $pad = str_pad('', $indent);\n            return $pad;\n        }\n        \n        if ($type == 'item_end') {\n            return \"\\n\";\n        }\n    }\n\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Tt.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_tt extends Text_Wiki_Render {\n    \n    \n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Underline.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Underline extends Text_Wiki_Render {\n\n    /**\n    * \n    * Renders a token into text matching the requested format.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return;\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Url.php",
    "content": "<?php\n\n\nclass Text_Wiki_Render_Plain_Url extends Text_Wiki_Render {\n\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start' || $options['type'] == 'end') {\n            return '';\n        } else {\n            return $options['text'];\n        }\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain/Wikilink.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain_Wikilink extends Text_Wiki_Render {\n    \n    \n    /**\n    * \n    * Renders a token into plain text.\n    * \n    * @access public\n    * \n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    * \n    * @return string The text rendered from the token options.\n    * \n    */\n    \n    function token($options)\n    {\n        return $options['text'];\n    }\n}\n?>"
  },
  {
    "path": "Creole/Render/Plain.php",
    "content": "<?php\n\nclass Text_Wiki_Render_Plain extends Text_Wiki_Render {\n    \n    function pre()\n    {\n        return;\n    }\n    \n    function post()\n    {\n        return;\n    }\n    \n}\n?>"
  },
  {
    "path": "Creole/Render/Xhtml/Address.php",
    "content": "<?php\n\n/**\n *\n * Address rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n *\n * @package    Text_Wiki\n *\n * @author     Michele Tomaiuolo <tomamic@yahoo.it>\n *\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n *\n * @version    CVS: $Id: Address.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n *\n * @link       http://pear.php.net/package/Text_Wiki\n *\n */\n\nclass Text_Wiki_Render_Xhtml_Address extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<address$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</address>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Anchor.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Anchor rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Anchor.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders an anchor target name in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Anchor extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    function token($options)\n    {\n        extract($options); // $type, $name\n\n        if ($type == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            $format = \"<a$css id=\\\"%s\\\">\";\n            return sprintf($format, $this->textEncode($name));\n        }\n\n        if ($type == 'end') {\n            return '</a>';\n        }\n    }\n}\n\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Blockquote.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Blockquote rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Blockquote.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders a blockquote in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Blockquote extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $type = $options['type'];\n        $level = $options['level'];\n\n        // set up indenting so that the results look nice; we do this\n        // in two steps to avoid str_pad mathematics.  ;-)\n        $pad = str_pad('', $level, \"\\t\");\n        $pad = str_replace(\"\\t\", '    ', $pad);\n\n        // pick the css type\n        $css = $this->formatConf(' class=\"%s\"', 'css');\n\n        if (isset($options['css'])) {\n            $css = ' class=\"' . $options['css']. '\"';\n        }\n        // starting\n        if ($type == 'start') {\n            return \"$pad<blockquote$css>\";\n        }\n\n        // ending\n        if ($type == 'end') {\n            return $pad . \"</blockquote>\\n\";\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Bold.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Bold rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Bold.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders bold text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Bold extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<b$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</b>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Box.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Box rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Box.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders a box drawn in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Box extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => 'simplebox'\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            if ($options['css']) {\n                $css = ' class=\"' . $options['css']. '\"';\n            }\n            else {\n                $css = $this->formatConf(' class=\"%s\"', 'css');\n            }\n            return \"<div $css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</div>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Break.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Break rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Break.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders line breaks in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Break extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $css = $this->formatConf(' class=\"%s\"', 'css');\n        return \"<br$css />\\n\";\n    }\n}\n\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Center.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Center rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Center.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders centered content in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Center extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->getConf('css');\n            if ($css) {\n                return \"<div class=\\\"$css\\\">\";\n            }\n            else {\n                return '<div style=\"text-align: center;\">';\n            }\n        }\n\n        if ($options['type'] == 'end') {\n            return '</div>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Code.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Code rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Code.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders code blocks in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Code extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css'      => null, // class for <pre>\n        'css_code' => null, // class for generic <code>\n        'css_php'  => null, // class for PHP <code>\n        'css_html' => null, // class for HTML <code>\n        'css_filename' => null // class for optional filename <div>\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $text = $options['text'];\n        $attr = $options['attr'];\n        $type = strtolower($attr['type']);\n\n        $css      = $this->formatConf(' class=\"%s\"', 'css');\n        $css_code = $this->formatConf(' class=\"%s\"', 'css_code');\n        $css_php  = $this->formatConf(' class=\"%s\"', 'css_php');\n        $css_html = $this->formatConf(' class=\"%s\"', 'css_html');\n        $css_filename = $this->formatConf(' class=\"%s\"', 'css_filename');\n\n        if ($type == 'php') {\n            if (substr($options['text'], 0, 5) != '<?php') {\n                // PHP code example:\n                // add the PHP tags\n                $text = \"<?php\\n\" . $options['text'] . \"\\n?>\"; // <?php\n            }\n\n            // convert tabs to four spaces\n            $text = str_replace(\"\\t\", \"    \", $text);\n\n            // colorize the code block (also converts HTML entities and adds\n            // <code>...</code> tags)\n            ob_start();\n            highlight_string($text);\n            $text = ob_get_contents();\n            ob_end_clean();\n\n            // replace <br /> tags with simple newlines.\n            // replace non-breaking space with simple spaces.\n            // translate HTML <font> and color to XHTML <span> and style.\n            // courtesy of research by A. Kalin :-).\n            $map = array(\n                '<br />'  => \"\\n\",\n                '&nbsp;'  => ' ',\n                '<font'   => '<span',\n                '</font>' => '</span>',\n                'color=\"' => 'style=\"color:'\n            );\n            $text = strtr($text, $map);\n\n            // get rid of the last newline inside the code block\n            // (becuase higlight_string puts one there)\n            if (substr($text, -8) == \"\\n</code>\") {\n                $text = substr($text, 0, -8) . \"</code>\";\n            }\n\n            // replace all <code> tags with classed tags\n            if ($css_php) {\n                $text = str_replace('<code>', \"<code$css_php>\", $text);\n            }\n\n            // done\n            $text = \"<pre$css>$text</pre>\";\n\n        } elseif ($type == 'html' || $type == 'xhtml') {\n\n            // HTML code example:\n            // add <html> opening and closing tags,\n            // convert tabs to four spaces,\n            // convert entities.\n            $text = str_replace(\"\\t\", \"    \", $text);\n            $text = \"<html>\\n$text\\n</html>\";\n            $text = $this->textEncode($text);\n            $text = \"<pre$css><code$css_html>$text</code></pre>\";\n\n        } else {\n            // generic code example:\n            // convert tabs to four spaces,\n            // convert entities.\n            $text = str_replace(\"\\t\", \"    \", $text);\n            $text = $this->textEncode($text);\n            $text = \"<pre$css><code$css_code>$text</code></pre>\";\n        }\n\n        if ($css_filename && isset($attr['filename'])) {\n            $text = \"<div$css_filename>\" .\n                $attr['filename'] . '</div>' . $text;\n        }\n\n        return \"\\n$text\\n\\n\";\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Colortext.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Colortext rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Colortext.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders colored text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Colortext extends Text_Wiki_Render {\n\n    var $colors = array(\n        'aqua',\n        'black',\n        'blue',\n        'fuchsia',\n        'gray',\n        'green',\n        'lime',\n        'maroon',\n        'navy',\n        'olive',\n        'purple',\n        'red',\n        'silver',\n        'teal',\n        'white',\n        'yellow'\n    );\n\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $type = $options['type'];\n        $color = $options['color'];\n\n        if (! in_array($color, $this->colors) && $color{0} != '#') {\n            $color = '#' . $color;\n        }\n\n        if ($type == 'start') {\n            return \"<span style=\\\"color: $color;\\\">\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</span>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Deflist.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Deflist rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Deflist.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders definition lists in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Deflist extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css_dl' => null,\n        'css_dt' => null,\n        'css_dd' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $type = $options['type'];\n        $pad = \"    \";\n\n        switch ($type) {\n\n        case 'list_start':\n            $css = $this->formatConf(' class=\"%s\"', 'css_dl');\n            return \"<dl$css>\\n\";\n            break;\n\n        case 'list_end':\n            return \"</dl>\\n\\n\";\n            break;\n\n        case 'term_start':\n            $css = $this->formatConf(' class=\"%s\"', 'css_dt');\n            return $pad . \"<dt$css>\";\n            break;\n\n        case 'term_end':\n            return \"</dt>\\n\";\n            break;\n\n        case 'narr_start':\n            $css = $this->formatConf(' class=\"%s\"', 'css_dd');\n            return $pad . $pad . \"<dd$css>\";\n            break;\n\n        case 'narr_end':\n            return \"</dd>\\n\";\n            break;\n\n        default:\n            return '';\n\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Delete.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Underline rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Delete.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders underlined text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Delete extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            //$css = $this->formatConf(' class=\"%s\"', 'css');\n            //return \"<u$css>\";\n            //return \"<span style=\\\"text-decoration:underline;\\\">\";\n            return \"<del>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</del>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Delimiter.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Delimiter rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Delimiter.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class set back the replaced delimiters in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Delimiter extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return $options['text'];\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Embed.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Embed rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Embed.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class replaces the embedded php output in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Embed extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return $options['text'];\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Emphasis.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Emphasis rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Emphasis.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders emphasized text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Emphasis extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<em$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</em>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Font.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * BBCode: extra Font rules renderer to size the text\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Font.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * Font rule render class (used for BBCode)\n * \n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n * @see        Text_Wiki::Text_Wiki_Render()\n */\nclass Text_Wiki_Render_Xhtml_Font extends Text_Wiki_Render {\n    \n/*    var $size = array(\n        'xx-small',\n        'x-small',\n        'small',\n        'medium',\n        'large',\n        'x-large',\n        'xx-large',\n        'larger',\n        'smaller'\n    );\n    var $units = array(\n        'em',\n        'ex',\n        'px',\n        'in',\n        'cm',\n        'mm',\n        'pt',\n        'pc'\n    );\n*/    \n    \n    /**\n      * Renders a token into text matching the requested format.\n      * process the font size option \n      *\n      * @access public\n      * @param array $options The \"options\" portion of the token (second element).\n      * @return string The text rendered from the token options.\n      */\n    function token($options)\n    {\n        if ($options['type'] == 'end') {\n            return '</span>';\n        }\n        if ($options['type'] != 'start') {\n            return '';\n        }\n\n        $ret = '<span style=\"';\n        if (isset($options['size'])) {\n            $size = trim($options['size']);\n            if (is_numeric($size)) {\n                $size .= 'px';\n            }\n            $ret .= \"font-size: $size;\";\n        }\n        \n        return $ret.'\">';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Freelink.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Freelink rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Freelink.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * The wikilink render class.\n */\nrequire_once 'Text/Wiki/Render/Xhtml/Wikilink.php';\n\n/**\n * This class renders free links in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Freelink extends Text_Wiki_Render_Xhtml_Wikilink {\n    // renders identically to wikilinks, only the parsing is different :-)\n}\n\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Function.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Function rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Function.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders a function description in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Function extends Text_Wiki_Render {\n\n    var $conf = array(\n    \t// list separator for params and throws\n        'list_sep' => ', ',\n\n        // the \"main\" format string\n        'format_main' => '%access %return <b>%name</b> ( %params ) %throws',\n\n        // the looped format string for required params\n        'format_param' => '%type <i>%descr</i>',\n\n        // the looped format string for params with default values\n        'format_paramd' => '[%type <i>%descr</i> default %default]',\n\n        // the looped format string for throws\n        'format_throws' => '<b>throws</b> %type <i>%descr</i>'\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        extract($options); // name, access, return, params, throws\n\n        // build the baseline output\n        $output = $this->conf['format_main'];\n        $output = str_replace('%access', $this->textEncode($access), $output);\n        $output = str_replace('%return', $this->textEncode($return), $output);\n        $output = str_replace('%name', $this->textEncode($name), $output);\n\n        // build the set of params\n        $list = array();\n        foreach ($params as $key => $val) {\n\n            // is there a default value?\n            if ($val['default']) {\n                $tmp = $this->conf['format_paramd'];\n            } else {\n                $tmp = $this->conf['format_param'];\n            }\n\n            // add the param elements\n            $tmp = str_replace('%type', $this->textEncode($val['type']), $tmp);\n            $tmp = str_replace('%descr', $this->textEncode($val['descr']), $tmp);\n            $tmp = str_replace('%default', $this->textEncode($val['default']), $tmp);\n            $list[] = $tmp;\n        }\n\n        // insert params into output\n        $tmp = implode($this->conf['list_sep'], $list);\n        $output = str_replace('%params', $tmp, $output);\n\n        // build the set of throws\n        $list = array();\n        foreach ($throws as $key => $val) {\n               $tmp = $this->conf['format_throws'];\n            $tmp = str_replace('%type', $this->textEncode($val['type']), $tmp);\n            $tmp = str_replace('%descr', $this->textEncode($val['descr']), $tmp);\n            $list[] = $tmp;\n        }\n\n        // insert throws into output\n        $tmp = implode($this->conf['list_sep'], $list);\n        $output = str_replace('%throws', $tmp, $output);\n\n        // close the div and return the output\n        $output .= '</div>';\n        return \"\\n$output\\n\\n\";\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Heading.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Heading rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Heading.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders headings in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Heading extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css_h1' => null,\n        'css_h2' => null,\n        'css_h3' => null,\n        'css_h4' => null,\n        'css_h5' => null,\n        'css_h6' => null\n    );\n\n    function token($options)\n    {\n    \t$collapse = null;\n        static $jsOutput = false;\n        // get nice variable names (id, type, level)\n        extract($options);\n\n        switch($type) {\n        case 'start':\n            //$css = $this->formatConf(' class=\"%s\"', \"css_h$level\");\n            return '<h'. $level .'>';\n            //return '<h'.$level.$css.' id=\"'.$id.'\"'.($collapse !== null ? ' onclick=\"hideTOC(\\''.$id.'\\');\"' : '').'>';\n        case 'end':\n            return '</h'.$level.'>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Horiz.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Horiz rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Horiz.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders an horizontal bar in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Horiz extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $css = $this->formatConf(' class=\"%s\"', 'css');\n        return \"<hr$css />\\n\";\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Html.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Html rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Html.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders preformated html in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Html extends Text_Wiki_Render {\n\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return $options['text'];\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Image.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Image rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Image.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class inserts an image in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Image extends Text_Wiki_Render {\n\n    var $conf = array(\n        'base' => null,\n        'url_base' => null,\n        'css'  => null,\n        'css_link' => null\n    );\n\n    /**\n     *\n     * Renders a token into text matching the requested format.\n     *\n     * @access public\n     *\n     * @param array $options The \"options\" portion of the token (second\n     * element).\n     *\n     * @return string The text rendered from the token options.\n     *\n     */\n\n    function token($options)\n    {\n        // note the image source\n        $src = $options['src'];\n\n        // is the source a local file or URL?\n        if (strpos($src, '://') === false) {\n            // the source refers to a local file.\n            // add the URL base to it.\n            $src = $this->getConf('base', '/') . $src;\n        }\n\n        // stephane@metacites.net\n        // is the image clickable?\n        if (isset($options['attr']['link'])) {\n            // yes, the image is clickable.\n            // are we linked to a URL or a wiki page?\n            if (strpos($options['attr']['link'], '://')) {\n                // it's a URL, prefix the URL base\n                $href = $this->getConf('url_base') . $options['attr']['link'];\n            } else {\n                // it's a WikiPage; assume it exists.\n                /** @todo This needs to honor sprintf wikilinks (pmjones) */\n                /** @todo This needs to honor interwiki (pmjones) */\n                /** @todo This needs to honor freelinks (pmjones) */\n                $href = $this->wiki->getRenderConf('xhtml', 'wikilink', 'view_url') .\n                    $options['attr']['link'];\n            }\n        } else {\n            // image is not clickable.\n            $href = null;\n        }\n        // unset so it won't show up as an attribute\n        unset($options['attr']['link']);\n\n        // stephane@metacites.net -- 25/07/2004\n        // use CSS for all alignment\n        if (isset($options['attr']['align'])) {\n            // make sure we have a style attribute\n            if (!isset($options['attr']['style'])) {\n                // no style, set up a blank one\n                $options['attr']['style'] = '';\n            } else {\n                // style exists, add a space\n                $options['attr']['style'] .= ' ';\n            }\n\n            if ($options['attr']['align'] == 'center') {\n                // add a \"center\" style to the existing style.\n                $options['attr']['style'] .=\n                    'display: block; margin-left: auto; margin-right: auto;';\n            } else {\n                // add a float style to the existing style\n                $options['attr']['style'] .=\n                    'float: '.$options['attr']['align'];\n            }\n\n            // unset so it won't show up as an attribute\n            unset($options['attr']['align']);\n        }\n\n        // stephane@metacites.net -- 25/07/2004\n        // try to guess width and height\n        if (! isset($options['attr']['width']) &&\n            ! isset($options['attr']['height'])) {\n\n                // does the source refer to a local file or a URL?\n                if (strpos($src,'://')) {\n                    // is a URL link\n                    $imageFile = $src;\n                } elseif ($src[0] == '.') {\n                    // reg at dav-muz dot net -- 2005-03-07\n                    // is a local file on relative path.\n                    $imageFile = $src; # ...don't do anything because it's perfect!\n                } else {\n                    // is a local file on absolute path.\n                    $imageFile = $_SERVER['DOCUMENT_ROOT'] . $src;\n                }\n\n                // attempt to get the image size\n                $imageSize = @getimagesize($imageFile);\n\n                if (is_array($imageSize)) {\n                    $options['attr']['width'] = $imageSize[0];\n                    $options['attr']['height'] = $imageSize[1];\n                }\n\n            }\n\n        // start the HTML output\n        $output = '<img src=\"' . $this->textEncode($src) . '\"';\n\n        // get the CSS class but don't add it yet\n        $css = $this->formatConf(' class=\"%s\"', 'css');\n\n        // add the attributes to the output, and be sure to\n        // track whether or not we find an \"alt\" attribute\n        $alt = false;\n        foreach ($options['attr'] as $key => $val) {\n\n            // track the 'alt' attribute\n            if (strtolower($key) == 'alt') {\n                $alt = true;\n            }\n\n            // the 'class' attribute overrides the CSS class conf\n            if (strtolower($key) == 'class') {\n                $css = null;\n            }\n\n            $key = $this->textEncode($key);\n            $val = $this->textEncode($val);\n            $output .= \" $key=\\\"$val\\\"\";\n        }\n\n        // always add an \"alt\" attribute per Stephane Solliec\n        if (! $alt) {\n            $alt = $this->textEncode(basename($options['src']));\n            $output .= \" alt=\\\"$alt\\\"\";\n        }\n\n        // end the image tag with the automatic CSS class (if any)\n        $output .= \"$css />\";\n\n        // was the image clickable?\n        if ($href) {\n            // yes, add the href and return\n            $href = $this->textEncode($href);\n            $css = $this->formatConf(' class=\"%s\"', 'css_link');\n            $output = \"<a$css href=\\\"$href\\\">$output</a>\";\n        }\n\n        return $output;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Include.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Include rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Include.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders included maekup in XHTML. (empty)\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Include extends Text_Wiki_Render {\n    function token()\n    {\n        return '';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Interwiki.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Interwiki rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Interwiki.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders inter wikis links in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Interwiki extends Text_Wiki_Render {\n\n    var $conf = array(\n        'sites' => array(\n            'MeatBall' => 'http://www.usemod.com/cgi-bin/mb.pl?%s',\n            'Advogato' => 'http://advogato.org/%s',\n            'Wiki'       => 'http://c2.com/cgi/wiki?%s'\n        ),\n        'target' => '_blank',\n        'css' => null\n    );\n\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $text = $options['text'];\n        if (isset($options['url'])) {\n            // calculated by the parser (e.g. Mediawiki)\n            $href = $options['url'];\n        } else {\n            $site = $options['site'];\n            // toggg 2006/02/05 page name must be url encoded (e.g. may contain spaces)\n            $page = $this->urlEncode($options['page']);\n\n            if (isset($this->conf['sites'][$site])) {\n                $href = $this->conf['sites'][$site];\n            } else {\n                return $text;\n            }\n\n            // old form where page is at end,\n            // or new form with %s placeholder for sprintf()?\n            if (strpos($href, '%s') === false) {\n                // use the old form\n                $href = $href . $page;\n            } else {\n                // use the new form\n                $href = sprintf($href, $page);\n            }\n        }\n\n        // allow for alternative targets\n        $target = $this->getConf('target');\n\n        // build base link\n        $css = $this->formatConf(' class=\"%s\"', 'css');\n        $text = $this->textEncode($text);\n        $output = \"<a$css href=\\\"$href\\\"\";\n\n        // are we targeting a specific window?\n        if ($target && $target != '_self') {\n            // this is XHTML compliant, suggested by Aaron Kalin.\n            // code tip is actually from youngpup.net, and it\n            // uses the $target as the new window name.\n            $target = $this->textEncode($target);\n            $output .= \" onclick=\\\"window.open(this.href, '$target');\";\n            $output .= \" return false;\\\"\";\n        }\n\n        $output .= \">$text</a>\";\n\n        return $output;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Italic.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Italic rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Italic.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders italic text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Italic extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<i$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</i>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/List.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * List rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: List.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders bullet and ordered lists in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_List extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css_ol' => null,\n        'css_ol_li' => null,\n        'css_ul' => null,\n        'css_ul_li' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * This rendering method is syntactically and semantically compliant\n    * with XHTML 1.1 in that sub-lists are part of the previous list item.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        // make nice variables (type, level, count)\n        extract($options);\n\n        // set up indenting so that the results look nice; we do this\n        // in two steps to avoid str_pad mathematics.  ;-)\n        $pad = str_pad('', $level, \"\\t\");\n        $pad = str_replace(\"\\t\", '    ', $pad);\n\n        switch ($type) {\n\n        case 'bullet_list_start':\n\n            // build the base HTML\n            $css = $this->formatConf(' class=\"%s\"', 'css_ul');\n            $html = \"<ul$css>\";\n\n            /*\n            // if this is the opening block for the list,\n            // put an extra newline in front of it so the\n            // output looks nice.\n            if ($level == 0) {\n                $html = \"\\n$html\";\n            }\n            */\n\n            // done!\n            return $html;\n            break;\n\n        case 'bullet_list_end':\n\n            // build the base HTML\n            $html = \"</li>\\n$pad</ul>\";\n\n            // if this is the closing block for the list,\n            // put extra newlines after it so the output\n            // looks nice.\n            if ($level == 0) {\n                $html .= \"\\n\\n\";\n            }\n\n            // done!\n            return $html;\n            break;\n\n        case 'number_list_start':\n            if (isset($format)) {\n                $format = ' type=\"' . $format . '\"';\n            } else  {\n                $format = '';\n            }\n            // build the base HTML\n            $css = $this->formatConf(' class=\"%s\"', 'css_ol');\n            $html = \"<ol{$format}{$css}>\";\n\n            /*\n            // if this is the opening block for the list,\n            // put an extra newline in front of it so the\n            // output looks nice.\n            if ($level == 0) {\n                $html = \"\\n$html\";\n            }\n            */\n\n            // done!\n            return $html;\n            break;\n\n        case 'number_list_end':\n\n            // build the base HTML\n            $html = \"</li>\\n$pad</ol>\";\n\n            // if this is the closing block for the list,\n            // put extra newlines after it so the output\n            // looks nice.\n            if ($level == 0) {\n                $html .= \"\\n\\n\";\n            }\n\n            // done!\n            return $html;\n            break;\n\n        case 'bullet_item_start':\n        case 'number_item_start':\n\n            // pick the proper CSS class\n            if ($type == 'bullet_item_start') {\n                $css = $this->formatConf(' class=\"%s\"', 'css_ul_li');\n            } else {\n                $css = $this->formatConf(' class=\"%s\"', 'css_ol_li');\n            }\n\n            // build the base HTML\n            $html = \"\\n$pad<li$css>\";\n\n            // for the very first item in the list, do nothing.\n            // but for additional items, be sure to close the\n            // previous item.\n            if ($count > 0) {\n                $html = \"</li>$html\";\n            }\n\n            // done!\n            return $html;\n            break;\n\n        case 'bullet_item_end':\n        case 'number_item_end':\n        default:\n            // ignore item endings and all other types.\n            // item endings are taken care of by the other types\n            // depending on their place in the list.\n            return '';\n            break;\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Newline.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Newline rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Newline.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders new lines in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Newline extends Text_Wiki_Render {\n\n\n    function token($options)\n    {\n        return \"<br />\\n\";\n    }\n}\n\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Page.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Page rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Page.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders page markers in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Page extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return 'PAGE MARKER HERE*&^%$#^$%*PAGEMARKERHERE';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Paragraph.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Paragraph rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Paragraph.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders paragraphs in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Paragraph extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        extract($options); //type\n\n        if ($type == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<p$css>\";\n        }\n\n        if ($type == 'end') {\n            return \"</p>\\n\\n\";\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Phplookup.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Phplookup rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Phplookup.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders a link to php functions description in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Phplookup extends Text_Wiki_Render {\n\n    var $conf = array(\n        'target' => '_blank',\n        'css' => null\n    );\n\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $text = trim($options['text']);\n        $css = $this->formatConf(' class=\"%s\"', 'css');\n\n        // start the html\n        $output = \"<a$css\";\n\n        // are we targeting another window?\n        $target = $this->getConf('target', '');\n        if ($target && $target != '_self') {\n            // use a \"popup\" window.  this is XHTML compliant, suggested by\n            // Aaron Kalin.  uses the $target as the new window name.\n            $target = $this->textEncode($target);\n            $output .= \" onclick=\\\"window.open(this.href, '$target');\";\n            $output .= \" return false;\\\"\";\n        }\n\n        // take off the final parens for functions\n        if (substr($text, -2) == '()') {\n            $q = substr($text, 0, -2);\n        } else {\n            $q = $text;\n        }\n\n        // toggg 2006/02/05 page name must be url encoded (e.g. may contain spaces)\n        $q = $this->urlEncode($q);\n        $text = $this->textEncode($text);\n\n        // finish and return\n        $output .= \" href=\\\"http://php.net/$q\\\">$text</a>\";\n        return $output;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Plugin.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Plugin rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Plugin.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders wiki plugins in XHTML. (empty)\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Plugin extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    * Plugins produce wiki markup so are processed by parsing, no tokens produced\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return '';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Prefilter.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Prefilter rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Prefilter.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class implements a Text_Wiki_Render_Xhtml to \"pre-filter\" source text so\n * that line endings are consistently \\n, lines ending in a backslash \\\n * are concatenated with the next line, and tabs are converted to spaces.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Prefilter extends Text_Wiki_Render {\n    function token()\n    {\n        return '';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Preformatted.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Preformatted rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Preformatted.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders preformated text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Preformatted extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        $text = $this->textEncode($options['text']);\n        return '<pre>'.$text.'</pre>';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Raw.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Raw rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Raw.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders not processed blocks in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Raw extends Text_Wiki_Render {\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        return $this->textEncode($options['text']);\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Revise.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Revise rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Revise.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders revision marks in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Revise extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css_ins' => null,\n        'css_del' => null\n    );\n\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'del_start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css_del');\n            return \"<del$css>\";\n        }\n\n        if ($options['type'] == 'del_end') {\n            return \"</del>\";\n        }\n\n        if ($options['type'] == 'ins_start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css_ins');\n            return \"<ins$css>\";\n        }\n\n        if ($options['type'] == 'ins_end') {\n            return \"</ins>\";\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Smiley.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Smiley rule Xhtml renderer\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Smiley.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * Smiley rule Xhtml render class\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Bertrand Gugger <bertrand@toggg.com>\n * @copyright  2005 bertrand Gugger\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n * @see        Text_Wiki::Text_Wiki_Render()\n */\nclass Text_Wiki_Render_Xhtml_Smiley extends Text_Wiki_Render {\n\n    /**\n     * Configuration keys for this rule\n     * 'prefix' => the path to smileys images inclusive file name prefix,\n     *             starts with '/' ==> abolute reference\n     *             if no file names prefix but some folder, terminates with '/'\n     * 'extension' => the file extension (inclusive '.'), e.g. :\n     *       if prefix 'smileys/icon_' and extension '.gif'\n     *       ':)' whose name is 'smile' will give relative file 'smileys/icon_smile.gif'\n     *       if prefix '/image/smileys/' and extension '.png': absolute '/image/smileys/smile.gif'\n     * 'css' => optional style applied to smileys\n     *\n     * @access public\n     * @var array 'config-key' => mixed config-value\n     */\n    var $conf = array(\n        'prefix' => 'images/smiles/icon_',\n        'extension' => '.gif',\n        'css' => null\n    );\n\n    /**\n      * Renders a token into text matching the requested format.\n      * process the Smileys\n      *\n      * @access public\n      * @param array $options The \"options\" portion of the token (second element).\n      * @return string The text rendered from the token options.\n      */\n    function token($options)\n    {\n        $imageFile = $this->getConf('prefix') . $options['name'] . $this->getConf('extension');\n\n        // attempt to get the image size\n        $imageSize = @getimagesize($imageFile);\n\n        // return the HTML output\n        return '<img src=\"' . $this->textEncode($imageFile) . '\"' .\n            (is_array($imageSize) ?\n                ' width=\"' . $imageSize[0] . '\" height=\"' . $imageSize[1] .'\"' : '') .\n            ' alt=\"' . $options['desc'] . '\"' .\n            $this->formatConf(' class=\"%s\"', 'css') . ' />';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Specialchar.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Specialchar rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Specialchar.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders special characters in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_SpecialChar extends Text_Wiki_Render {\n\n    var $types = array('~bs~' => '&#92;',\n                       '~hs~' => '&nbsp;',\n                       '~amp~' => '&amp;',\n                       '~ldq~' => '&ldquo;',\n                       '~rdq~' => '&rdquo;',\n                       '~lsq~' => '&lsquo;',\n                       '~rsq~' => '&rsquo;',\n                       '~c~' => '&copy;',\n                       '~--~' => '&mdash;',\n                       '\" -- \"' => '&mdash;',\n                       '&quot; -- &quot;' => '&mdash;',\n                       '~lt~' => '&lt;',\n                       '~gt~' => '&gt;');\n\n    function token($options)\n    {\n        if (isset($this->types[$options['char']])) {\n            return $this->types[$options['char']];\n        } else {\n            return '&#'.substr($options['char'], 1, -1).';';\n        }\n    }\n}\n\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Strong.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Strong rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Strong.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders text marked as strong in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Strong extends Text_Wiki_Render {\n\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<strong$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</strong>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Subscript.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Subscript rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Subscript.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders subscript text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Subscript extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<sub$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</sub>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Superscript.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Superscript rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Superscript.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders superscript text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Superscript extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<sup$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</sup>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Table.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Table rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Table.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders tables in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Table extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css_table' => null,\n        'css_caption' => null,\n        'css_tr' => null,\n        'css_th' => null,\n        'css_td' => null\n    );\n\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        // make nice variable names (type, attr, span)\n        $span = $rowspan = 1;\n        extract($options);\n\n        // free format\n        $format = isset($format) ? ' '. $format : '';\n\n        $pad = '    ';\n\n        switch ($type) {\n\n        case 'table_start':\n            $css = $this->formatConf(' class=\"%s\"', 'css_table');\n            return \"\\n\\n<table$css$format>\\n\";\n            break;\n\n        case 'table_end':\n            return \"</table>\\n\\n\";\n            break;\n\n        case 'caption_start':\n            $css = $this->formatConf(' class=\"%s\"', 'css_caption');\n            return \"<caption$css$format>\\n\";\n            break;\n\n        case 'caption_end':\n            return \"</caption>\\n\";\n            break;\n\n        case 'row_start':\n            $css = $this->formatConf(' class=\"%s\"', 'css_tr');\n            return \"$pad<tr$css$format>\\n\";\n            break;\n\n        case 'row_end':\n            return \"$pad</tr>\\n\";\n            break;\n\n        case 'cell_start':\n\n            // base html\n            $html = $pad . $pad;\n\n            // is this a TH or TD cell?\n            if ($attr == 'header') {\n                // start a header cell\n                $css = $this->formatConf(' class=\"%s\"', 'css_th');\n                $html .= \"<th$css\";\n            } else {\n                // start a normal cell\n                $css = $this->formatConf(' class=\"%s\"', 'css_td');\n                $html .= \"<td$css\";\n            }\n\n            // add the column span\n            if ($span > 1) {\n                $html .= \" colspan=\\\"$span\\\"\";\n            }\n\n            // add the row span\n            if ($rowspan > 1) {\n                $html .= \" rowspan=\\\"$rowspan\\\"\";\n            }\n\n            // add alignment\n            if ($attr != 'header' && $attr != '') {\n                $html .= \" style=\\\"text-align: $attr;\\\"\";\n            }\n\n            // done!\n            $html .= \"$format>\";\n            return $html;\n            break;\n\n        case 'cell_end':\n            if ($attr == 'header') {\n                return \"</th>\\n\";\n            } else {\n                return \"</td>\\n\";\n            }\n            break;\n\n        default:\n            return '';\n\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Tighten.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Tighten rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Tighten.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class makes the tightening in XHTML. (empty)\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Tighten extends Text_Wiki_Render {\n\n\n    function token()\n    {\n        return '';\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Titlebar.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Titlebar rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Titlebar.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders a title bar in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Titlebar extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => 'titlebar'\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<div$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</div>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Toc.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Toc rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Toc.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class inserts a table of content in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Toc extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css_list' => null,\n        'css_item' => null,\n        'title' => '<strong>Table of Contents</strong>',\n        'div_id' => 'toc',\n        'collapse' => true\n    );\n\n    var $min = 2;\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        // type, id, level, count, attr\n        extract($options);\n\n        switch ($type) {\n\n        case 'list_start':\n\n            $css = $this->getConf('css_list');\n            $html = '';\n\n            // collapse div within a table?\n            if ($this->getConf('collapse')) {\n                $html .= '<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">';\n                $html .= \"<tr><td>\\n\";\n            }\n\n            // add the div, class, and id\n            $html .= '<div';\n            if ($css) {\n                $html .= \" class=\\\"$css\\\"\";\n            }\n\n            $div_id = $this->getConf('div_id');\n            if ($div_id) {\n                $html .= \" id=\\\"$div_id\\\"\";\n            }\n\n            // add the title, and done\n            $html .= '>';\n            $html .= $this->getConf('title');\n            return $html;\n            break;\n\n        case 'list_end':\n        \tif ($this->getConf('collapse')) {\n        \t    return \"\\n</div>\\n</td></tr></table>\\n\\n\";\n        \t} else {\n                return \"\\n</div>\\n\\n\";\n            }\n            break;\n\n        case 'item_start':\n            $html = \"\\n\\t<div\";\n\n            $css = $this->getConf('css_item');\n            if ($css) {\n                $html .= \" class=\\\"$css\\\"\";\n            }\n\n            $pad = ($level - $this->min);\n            $html .= \" style=\\\"margin-left: {$pad}em;\\\">\";\n\n            $html .= \"<a href=\\\"#$id\\\">\";\n            return $html;\n            break;\n\n        case 'item_end':\n            return \"</a></div>\";\n            break;\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Tt.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Tt rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Tt.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders monospaced text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Tt extends Text_Wiki_Render {\n\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            $css = $this->formatConf(' class=\"%s\"', 'css');\n            return \"<tt$css>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</tt>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Underline.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Underline rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Underline.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders underlined text in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Underline extends Text_Wiki_Render {\n\n    var $conf = array(\n        'css' => null\n    );\n\n    /**\n    *\n    * Renders a token into text matching the requested format.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n    function token($options)\n    {\n        if ($options['type'] == 'start') {\n            //$css = $this->formatConf(' class=\"%s\"', 'css');\n            //return \"<u$css>\";\n            //return \"<span style=\\\"text-decoration:underline;\\\">\";\n            return \"<ins>\";\n        }\n\n        if ($options['type'] == 'end') {\n            return '</ins>';\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Url.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Url rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Url.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders URL links in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Url extends Text_Wiki_Render {\n    var $conf = array(\n        //'target' => '_blank',\n        'images' => true,\n        'img_ext' => array('jpg', 'jpeg', 'gif', 'png'),\n        'css_inline' => null,\n        //'css_footnote' => null,\n        //'css_descr' => null,\n        //'css_img' => null\n    );\n\n    /**\n     *\n     * Renders a token into text matching the requested format.\n     *\n     * @access public\n     *\n     * @param array $options The \"options\" portion of the token (second\n     * element).\n     *\n     * @return string The text rendered from the token options.\n     *\n     */\n\n    function token($options)\n    {\n        // create local variables from the options array (text,\n        // href, type)\n        extract($options);\n\n        // find the rightmost dot and determine the filename\n        // extension.\n        $pos = strrpos($href, '.');\n        $ext = strtolower(substr($href, $pos + 1));\n        $href = $this->textEncode($href);\n\n        // does the filename extension indicate an image file?\n        if ($this->getConf('images') &&\n            in_array($ext, $this->getConf('img_ext', array()))) {\n\n                // create alt text for the image\n                if (! isset($text) || $text == '') {\n                    $text = basename($href);\n                    $text = $this->textEncode($text);\n                }\n\n                // generate an image tag\n                //              $css = $this->formatConf(' class=\"%s\"', 'css_img');\n                $start = \"<img src=\\\"$href\\\" alt=\\\"$text\\\" title=\\\"$text\\\" />\"; //\"<!-- \";\n                //$end = \" -->\";\n                $end = \"\";\n                $text = \"\"; // cancel by feelinglucky\n\n            } else {\n\n                // should we build a target clause?\n                if ($href{0} == '#' ||\n                    strtolower(substr($href, 0, 7)) == 'mailto:') {\n                        // targets not allowed for on-page anchors\n                        // and mailto: links.\n                        $target = '';\n                    } else {\n                        // allow targets on non-anchor non-mailto links\n                        $target = $this->getConf('target');\n                    }\n\n                // generate a regular link (not an image)\n                $text = $this->textEncode($text);\n                //$css = $this->formatConf(' class=\"%s\"', \"css_$type\");\n                $start = \"<a href=\\\"$href\\\" title=\\\"$href\\\"\";\n\n                /**\n                if ($target && $target != '_self') {\n                    // use a \"popup\" window.  this is XHTML compliant, suggested by\n                    // Aaron Kalin.  uses the $target as the new window name.\n                    $target = $this->textEncode($target);\n                    $start .= \" onclick=\\\"window.open(this.href, '$target');\";\n                    $start .= \" return false;\\\"\";\n                }\n                 */\n\n                /*\n                if (isset($name)) {\n                    $start .= \" id=\\\"$name\\\"\";\n                }\n                 */\n\n                // finish up output\n                $start .= \">\";\n                $end = \"</a>\";\n\n                // make numbered references look like footnotes when no\n                // CSS class specified, make them superscript by default\n                /*\n                if ($type == 'footnote' && ! $css) {\n                    $start = '<sup>' . $start;\n                    $end = $end . '</sup>';\n                }\n                 */\n            }\n\n        if ($options['type'] == 'start') {\n            $output = $start;\n        } else if ($options['type'] == 'end') {\n            $output = $end;\n        } else {\n            $output = $start . $text . $end;\n        }\n\n        return $output;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml/Wikilink.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Wikilink rule end renderer for Xhtml\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Wikilink.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * This class renders wiki links in XHTML.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml_Wikilink extends Text_Wiki_Render {\n\n    var $conf = array(\n        'pages' => array(), // set to null or false to turn off page checks\n        'view_url' => 'http://example.com/index.php?page=%s',\n        'new_url'  => 'http://example.com/new.php?page=%s',\n        'new_text' => '?',\n        'new_text_pos' => 'after', // 'before', 'after', or null/false\n        'css' => null,\n        'css_new' => null,\n        'exists_callback' => null // call_user_func() callback\n    );\n\n\n    /**\n    *\n    * Renders a token into XHTML.\n    *\n    * @access public\n    *\n    * @param array $options The \"options\" portion of the token (second\n    * element).\n    *\n    * @return string The text rendered from the token options.\n    *\n    */\n\n    function token($options)\n    {\n        // make nice variable names (page, anchor, text)\n        extract($options);\n\n        // is there a \"page existence\" callback?\n        // we need to access it directly instead of through\n        // getConf() because we'll need a reference (for\n        // object instance method callbacks).\n        if (isset($this->conf['exists_callback'])) {\n            $callback =& $this->conf['exists_callback'];\n        } else {\n        \t$callback = false;\n        }\n\n        if ($callback) {\n            // use the callback function\n            $exists = call_user_func($callback, $page);\n        } else {\n            // no callback, go to the naive page array.\n            $list = $this->getConf('pages');\n            if (is_array($list)) {\n                // yes, check against the page list\n                $exists = in_array($page, $list);\n            } else {\n                // no, assume it exists\n                $exists = true;\n            }\n        }\n\n        $anchor = '#'.$this->urlEncode(substr($anchor, 1));\n\n        // does the page exist?\n        if ($exists) {\n\n            // PAGE EXISTS.\n\n            // link to the page view, but we have to build\n            // the HREF.  we support both the old form where\n            // the page always comes at the end, and the new\n            // form that uses %s for sprintf()\n            $href = $this->getConf('view_url');\n\n            if (strpos($href, '%s') === false) {\n                // use the old form (page-at-end)\n                $href = $href . $this->urlEncode($page) . $anchor;\n            } else {\n                // use the new form (sprintf format string)\n                $href = sprintf($href, $this->urlEncode($page)) . $anchor;\n            }\n\n            // get the CSS class and generate output\n            $css = ' class=\"'.$this->textEncode($this->getConf('css')).'\"';\n\n            $start = '<a'.$css.' href=\"'.$this->textEncode($href).'\">';\n            $end = '</a>';\n        } else {\n\n            // PAGE DOES NOT EXIST.\n\n            // link to a create-page url, but only if new_url is set\n            $href = $this->getConf('new_url', null);\n\n            // set the proper HREF\n            if (! $href || trim($href) == '') {\n\n                // no useful href, return the text as it is\n                //TODO: This is no longer used, need to look closer into this branch\n                $output = $text;\n\n            } else {\n\n                // yes, link to the new-page href, but we have to build\n                // it.  we support both the old form where\n                // the page always comes at the end, and the new\n                // form that uses sprintf()\n                if (strpos($href, '%s') === false) {\n                    // use the old form\n                    $href = $href . $this->urlEncode($page);\n                } else {\n                    // use the new form\n                    $href = sprintf($href, $this->urlEncode($page));\n                }\n            }\n\n            // get the appropriate CSS class and new-link text\n            $css = ' class=\"'.$this->textEncode($this->getConf('css_new')).'\"';\n            $new = $this->getConf('new_text');\n\n            // what kind of linking are we doing?\n            $pos = $this->getConf('new_text_pos');\n            if (! $pos || ! $new) {\n                // no position (or no new_text), use css only on the page name\n\n                $start = '<a'.$css.' href=\"'.$this->textEncode($href).'\">';\n                $end = '</a>';\n            } elseif ($pos == 'before') {\n                // use the new_text BEFORE the page name\n                $start = '<a'.$css.' href=\"'.$this->textEncode($href).'\">'.$this->textEncode($new).'</a>';\n                $end = '';\n            } else {\n                // default, use the new_text link AFTER the page name\n                $start = '';\n                $end = '<a'.$css.' href=\"'.$this->textEncode($href).'\">'.$this->textEncode($new).'</a>';\n            }\n        }\n        if (!strlen($text)) {\n            $start .= $this->textEncode($page);\n        }\n        if (isset($type)) {\n            switch ($type) {\n            case 'start':\n                $output = $start;\n                break;\n            case 'end':\n                $output = $end;\n                break;\n            }\n        } else {\n            $output = $start.$this->textEncode($text).$end;\n        }\n        return $output;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render/Xhtml.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Format class for the Xhtml rendering\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Xhtml.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * Format class for the Xhtml rendering\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render_Xhtml extends Text_Wiki_Render {\n\n    var $conf = array(\n        'translate' => HTML_ENTITIES,\n        'quotes'    => ENT_COMPAT,\n        //'charset'   => 'ISO-8859-1'\n        'charset'   => 'UTF-8'\n    );\n\n    function pre()\n    {\n        $this->wiki->source = $this->textEncode($this->wiki->source);\n    }\n\n    function post()\n    {\n        return;\n    }\n\n\n    /**\n     * Method to render text\n     *\n     * @access public\n     * @param string $text the text to render\n     * @return rendered text\n     *\n     */\n\n    function textEncode($text)\n    {\n        // attempt to translate HTML entities in the source.\n        // get the config options.\n        $type = $this->getConf('translate', HTML_ENTITIES);\n        $quotes = $this->getConf('quotes', ENT_COMPAT);\n        //$charset = $this->getConf('charset', 'ISO-8859-1');\n        $charset = $this->getConf('charset', 'UTF-8');\n\n        // have to check null and false because HTML_ENTITIES is a zero\n        if ($type === HTML_ENTITIES) {\n\n            // keep a copy of the translated version of the delimiter\n            // so we can convert it back.\n            $new_delim = htmlentities($this->wiki->delim, $quotes, $charset);\n\n            // convert the entities.  we silence the call here so that\n            // errors about charsets don't pop up, per counsel from\n            // Jan at Horde.  (http://pear.php.net/bugs/bug.php?id=4474)\n            $text = @htmlentities(\n                $text,\n                $quotes,\n                $charset\n            );\n\n            // re-convert the delimiter\n            $text = str_replace(\n                $new_delim, $this->wiki->delim, $text\n            );\n\n        } elseif ($type === HTML_SPECIALCHARS) {\n\n            // keep a copy of the translated version of the delimiter\n            // so we can convert it back.\n            $new_delim = htmlspecialchars($this->wiki->delim, $quotes,\n                $charset);\n\n            // convert the entities.  we silence the call here so that\n            // errors about charsets don't pop up, per counsel from\n            // Jan at Horde.  (http://pear.php.net/bugs/bug.php?id=4474)\n            $text = @htmlspecialchars(\n                $text,\n                $quotes,\n                $charset\n            );\n\n            // re-convert the delimiter\n            $text = str_replace(\n                $new_delim, $this->wiki->delim, $text\n            );\n        }\n        return $text;\n    }\n}\n?>\n"
  },
  {
    "path": "Creole/Render.inc.php",
    "content": "<?php\n// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:\n/**\n * Base rendering class for parsed and tokenized text.\n *\n * PHP versions 4 and 5\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    CVS: $Id: Render.inc.php 182 2008-09-14 15:56:00Z i.feelinglucky $\n * @link       http://pear.php.net/package/Text_Wiki\n */\n\n/**\n * Base rendering class for parsed and tokenized text.\n *\n * @category   Text\n * @package    Text_Wiki\n * @author     Paul M. Jones <pmjones@php.net>\n * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1\n * @version    Release: @package_version@\n * @link       http://pear.php.net/package/Text_Wiki\n */\nclass Text_Wiki_Render {\n\n\n    /**\n    *\n    * Configuration options for this render rule.\n    *\n    * @access public\n    *\n    * @var string\n    *\n    */\n\n    var $conf = array();\n\n\n    /**\n    *\n    * The name of this rule's format.\n    *\n    * @access public\n    *\n    * @var string\n    *\n    */\n\n    var $format = null;\n\n\n    /**\n    *\n    * The name of this rule's token array elements.\n    *\n    * @access public\n    *\n    * @var string\n    *\n    */\n\n    var $rule = null;\n\n\n    /**\n    *\n    * A reference to the calling Text_Wiki object.\n    *\n    * This is needed so that each rule has access to the same source\n    * text, token set, URLs, interwiki maps, page names, etc.\n    *\n    * @access public\n    *\n    * @var object\n    */\n\n    var $wiki = null;\n\n\n    /**\n    *\n    * Constructor for this render format or rule.\n    *\n    * @access public\n    *\n    * @param object &$obj The calling \"parent\" Text_Wiki object.\n    *\n    */\n\n    function Text_Wiki_Render(&$obj)\n    {\n        // keep a reference to the calling Text_Wiki object\n        $this->wiki =& $obj;\n\n        // get the config-key-name for this object,\n        // strip the Text_Wiki_Render_ part\n        //           01234567890123456\n        $tmp = get_class($this);\n        $tmp = substr($tmp, 17);\n\n        // split into pieces at the _ mark.\n        // first part is format, second part is rule.\n        $part   = explode('_', $tmp);\n        $this->format = isset($part[0]) ? ucwords(strtolower($part[0])) : null;\n        $this->rule   = isset($part[1]) ? ucwords(strtolower($part[1])) : null;\n\n        // is there a format but no rule?\n        // then this is the \"main\" render object, with\n        // pre() and post() methods.\n        if ($this->format && ! $this->rule &&\n            isset($this->wiki->formatConf[$this->format]) &&\n            is_array($this->wiki->formatConf[$this->format])) {\n\n            // this is a format render object\n            $this->conf = array_merge(\n                $this->conf,\n                $this->wiki->formatConf[$this->format]\n            );\n\n        }\n\n        // is there a format and a rule?\n        if ($this->format && $this->rule &&\n            isset($this->wiki->renderConf[$this->format][$this->rule]) &&\n            is_array($this->wiki->renderConf[$this->format][$this->rule])) {\n\n            // this is a rule render object\n            $this->conf = array_merge(\n                $this->conf,\n                $this->wiki->renderConf[$this->format][$this->rule]\n            );\n        }\n    }\n\n\n    /**\n    *\n    * Simple method to safely get configuration key values.\n    *\n    * @access public\n    *\n    * @param string $key The configuration key.\n    *\n    * @param mixed $default If the key does not exist, return this value\n    * instead.\n    *\n    * @return mixed The configuration key value (if it exists) or the\n    * default value (if not).\n    *\n    */\n\n    function getConf($key, $default = null)\n    {\n        if (isset($this->conf[$key])) {\n            return $this->conf[$key];\n        } else {\n            return $default;\n        }\n    }\n\n\n    /**\n    *\n    * Simple method to wrap a configuration in an sprintf() format.\n    *\n    * @access public\n    *\n    * @param string $key The configuration key.\n    *\n    * @param string $format The sprintf() format string.\n    *\n    * @return mixed The formatted configuration key value (if it exists)\n    * or null (if it does not).\n    *\n    */\n\n    function formatConf($format, $key)\n    {\n        if (isset($this->conf[$key])) {\n            //$this->conf[$key] needs a textEncode....at least for Xhtml output...\n            return sprintf($format, $this->conf[$key]);\n        } else {\n            return null;\n        }\n    }\n\n    /**\n    * Default method to render url\n    *\n    * @access public\n    * @param string $urlChunk a part of an url to render\n    * @return rendered url\n    *\n    */\n\n    function urlEncode($urlChunk)\n    {\n        return rawurlencode($urlChunk);\n    }\n\n    /**\n    * Default method to render text (htmlspecialchars)\n    *\n    * @access public\n    * @param string $text the text to render\n    * @return rendered text\n    *\n    */\n\n    function textEncode($text)\n    {\n        return htmlspecialchars($text);\n    }\n}\n?>\n"
  },
  {
    "path": "FlashMp3Player/Plugin.php",
    "content": "<?php\n/**\n * 小巧的mp3播放器,在编辑器代码模式下使用<strong>&lt;mp3&gt;http://...&lt;/mp3&gt;</strong>的格式来添加一个音乐播放器\n * \n * @package Dewplayer\n * @author qining\n * @version 1.0.1\n * @dependence 9.9.2-*\n * @link http://typecho.org\n */\nclass FlashMp3Player_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {        \n        //离线浏览器都是所见即所得模式\n        Typecho_Plugin::factory('Widget_XmlRpc')->fromOfflineEditor = array('FlashMp3Player_Plugin', 'toCodeEditor');\n        \n        /** 前端输出处理接口 */\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('FlashMp3Player_Plugin', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('FlashMp3Player_Plugin', 'parse');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 将伪可视化代码转化为可视化代码\n     * \n     * @access public\n     * @param string $content 需要处理的内容\n     * @return string\n     */\n    public static function toVisualEditor($content)\n    {\n        $swfUrl = Typecho_Common::url('FlashMp3Player/swf/dewplayer.swf', Helper::options()->pluginUrl);\n        return preg_replace(\"/<(mp3)>(.*?)<\\/\\\\1>/is\", \n        \"<object class=\\\"typecho-plugin\\\" type=\\\"application/x-shockwave-flash\\\" data=\\\"{$swfUrl}?mp3=\\\\2\\\" width=\\\"200\\\" height=\\\"20\\\">\n<param name=\\\"movie\\\" value=\\\"{$swfUrl}?mp3=\\\\2\\\" />\n</object>\",\n        $content);\n    }\n    \n    /**\n     * 将可视化代码转化为伪可视化代码\n     * \n     * @access public\n     * @param string $content 需要处理的内容\n     * @return string\n     */\n    public static function toCodeEditor($content)\n    {\n        $swfUrl = preg_quote(Typecho_Common::url('FlashMp3Player/swf/dewplayer.swf', Helper::options()->pluginUrl), \"/\");\n        return preg_replace(\"/<(object)[^>]*data=\\\"{$swfUrl}\\?mp3\\=([^\\\">]+)\\\"[^>]*>(.*?)<\\/\\\\1>/is\", \"<mp3>\\\\2</mp3>\", $content);\n    }\n    \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function parse($text, $widget, $lastResult)\n    {\n        $text = empty($lastResult) ? $text : $lastResult;\n        \n        if ($widget instanceof Widget_Archive) {\n            $swfUrl = Typecho_Common::url('FlashMp3Player/swf/dewplayer.swf', Helper::options()->pluginUrl);\n            $text = preg_replace(\"/<(mp3)>(.*?)<\\/\\\\1>/is\", \n            \"<object class=\\\"typecho-plugin\\\" type=\\\"application/x-shockwave-flash\\\" data=\\\"{$swfUrl}?mp3=\\\\2\\\" width=\\\"200\\\" height=\\\"20\\\">\n<param name=\\\"movie\\\" value=\\\"{$swfUrl}?mp3=\\\\2\\\" />\n</object>\",\n            $text);\n        }\n        \n        return $text;\n    }\n}\n"
  },
  {
    "path": "GitHubGit/Action.php",
    "content": "<?php\n\nrequire_once \"Spyc.php\";\n\nclass GitHubGit_Action extends Widget_Abstract_Contents implements Widget_Interface_Do\n{\n\n    public function action()\n    {\n\n      $get_payload = function () {\n      \n      /** get added files\n\n          GitHub webhooks\n          https://help.github.com/articles/post-receive-hooks        \n      **/\n\n        $payload = ltrim(urldecode(file_get_contents('php://input')), 'payload='); \n        $data = json_decode($payload, true); //without `true`, json_decode will return object instead of array\n        return $data;\n      };\n\n      $data = $get_payload();\n\n\n      $get_added_files = function ($data) {\n      \n        $commits = $data['commits'];\n        foreach ($commits as $commit) {\n          foreach ($commit['added'] as $added_file) {\n            if (preg_match('#^_posts/#', $added_file)) {\n              $added_files[] = $added_file;\n            }\n          }\n        }\n\n        return $added_files;\n      };\n\n      $added_files = $get_added_files($data);\n\n\n      $get_repository_url = function ($data) {\n        return $repository_url = $data['repository']['url'];\n      };\n\n      $repository_prefix = preg_replace('#https://#', 'https://raw.', $get_repository_url($data));\n\n\n      $login = function () {\n            $master = $this->db->fetchRow($this->db->select()->from('table.users')\n                ->where('group = ?', 'administrator')\n                ->order('uid', Typecho_Db::SORT_ASC)\n                ->limit(1));\n            \n            if (empty($master)) {\n                return false;\n            } else if (!$this->user->simpleLogin($master['uid'])) {\n                return false;\n            }\n      \n      };\n\n      \n      $prepare_post = function ($to_post_file) use ($login, $repository_prefix) {\n            $input = array(\n                'do'            =>  'publish',\n                'allowComment'  =>  $this->options->defaultAllowComment,\n                'allowPing'     =>  $this->options->defaultAllowPing,\n                'allowFeed'     =>  $this->options->defaultAllowFeed\n            );\n\n            list($slug) = explode('.', basename($to_post_file));\n            $input['slug'] = $slug;\n\n            $post = $this->db->fetchRow($this->db->select()\n            ->from('table.contents')->where('slug = ?', $slug)->limit(1));\n            if (!empty($post)) {\n                if ('post' != $post['type']) {\n                    return false;\n                } else {\n                    $input['cid'] = $post['cid'];\n                }\n            }\n            \n            $url = $repository_prefix . '/master/' . $to_post_file;\n            $post_text = file_get_contents($url);\n            $post_text_array = Spyc::YAMLLoad($post_text);\n            \n            $post_sections = preg_split('/^---$/m', $post_text, 2, PREG_SPLIT_NO_EMPTY);\n            if (sizeof($post_sections) == 2) {\n              $post_body = $post_sections[1];\n            } else {\n              $post_body = $post_sections[0];\n            }\n\n            $input['title'] = $post_text_array['title'] ?: pathinfo($to_post_file)['filename'];\n            $input['category']  = $post_text_array['category'] ?: 'default';\n            $input['tags'] = implode(',', explode(' ', $post_text_array['tags'])) ?: '';\n            $input['text'] = MarkdownExtraExtended::defaultTransform($post_body);\n\n            return $input;\n      };\n\n      $post_to_typecho = function ($input) {\n            if ($input) {\n              // It seems that only the first added file get published.\n              $this->widget('Widget_Contents_Post_Edit', NULL, $input, false)->action();\n            }\n      };\n      \n\n      if (isset($added_files) && is_array($added_files)) {\n        $login();\n        foreach ($added_files as $to_post_file) {\n          $post_to_typecho($prepare_post($to_post_file));  \n        }\n      }   \n    }\n}\n"
  },
  {
    "path": "GitHubGit/Plugin.php",
    "content": "<?php\n/**\n * GitHub git 同步文章\n * \n * @package GitHub Git Transmit\n * @author weakish\n * @version 0.0.1\n * @dependence 10.6.24-*\n * @link http://typecho.org\n */\nclass GitHubGit_Plugin implements Typecho_Plugin_Interface\n{\n    // Use your own random code.\n    // Keep your code secret!\n    // Anyone knowing the code can post articles on your blog!\n    const github_git = 'curtseyingpiddlesMiguelyeshivahsclarinettists';\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        if (false == Typecho_Http_Client::get()) {\n            throw new Typecho_Plugin_Exception(_t('对不起, 您的主机不支持 php-curl 扩展而且没有打开 allow_url_fopen 功能, 无法正常使用此功能'));\n        }\n    \n        Helper::addAction(github_git, 'GitHubGit_Action');\n        return _t('安装成功') . $error;\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate()\n    {\n        Helper::removeAction(github_git);\n    }\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n}\n\n"
  },
  {
    "path": "GitHubGit/README.md",
    "content": "Configuration\n-------------\n\n### configure security code\n\nOpen `Plugin.php` in your editor, find this line:\n\n```php\nconst github_git = 'curtseyingpiddlesMiguelyeshivahsclarinettists'    ;\n```\n\nChange `github_git` value to something else.\n\nYou can make up anything you like, but please use a long and hard to guess one.\n\nIf the value of `github_git` be guessed by someone else, they can post articles to your blog, if they know how to add GitHub web hooks.\n\nAfter editing, save `Plugin.php`.\n\n### setup GitHub web hook\n\nIn your repository, click `Settings` -> `Service Hooks` -> `WebHook URLs`, add the action url, e.g.\n\n```\nhttp://typecho.example.com/action/curtseyingpiddlesMiguelyeshivahsclarinettists\n```\n\nInstall\n-------\n\nSame as other typecho plugins.\n\nThat is:\n\n- Upload the `GitHubGit` diretory to `usr/plugins` of your typecho directory.\n- Enable the plugin at your dashboard.\n\nUsage\n-----\n\nThis plugin is roughly jekyll compatible.\nYou just need to do as you normally do in jekyll.\n\n- Add a new post in the `_posts` directory of your git repository.\n- Commit and push to GitHub.\n \nYour new post will be published in typecho automatically.\n\nPost format\n-----------\n\nExample:\n\n```yaml\n---\ntitle: your blog title\ntags: apple orange\ncategroy: life\n---\n\nWrite you posts in *markdown*.\n```\n\nIf you have used jekyll before, you will find this format familiar.\n\nBut there are some differencs:\n\n- Only support markdown markup.\n- No self defined field.\n- No support for `layout`, `published` and `permalink`. (We will use filename as permalink slug.)\n- `category` only allows one value, since Typecho only allows one.\n- `tags` only support space-separated strings. YAML list is not supported.\n\n\nBugs\n----\n\n[#9](https://github.com/weakish/plugins/issues/9) `git add` multiple files to repostiory, then push. Only the first file will be published into typecho. \n\n"
  },
  {
    "path": "GitHubGit/Spyc.php",
    "content": "<?php\n/**\n   * Spyc -- A Simple PHP YAML Class\n   * @version 0.5.1\n   * @author Vlad Andersen <vlad.andersen@gmail.com>\n   * @author Chris Wanstrath <chris@ozmm.org>\n   * @link http://code.google.com/p/spyc/\n   * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen\n   * @license http://www.opensource.org/licenses/mit-license.php MIT License\n   * @package Spyc\n   */\n\nif (!function_exists('spyc_load')) {\n  /**\n   * Parses YAML to array.\n   * @param string $string YAML string.\n   * @return array\n   */\n  function spyc_load ($string) {\n    return Spyc::YAMLLoadString($string);\n  }\n}\n\nif (!function_exists('spyc_load_file')) {\n  /**\n   * Parses YAML to array.\n   * @param string $file Path to YAML file.\n   * @return array\n   */\n  function spyc_load_file ($file) {\n    return Spyc::YAMLLoad($file);\n  }\n}\n\nif (!function_exists('spyc_dump')) {\n  /**\n   * Dumps array to YAML.\n   * @param array $data Array.\n   * @return string\n   */\n  function spyc_dump ($data) {\n    return Spyc::YAMLDump($data, false, false, true);\n  }\n}\n\n/**\n   * The Simple PHP YAML Class.\n   *\n   * This class can be used to read a YAML file and convert its contents\n   * into a PHP array.  It currently supports a very limited subsection of\n   * the YAML spec.\n   *\n   * Usage:\n   * <code>\n   *   $Spyc  = new Spyc;\n   *   $array = $Spyc->load($file);\n   * </code>\n   * or:\n   * <code>\n   *   $array = Spyc::YAMLLoad($file);\n   * </code>\n   * or:\n   * <code>\n   *   $array = spyc_load_file($file);\n   * </code>\n   * @package Spyc\n   */\nclass Spyc {\n\n  // SETTINGS\n\n  const REMPTY = \"\\0\\0\\0\\0\\0\";\n\n  /**\n   * Setting this to true will force YAMLDump to enclose any string value in\n   * quotes.  False by default.\n   *\n   * @var bool\n   */\n  public $setting_dump_force_quotes = false;\n\n  /**\n   * Setting this to true will forse YAMLLoad to use syck_load function when\n   * possible. False by default.\n   * @var bool\n   */\n  public $setting_use_syck_is_possible = false;\n\n\n\n  /**#@+\n  * @access private\n  * @var mixed\n  */\n  private $_dumpIndent;\n  private $_dumpWordWrap;\n  private $_containsGroupAnchor = false;\n  private $_containsGroupAlias = false;\n  private $path;\n  private $result;\n  private $LiteralPlaceHolder = '___YAML_Literal_Block___';\n  private $SavedGroups = array();\n  private $indent;\n  /**\n   * Path modifier that should be applied after adding current element.\n   * @var array\n   */\n  private $delayedPath = array();\n\n  /**#@+\n  * @access public\n  * @var mixed\n  */\n  public $_nodeId;\n\n/**\n * Load a valid YAML string to Spyc.\n * @param string $input\n * @return array\n */\n  public function load ($input) {\n    return $this->__loadString($input);\n  }\n\n /**\n * Load a valid YAML file to Spyc.\n * @param string $file\n * @return array\n */\n  public function loadFile ($file) {\n    return $this->__load($file);\n  }\n\n  /**\n     * Load YAML into a PHP array statically\n     *\n     * The load method, when supplied with a YAML stream (string or file),\n     * will do its best to convert YAML in a file into a PHP array.  Pretty\n     * simple.\n     *  Usage:\n     *  <code>\n     *   $array = Spyc::YAMLLoad('lucky.yaml');\n     *   print_r($array);\n     *  </code>\n     * @access public\n     * @return array\n     * @param string $input Path of YAML file or string containing YAML\n     */\n  public static function YAMLLoad($input) {\n    $Spyc = new Spyc;\n    return $Spyc->__load($input);\n  }\n\n  /**\n     * Load a string of YAML into a PHP array statically\n     *\n     * The load method, when supplied with a YAML string, will do its best\n     * to convert YAML in a string into a PHP array.  Pretty simple.\n     *\n     * Note: use this function if you don't want files from the file system\n     * loaded and processed as YAML.  This is of interest to people concerned\n     * about security whose input is from a string.\n     *\n     *  Usage:\n     *  <code>\n     *   $array = Spyc::YAMLLoadString(\"---\\n0: hello world\\n\");\n     *   print_r($array);\n     *  </code>\n     * @access public\n     * @return array\n     * @param string $input String containing YAML\n     */\n  public static function YAMLLoadString($input) {\n    $Spyc = new Spyc;\n    return $Spyc->__loadString($input);\n  }\n\n  /**\n     * Dump YAML from PHP array statically\n     *\n     * The dump method, when supplied with an array, will do its best\n     * to convert the array into friendly YAML.  Pretty simple.  Feel free to\n     * save the returned string as nothing.yaml and pass it around.\n     *\n     * Oh, and you can decide how big the indent is and what the wordwrap\n     * for folding is.  Pretty cool -- just pass in 'false' for either if\n     * you want to use the default.\n     *\n     * Indent's default is 2 spaces, wordwrap's default is 40 characters.  And\n     * you can turn off wordwrap by passing in 0.\n     *\n     * @access public\n     * @return string\n     * @param array $array PHP array\n     * @param int $indent Pass in false to use the default, which is 2\n     * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)\n     * @param int $no_opening_dashes Do not start YAML file with \"---\\n\"\n     */\n  public static function YAMLDump($array, $indent = false, $wordwrap = false, $no_opening_dashes = false) {\n    $spyc = new Spyc;\n    return $spyc->dump($array, $indent, $wordwrap, $no_opening_dashes);\n  }\n\n\n  /**\n     * Dump PHP array to YAML\n     *\n     * The dump method, when supplied with an array, will do its best\n     * to convert the array into friendly YAML.  Pretty simple.  Feel free to\n     * save the returned string as tasteful.yaml and pass it around.\n     *\n     * Oh, and you can decide how big the indent is and what the wordwrap\n     * for folding is.  Pretty cool -- just pass in 'false' for either if\n     * you want to use the default.\n     *\n     * Indent's default is 2 spaces, wordwrap's default is 40 characters.  And\n     * you can turn off wordwrap by passing in 0.\n     *\n     * @access public\n     * @return string\n     * @param array $array PHP array\n     * @param int $indent Pass in false to use the default, which is 2\n     * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)\n     */\n  public function dump($array,$indent = false,$wordwrap = false, $no_opening_dashes = false) {\n    // Dumps to some very clean YAML.  We'll have to add some more features\n    // and options soon.  And better support for folding.\n\n    // New features and options.\n    if ($indent === false or !is_numeric($indent)) {\n      $this->_dumpIndent = 2;\n    } else {\n      $this->_dumpIndent = $indent;\n    }\n\n    if ($wordwrap === false or !is_numeric($wordwrap)) {\n      $this->_dumpWordWrap = 40;\n    } else {\n      $this->_dumpWordWrap = $wordwrap;\n    }\n\n    // New YAML document\n    $string = \"\";\n    if (!$no_opening_dashes) $string = \"---\\n\";\n\n    // Start at the base of the array and move through it.\n    if ($array) {\n      $array = (array)$array;\n      $previous_key = -1;\n      foreach ($array as $key => $value) {\n        if (!isset($first_key)) $first_key = $key;\n        $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array);\n        $previous_key = $key;\n      }\n    }\n    return $string;\n  }\n\n  /**\n     * Attempts to convert a key / value array item to YAML\n     * @access private\n     * @return string\n     * @param $key The name of the key\n     * @param $value The value of the item\n     * @param $indent The indent of the current node\n     */\n  private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) {\n    if (is_array($value)) {\n      if (empty ($value))\n        return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array);\n      // It has children.  What to do?\n      // Make it the right kind of item\n      $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array);\n      // Add the indent\n      $indent += $this->_dumpIndent;\n      // Yamlize the array\n      $string .= $this->_yamlizeArray($value,$indent);\n    } elseif (!is_array($value)) {\n      // It doesn't have children.  Yip.\n      $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array);\n    }\n    return $string;\n  }\n\n  /**\n     * Attempts to convert an array to YAML\n     * @access private\n     * @return string\n     * @param $array The array you want to convert\n     * @param $indent The indent of the current level\n     */\n  private function _yamlizeArray($array,$indent) {\n    if (is_array($array)) {\n      $string = '';\n      $previous_key = -1;\n      foreach ($array as $key => $value) {\n        if (!isset($first_key)) $first_key = $key;\n        $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array);\n        $previous_key = $key;\n      }\n      return $string;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n     * Returns YAML from a key and a value\n     * @access private\n     * @return string\n     * @param $key The name of the key\n     * @param $value The value of the item\n     * @param $indent The indent of the current node\n     */\n  private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) {\n    // do some folding here, for blocks\n    if (is_string ($value) && ((strpos($value,\"\\n\") !== false || strpos($value,\": \") !== false || strpos($value,\"- \") !== false ||\n      strpos($value,\"*\") !== false || strpos($value,\"#\") !== false || strpos($value,\"<\") !== false || strpos($value,\">\") !== false || strpos ($value, '  ') !== false ||\n      strpos($value,\"[\") !== false || strpos($value,\"]\") !== false || strpos($value,\"{\") !== false || strpos($value,\"}\") !== false) || strpos($value,\"&\") !== false || strpos($value, \"'\") !== false || strpos($value, \"!\") === 0 ||\n      substr ($value, -1, 1) == ':')\n    ) {\n      $value = $this->_doLiteralBlock($value,$indent);\n    } else {\n      $value  = $this->_doFolding($value,$indent);\n    }\n\n    if ($value === array()) $value = '[ ]';\n    if ($value === \"\") $value = '\"\"';\n    if (self::isTranslationWord($value)) {\n      $value = $this->_doLiteralBlock($value, $indent);\n    }\n    if (trim ($value) != $value)\n       $value = $this->_doLiteralBlock($value,$indent);\n\n    if (is_bool($value)) {\n       $value = $value ? \"true\" : \"false\";\n    }\n\n    if ($value === null) $value = 'null';\n    if ($value === \"'\" . self::REMPTY . \"'\") $value = null;\n\n    $spaces = str_repeat(' ',$indent);\n\n    //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {\n    if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) {\n      // It's a sequence\n      $string = $spaces.'- '.$value.\"\\n\";\n    } else {\n      // if ($first_key===0)  throw new Exception('Keys are all screwy.  The first one was zero, now it\\'s \"'. $key .'\"');\n      // It's mapped\n      if (strpos($key, \":\") !== false || strpos($key, \"#\") !== false) { $key = '\"' . $key . '\"'; }\n      $string = rtrim ($spaces.$key.': '.$value).\"\\n\";\n    }\n    return $string;\n  }\n\n  /**\n     * Creates a literal block for dumping\n     * @access private\n     * @return string\n     * @param $value\n     * @param $indent int The value of the indent\n     */\n  private function _doLiteralBlock($value,$indent) {\n    if ($value === \"\\n\") return '\\n';\n    if (strpos($value, \"\\n\") === false && strpos($value, \"'\") === false) {\n      return sprintf (\"'%s'\", $value);\n    }\n    if (strpos($value, \"\\n\") === false && strpos($value, '\"') === false) {\n      return sprintf ('\"%s\"', $value);\n    }\n    $exploded = explode(\"\\n\",$value);\n    $newValue = '|';\n    $indent  += $this->_dumpIndent;\n    $spaces   = str_repeat(' ',$indent);\n    foreach ($exploded as $line) {\n      $newValue .= \"\\n\" . $spaces . ($line);\n    }\n    return $newValue;\n  }\n\n  /**\n     * Folds a string of text, if necessary\n     * @access private\n     * @return string\n     * @param $value The string you wish to fold\n     */\n  private function _doFolding($value,$indent) {\n    // Don't do anything if wordwrap is set to 0\n\n    if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) {\n      $indent += $this->_dumpIndent;\n      $indent = str_repeat(' ',$indent);\n      $wrapped = wordwrap($value,$this->_dumpWordWrap,\"\\n$indent\");\n      $value   = \">\\n\".$indent.$wrapped;\n    } else {\n      if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY)\n        $value = '\"' . $value . '\"';\n      if (is_numeric($value) && is_string($value))\n        $value = '\"' . $value . '\"';\n    }\n\n\n    return $value;\n  }\n\n  private function isTrueWord($value) {\n    $words = self::getTranslations(array('true', 'on', 'yes', 'y'));\n    return in_array($value, $words, true);\n  }\n\n  private function isFalseWord($value) {\n    $words = self::getTranslations(array('false', 'off', 'no', 'n'));\n    return in_array($value, $words, true);\n  }\n\n  private function isNullWord($value) {\n    $words = self::getTranslations(array('null', '~'));\n    return in_array($value, $words, true);\n  }\n\n  private function isTranslationWord($value) {\n    return (\n      self::isTrueWord($value)  ||\n      self::isFalseWord($value) ||\n      self::isNullWord($value)\n    );\n  }\n\n  /**\n     * Coerce a string into a native type\n     * Reference: http://yaml.org/type/bool.html\n     * TODO: Use only words from the YAML spec.\n     * @access private\n     * @param $value The value to coerce\n     */\n  private function coerceValue(&$value) {\n    if (self::isTrueWord($value)) {\n      $value = true;\n    } else if (self::isFalseWord($value)) {\n      $value = false;\n    } else if (self::isNullWord($value)) {\n      $value = null;\n    }\n  }\n\n  /**\n     * Given a set of words, perform the appropriate translations on them to\n     * match the YAML 1.1 specification for type coercing.\n     * @param $words The words to translate\n     * @access private\n     */\n  private static function getTranslations(array $words) {\n    $result = array();\n    foreach ($words as $i) {\n      $result = array_merge($result, array(ucfirst($i), strtoupper($i), strtolower($i)));\n    }\n    return $result;\n  }\n\n// LOADING FUNCTIONS\n\n  private function __load($input) {\n    $Source = $this->loadFromSource($input);\n    return $this->loadWithSource($Source);\n  }\n\n  private function __loadString($input) {\n    $Source = $this->loadFromString($input);\n    return $this->loadWithSource($Source);\n  }\n\n  private function loadWithSource($Source) {\n    if (empty ($Source)) return array();\n    if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) {\n      $array = syck_load (implode (\"\\n\", $Source));\n      return is_array($array) ? $array : array();\n    }\n\n    $this->path = array();\n    $this->result = array();\n\n    $cnt = count($Source);\n    for ($i = 0; $i < $cnt; $i++) {\n      $line = $Source[$i];\n\n      $this->indent = strlen($line) - strlen(ltrim($line));\n      $tempPath = $this->getParentPathByIndent($this->indent);\n      $line = self::stripIndent($line, $this->indent);\n      if (self::isComment($line)) continue;\n      if (self::isEmpty($line)) continue;\n      $this->path = $tempPath;\n\n      $literalBlockStyle = self::startsLiteralBlock($line);\n      if ($literalBlockStyle) {\n        $line = rtrim ($line, $literalBlockStyle . \" \\n\");\n        $literalBlock = '';\n        $line .= ' '.$this->LiteralPlaceHolder;\n        $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1]));\n        while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) {\n          $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent);\n        }\n        $i--;\n      }\n\n      // Strip out comments\n      if (strpos ($line, '#')) {\n          $line = preg_replace('/\\s*#([^\"\\']+)$/','',$line);\n      }\n\n      while (++$i < $cnt && self::greedilyNeedNextLine($line)) {\n        $line = rtrim ($line, \" \\n\\t\\r\") . ' ' . ltrim ($Source[$i], \" \\t\");\n      }\n      $i--;\n\n      $lineArray = $this->_parseLine($line);\n\n      if ($literalBlockStyle)\n        $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock);\n\n      $this->addArray($lineArray, $this->indent);\n\n      foreach ($this->delayedPath as $indent => $delayedPath)\n        $this->path[$indent] = $delayedPath;\n\n      $this->delayedPath = array();\n\n    }\n    return $this->result;\n  }\n\n  private function loadFromSource ($input) {\n    if (!empty($input) && strpos($input, \"\\n\") === false && file_exists($input))\n      $input = file_get_contents($input);\n\n    return $this->loadFromString($input);\n  }\n\n  private function loadFromString ($input) {\n    $lines = explode(\"\\n\",$input);\n    foreach ($lines as $k => $_) {\n      $lines[$k] = rtrim ($_, \"\\r\");\n    }\n    return $lines;\n  }\n\n  /**\n     * Parses YAML code and returns an array for a node\n     * @access private\n     * @return array\n     * @param string $line A line from the YAML file\n     */\n  private function _parseLine($line) {\n    if (!$line) return array();\n    $line = trim($line);\n    if (!$line) return array();\n\n    $array = array();\n\n    $group = $this->nodeContainsGroup($line);\n    if ($group) {\n      $this->addGroup($line, $group);\n      $line = $this->stripGroup ($line, $group);\n    }\n\n    if ($this->startsMappedSequence($line))\n      return $this->returnMappedSequence($line);\n\n    if ($this->startsMappedValue($line))\n      return $this->returnMappedValue($line);\n\n    if ($this->isArrayElement($line))\n     return $this->returnArrayElement($line);\n\n    if ($this->isPlainArray($line))\n     return $this->returnPlainArray($line);\n\n\n    return $this->returnKeyValuePair($line);\n\n  }\n\n  /**\n     * Finds the type of the passed value, returns the value as the new type.\n     * @access private\n     * @param string $value\n     * @return mixed\n     */\n  private function _toType($value) {\n    if ($value === '') return \"\";\n    $first_character = $value[0];\n    $last_character = substr($value, -1, 1);\n\n    $is_quoted = false;\n    do {\n      if (!$value) break;\n      if ($first_character != '\"' && $first_character != \"'\") break;\n      if ($last_character != '\"' && $last_character != \"'\") break;\n      $is_quoted = true;\n    } while (0);\n\n    if ($is_quoted) {\n      $value = str_replace('\\n', \"\\n\", $value);\n      return strtr(substr ($value, 1, -1), array ('\\\\\"' => '\"', '\\'\\'' => '\\'', '\\\\\\'' => '\\''));\n    }\n\n    if (strpos($value, ' #') !== false && !$is_quoted)\n      $value = preg_replace('/\\s+#(.+)$/','',$value);\n\n    if ($first_character == '[' && $last_character == ']') {\n      // Take out strings sequences and mappings\n      $innerValue = trim(substr ($value, 1, -1));\n      if ($innerValue === '') return array();\n      $explode = $this->_inlineEscape($innerValue);\n      // Propagate value array\n      $value  = array();\n      foreach ($explode as $v) {\n        $value[] = $this->_toType($v);\n      }\n      return $value;\n    }\n\n    if (strpos($value,': ')!==false && $first_character != '{') {\n      $array = explode(': ',$value);\n      $key   = trim($array[0]);\n      array_shift($array);\n      $value = trim(implode(': ',$array));\n      $value = $this->_toType($value);\n      return array($key => $value);\n    }\n\n    if ($first_character == '{' && $last_character == '}') {\n      $innerValue = trim(substr ($value, 1, -1));\n      if ($innerValue === '') return array();\n      // Inline Mapping\n      // Take out strings sequences and mappings\n      $explode = $this->_inlineEscape($innerValue);\n      // Propagate value array\n      $array = array();\n      foreach ($explode as $v) {\n        $SubArr = $this->_toType($v);\n        if (empty($SubArr)) continue;\n        if (is_array ($SubArr)) {\n          $array[key($SubArr)] = $SubArr[key($SubArr)]; continue;\n        }\n        $array[] = $SubArr;\n      }\n      return $array;\n    }\n\n    if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') {\n      return null;\n    }\n\n    if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){\n      $intvalue = (int)$value;\n      if ($intvalue != PHP_INT_MAX)\n        $value = $intvalue;\n      return $value;\n    }\n\n    $this->coerceValue($value);\n\n    if (is_numeric($value)) {\n      if ($value === '0') return 0;\n      if (rtrim ($value, 0) === $value)\n        $value = (float)$value;\n      return $value;\n    }\n\n    return $value;\n  }\n\n  /**\n     * Used in inlines to check for more inlines or quoted strings\n     * @access private\n     * @return array\n     */\n  private function _inlineEscape($inline) {\n    // There's gotta be a cleaner way to do this...\n    // While pure sequences seem to be nesting just fine,\n    // pure mappings and mappings with sequences inside can't go very\n    // deep.  This needs to be fixed.\n\n    $seqs = array();\n    $maps = array();\n    $saved_strings = array();\n    $saved_empties = array();\n\n    // Check for empty strings\n    $regex = '/(\"\")|(\\'\\')/';\n    if (preg_match_all($regex,$inline,$strings)) {\n      $saved_empties = $strings[0];\n      $inline  = preg_replace($regex,'YAMLEmpty',$inline);\n    }\n    unset($regex);\n\n    // Check for strings\n    $regex = '/(?:(\")|(?:\\'))((?(1)[^\"]+|[^\\']+))(?(1)\"|\\')/';\n    if (preg_match_all($regex,$inline,$strings)) {\n      $saved_strings = $strings[0];\n      $inline  = preg_replace($regex,'YAMLString',$inline);\n    }\n    unset($regex);\n\n    // echo $inline;\n\n    $i = 0;\n    do {\n\n    // Check for sequences\n    while (preg_match('/\\[([^{}\\[\\]]+)\\]/U',$inline,$matchseqs)) {\n      $seqs[] = $matchseqs[0];\n      $inline = preg_replace('/\\[([^{}\\[\\]]+)\\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1);\n    }\n\n    // Check for mappings\n    while (preg_match('/{([^\\[\\]{}]+)}/U',$inline,$matchmaps)) {\n      $maps[] = $matchmaps[0];\n      $inline = preg_replace('/{([^\\[\\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1);\n    }\n\n    if ($i++ >= 10) break;\n\n    } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false);\n\n    $explode = explode(',',$inline);\n    $explode = array_map('trim', $explode);\n    $stringi = 0; $i = 0;\n\n    while (1) {\n\n    // Re-add the sequences\n    if (!empty($seqs)) {\n      foreach ($explode as $key => $value) {\n        if (strpos($value,'YAMLSeq') !== false) {\n          foreach ($seqs as $seqk => $seq) {\n            $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value);\n            $value = $explode[$key];\n          }\n        }\n      }\n    }\n\n    // Re-add the mappings\n    if (!empty($maps)) {\n      foreach ($explode as $key => $value) {\n        if (strpos($value,'YAMLMap') !== false) {\n          foreach ($maps as $mapk => $map) {\n            $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value);\n            $value = $explode[$key];\n          }\n        }\n      }\n    }\n\n\n    // Re-add the strings\n    if (!empty($saved_strings)) {\n      foreach ($explode as $key => $value) {\n        while (strpos($value,'YAMLString') !== false) {\n          $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1);\n          unset($saved_strings[$stringi]);\n          ++$stringi;\n          $value = $explode[$key];\n        }\n      }\n    }\n\n\n    // Re-add the empties\n    if (!empty($saved_empties)) {\n      foreach ($explode as $key => $value) {\n        while (strpos($value,'YAMLEmpty') !== false) {\n          $explode[$key] = preg_replace('/YAMLEmpty/', '', $value, 1);\n          $value = $explode[$key];\n        }\n      }\n    }\n\n    $finished = true;\n    foreach ($explode as $key => $value) {\n      if (strpos($value,'YAMLSeq') !== false) {\n        $finished = false; break;\n      }\n      if (strpos($value,'YAMLMap') !== false) {\n        $finished = false; break;\n      }\n      if (strpos($value,'YAMLString') !== false) {\n        $finished = false; break;\n      }\n      if (strpos($value,'YAMLEmpty') !== false) {\n        $finished = false; break;\n      }\n    }\n    if ($finished) break;\n\n    $i++;\n    if ($i > 10)\n      break; // Prevent infinite loops.\n    }\n\n\n    return $explode;\n  }\n\n  private function literalBlockContinues ($line, $lineIndent) {\n    if (!trim($line)) return true;\n    if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true;\n    return false;\n  }\n\n  private function referenceContentsByAlias ($alias) {\n    do {\n      if (!isset($this->SavedGroups[$alias])) { echo \"Bad group name: $alias.\"; break; }\n      $groupPath = $this->SavedGroups[$alias];\n      $value = $this->result;\n      foreach ($groupPath as $k) {\n        $value = $value[$k];\n      }\n    } while (false);\n    return $value;\n  }\n\n  private function addArrayInline ($array, $indent) {\n      $CommonGroupPath = $this->path;\n      if (empty ($array)) return false;\n\n      foreach ($array as $k => $_) {\n        $this->addArray(array($k => $_), $indent);\n        $this->path = $CommonGroupPath;\n      }\n      return true;\n  }\n\n  private function addArray ($incoming_data, $incoming_indent) {\n\n   // print_r ($incoming_data);\n\n    if (count ($incoming_data) > 1)\n      return $this->addArrayInline ($incoming_data, $incoming_indent);\n\n    $key = key ($incoming_data);\n    $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null;\n    if ($key === '__!YAMLZero') $key = '0';\n\n    if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values.\n      if ($key || $key === '' || $key === '0') {\n        $this->result[$key] = $value;\n      } else {\n        $this->result[] = $value; end ($this->result); $key = key ($this->result);\n      }\n      $this->path[$incoming_indent] = $key;\n      return;\n    }\n\n\n\n    $history = array();\n    // Unfolding inner array tree.\n    $history[] = $_arr = $this->result;\n    foreach ($this->path as $k) {\n      $history[] = $_arr = $_arr[$k];\n    }\n\n    if ($this->_containsGroupAlias) {\n      $value = $this->referenceContentsByAlias($this->_containsGroupAlias);\n      $this->_containsGroupAlias = false;\n    }\n\n\n    // Adding string or numeric key to the innermost level or $this->arr.\n    if (is_string($key) && $key == '<<') {\n      if (!is_array ($_arr)) { $_arr = array (); }\n\n      $_arr = array_merge ($_arr, $value);\n    } else if ($key || $key === '' || $key === '0') {\n      if (!is_array ($_arr))\n        $_arr = array ($key=>$value);\n      else\n        $_arr[$key] = $value;\n    } else {\n      if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }\n      else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }\n    }\n\n    $reverse_path = array_reverse($this->path);\n    $reverse_history = array_reverse ($history);\n    $reverse_history[0] = $_arr;\n    $cnt = count($reverse_history) - 1;\n    for ($i = 0; $i < $cnt; $i++) {\n      $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i];\n    }\n    $this->result = $reverse_history[$cnt];\n\n    $this->path[$incoming_indent] = $key;\n\n    if ($this->_containsGroupAnchor) {\n      $this->SavedGroups[$this->_containsGroupAnchor] = $this->path;\n      if (is_array ($value)) {\n        $k = key ($value);\n        if (!is_int ($k)) {\n          $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k;\n        }\n      }\n      $this->_containsGroupAnchor = false;\n    }\n\n  }\n\n  private static function startsLiteralBlock ($line) {\n    $lastChar = substr (trim($line), -1);\n    if ($lastChar != '>' && $lastChar != '|') return false;\n    if ($lastChar == '|') return $lastChar;\n    // HTML tags should not be counted as literal blocks.\n    if (preg_match ('#<.*?>$#', $line)) return false;\n    return $lastChar;\n  }\n\n  private static function greedilyNeedNextLine($line) {\n    $line = trim ($line);\n    if (!strlen($line)) return false;\n    if (substr ($line, -1, 1) == ']') return false;\n    if ($line[0] == '[') return true;\n    if (preg_match ('#^[^:]+?:\\s*\\[#', $line)) return true;\n    return false;\n  }\n\n  private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) {\n    $line = self::stripIndent($line, $indent);\n    if ($literalBlockStyle !== '|') {\n        $line = self::stripIndent($line);\n    }\n    $line = rtrim ($line, \"\\r\\n\\t \") . \"\\n\";\n    if ($literalBlockStyle == '|') {\n      return $literalBlock . $line;\n    }\n    if (strlen($line) == 0)\n      return rtrim($literalBlock, ' ') . \"\\n\";\n    if ($line == \"\\n\" && $literalBlockStyle == '>') {\n      return rtrim ($literalBlock, \" \\t\") . \"\\n\";\n    }\n    if ($line != \"\\n\")\n      $line = trim ($line, \"\\r\\n \") . \" \";\n    return $literalBlock . $line;\n  }\n\n   function revertLiteralPlaceHolder ($lineArray, $literalBlock) {\n     foreach ($lineArray as $k => $_) {\n      if (is_array($_))\n        $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock);\n      else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder)\n\t       $lineArray[$k] = rtrim ($literalBlock, \" \\r\\n\");\n     }\n     return $lineArray;\n   }\n\n  private static function stripIndent ($line, $indent = -1) {\n    if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line));\n    return substr ($line, $indent);\n  }\n\n  private function getParentPathByIndent ($indent) {\n    if ($indent == 0) return array();\n    $linePath = $this->path;\n    do {\n      end($linePath); $lastIndentInParentPath = key($linePath);\n      if ($indent <= $lastIndentInParentPath) array_pop ($linePath);\n    } while ($indent <= $lastIndentInParentPath);\n    return $linePath;\n  }\n\n\n  private function clearBiggerPathValues ($indent) {\n\n\n    if ($indent == 0) $this->path = array();\n    if (empty ($this->path)) return true;\n\n    foreach ($this->path as $k => $_) {\n      if ($k > $indent) unset ($this->path[$k]);\n    }\n\n    return true;\n  }\n\n\n  private static function isComment ($line) {\n    if (!$line) return false;\n    if ($line[0] == '#') return true;\n    if (trim($line, \" \\r\\n\\t\") == '---') return true;\n    return false;\n  }\n\n  private static function isEmpty ($line) {\n    return (trim ($line) === '');\n  }\n\n\n  private function isArrayElement ($line) {\n    if (!$line || !is_scalar($line)) return false;\n    if (substr($line, 0, 2) != '- ') return false;\n    if (strlen ($line) > 3)\n      if (substr($line,0,3) == '---') return false;\n\n    return true;\n  }\n\n  private function isHashElement ($line) {\n    return strpos($line, ':');\n  }\n\n  private function isLiteral ($line) {\n    if ($this->isArrayElement($line)) return false;\n    if ($this->isHashElement($line)) return false;\n    return true;\n  }\n\n\n  private static function unquote ($value) {\n    if (!$value) return $value;\n    if (!is_string($value)) return $value;\n    if ($value[0] == '\\'') return trim ($value, '\\'');\n    if ($value[0] == '\"') return trim ($value, '\"');\n    return $value;\n  }\n\n  private function startsMappedSequence ($line) {\n    return (substr($line, 0, 2) == '- ' && substr ($line, -1, 1) == ':');\n  }\n\n  private function returnMappedSequence ($line) {\n    $array = array();\n    $key         = self::unquote(trim(substr($line,1,-1)));\n    $array[$key] = array();\n    $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key);\n    return array($array);\n  }\n\n  private function checkKeysInValue($value) {\n    if (strchr('[{\"\\'', $value[0]) === false) {\n      if (strchr($value, ': ') !== false) {\n          throw new Exception('Too many keys: '.$value);\n      }\n    }\n  }\n\n  private function returnMappedValue ($line) {\n    $this->checkKeysInValue($line);\n    $array = array();\n    $key         = self::unquote (trim(substr($line,0,-1)));\n    $array[$key] = '';\n    return $array;\n  }\n\n  private function startsMappedValue ($line) {\n    return (substr ($line, -1, 1) == ':');\n  }\n\n  private function isPlainArray ($line) {\n    return ($line[0] == '[' && substr ($line, -1, 1) == ']');\n  }\n\n  private function returnPlainArray ($line) {\n    return $this->_toType($line);\n  }\n\n  private function returnKeyValuePair ($line) {\n    $array = array();\n    $key = '';\n    if (strpos ($line, ': ')) {\n      // It's a key/value pair most likely\n      // If the key is in double quotes pull it out\n      if (($line[0] == '\"' || $line[0] == \"'\") && preg_match('/^([\"\\'](.*)[\"\\'](\\s)*:)/',$line,$matches)) {\n        $value = trim(str_replace($matches[1],'',$line));\n        $key   = $matches[2];\n      } else {\n        // Do some guesswork as to the key and the value\n        $explode = explode(': ', $line);\n        $key     = trim(array_shift($explode));\n        $value   = trim(implode(': ', $explode));\n        $this->checkKeysInValue($value);\n      }\n      // Set the type of the value.  Int, string, etc\n      $value = $this->_toType($value);\n      if ($key === '0') $key = '__!YAMLZero';\n      $array[$key] = $value;\n    } else {\n      $array = array ($line);\n    }\n    return $array;\n\n  }\n\n\n  private function returnArrayElement ($line) {\n     if (strlen($line) <= 1) return array(array()); // Weird %)\n     $array = array();\n     $value   = trim(substr($line,1));\n     $value   = $this->_toType($value);\n     if ($this->isArrayElement($value)) {\n       $value = $this->returnArrayElement($value);\n     }\n     $array[] = $value;\n     return $array;\n  }\n\n\n  private function nodeContainsGroup ($line) {\n    $symbolsForReference = 'A-z0-9_\\-';\n    if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-)\n    if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];\n    if ($line[0] == '*' && preg_match('/^(\\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];\n    if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1];\n    if (preg_match('/(\\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1];\n    if (preg_match ('#^\\s*<<\\s*:\\s*(\\*[^\\s]+).*$#', $line, $matches)) return $matches[1];\n    return false;\n\n  }\n\n  private function addGroup ($line, $group) {\n    if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1);\n    if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1);\n    //print_r ($this->path);\n  }\n\n  private function stripGroup ($line, $group) {\n    $line = trim(str_replace($group, '', $line));\n    return $line;\n  }\n}\n\n// Enable use of Spyc from command line\n// The syntax is the following: php Spyc.php spyc.yaml\n\ndo {\n  if (PHP_SAPI != 'cli') break;\n  if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break;\n  if (empty ($_SERVER['PHP_SELF']) || FALSE === strpos ($_SERVER['PHP_SELF'], 'Spyc.php') ) break;\n  $file = $argv[1];\n  echo json_encode (spyc_load_file ($file));\n} while (0);\n"
  },
  {
    "path": "GoogleAnalytics/Plugin.php",
    "content": "<?php\n/**\n * Google Analytics\n * \n * @package GoogleAnalytics\n * @author mutoo\n * @version 1.0.0\n * @link http://typecho.org\n */\nclass GoogleAnalytics_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Archive')->footer = array('GoogleAnalytics_Plugin', 'render');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        /** 分类名称 */\n        $account = new Typecho_Widget_Helper_Form_Element_Text('account', NULL, 'UA-XXXXXXX-X', _t('Google Analytics 帐号'), _t('此帐号可在 GA 管理平台查询；格式为 UA-XXXXXXX-X 。'));\n        $form->addInput($account);\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function render()\n    {\n        $account = Typecho_Widget::widget('Widget_Options')->plugin('GoogleAnalytics')->account;\n        echo \"<script type=\\\"text/javascript\\\">var _gaq = _gaq || [];_gaq.push(['_setAccount', '{$account}']);_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();</script>\";\n    }\n}"
  },
  {
    "path": "GoogleCodePrettify/Plugin.php",
    "content": "<?php\n/**\n * Google高亮代码\n * \n * @package Google Code Prettify\n * @author qining\n * @version 1.0.0\n * @dependence 9.9.2-*\n * @link http://typecho.org\n */\nclass GoogleCodePrettify_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('GoogleCodePrettify_Plugin', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('GoogleCodePrettify_Plugin', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Comments')->contentEx = array('GoogleCodePrettify_Plugin', 'parse');\n        Typecho_Plugin::factory('Widget_Archive')->header = array('GoogleCodePrettify_Plugin', 'header');\n        Typecho_Plugin::factory('Widget_Archive')->footer = array('GoogleCodePrettify_Plugin', 'footer');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 输出头部css\n     * \n     * @access public\n     * @param unknown $header\n     * @return unknown\n     */\n    public static function header() {\n        $cssUrl = Helper::options()->pluginUrl . '/GoogleCodePrettify/src/prettify.css';\n        echo '<link rel=\"stylesheet\" type=\"text/css\" href=\"' . $cssUrl . '\" />';\n    }\n    \n    /**\n     * 输出尾部js\n     * \n     * @access public\n     * @param unknown $header\n     * @return unknown\n     */\n    public static function footer() {\n        $jsUrl = Helper::options()->pluginUrl . '/GoogleCodePrettify/src/prettify.js';\n        echo '<script type=\"text/javascript\" src=\"'. $jsUrl .'\"></script>';\n        echo '<script type=\"text/javascript\">window.onload = function () {\n            prettyPrint();\n        }</script>';\n    }\n    \n    /**\n     * 解析\n     * \n     * @access public\n     * @param array $matches 解析值\n     * @return string\n     */\n    public static function parseCallback($matches)\n    {\n        $language = trim($matches[2]);\n        \n        $map = array(\n            'js'                =>  'javascript',\n            'as'                =>  'actionscript',\n            'as3'               =>  'actionscript3'\n        );\n        \n        if (!empty($language) && isset($map[$language])) {\n            $language = $map[$language];\n        }\n        \n        $source = '<div class=\"prettyprint-box\"><table class=\"prettyprint-table\"><tr>';\n        $numberItem = '<td width=\"2%\" class=\"number\"><table>';\n        $sourceItem = '<td width=\"98%\" class=\"code\"><pre' . (empty($language) ? '' : ' id=\"' . $language . '\"') . ' class=\"prettyprint\"><table>';\n        \n        $sourceList = explode(\"\\n\", trim($matches[3]));\n        foreach ($sourceList as $key => $sourceLine) {\n            $numberItem .= '<tr><td>' . ($key + 1) . '</td></tr>';\n            $sourceItem .= '<tr><td class=\"source\">' . htmlspecialchars($sourceLine) . '</td></tr>';\n        }\n        \n        $numberItem .= '</table></td>';\n        $sourceItem .= '</table></pre></td>';\n        \n        return $source . $numberItem . $sourceItem . '</tr></table></div>';\n    }\n    \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function parse($text, $widget, $lastResult)\n    {\n        $text = empty($lastResult) ? $text : $lastResult;\n        \n        if ($widget instanceof Widget_Archive || $widget instanceof Widget_Abstract_Comments) {\n            return preg_replace_callback(\"/<(code|pre)(\\s*[^>]*)>(.*?)<\\/\\\\1>/is\", array('GoogleCodePrettify_Plugin', 'parseCallback'), $text);\n        } else {\n            return $text;\n        }\n    }\n}\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-apollo.js",
    "content": "// Copyright (C) 2009 Onno Hommes.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n/**\n * @fileoverview\n * Registers a language handler for the AGC/AEA Assembly Language as described\n * at http://virtualagc.googlecode.com\n * <p>\n * This file could be used by goodle code to allow syntax highlight for\n * Virtual AGC SVN repository or if you don't want to commonize\n * the header for the agc/aea html assembly listing.\n *\n * @author ohommes@alumni.cmu.edu\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         // A line comment that starts with ;\n         [PR.PR_COMMENT,     /^#[^\\r\\n]*/, null, '#'],\n         // Whitespace\n         [PR.PR_PLAIN,       /^[\\t\\n\\r \\xA0]+/, null, '\\t\\n\\r \\xA0'],\n         // A double quoted, possibly multi-line, string.\n         [PR.PR_STRING,      /^\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S])*(?:\\\"|$)/, null, '\"']\n        ],\n        [\n         [PR.PR_KEYWORD, /^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\\s/,null],\n         [PR.PR_TYPE, /^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\\=?|BLOCK|BNKSUM|E?CADR|COUNT\\*?|2?DEC\\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\\s/,null],\n         // A single quote possibly followed by a word that optionally ends with\n         // = ! or ?.\n         [PR.PR_LITERAL,\n          /^\\'(?:-*(?:\\w|\\\\[\\x21-\\x7e])(?:[\\w-]*|\\\\[\\x21-\\x7e])[=!?]?)?/],\n         // Any word including labels that optionally ends with = ! or ?.\n         [PR.PR_PLAIN,\n          /^-*(?:[!-z_]|\\\\[\\x21-\\x7e])(?:[\\w-]*|\\\\[\\x21-\\x7e])[=!?]?/i],\n         // A printable non-space non-special character\n         [PR.PR_PUNCTUATION, /^[^\\w\\t\\n\\r \\xA0()\\\"\\\\\\';]+/]\n        ]),\n    ['apollo', 'agc', 'aea']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-css.js",
    "content": "// Copyright (C) 2009 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n\n/**\n * @fileoverview\n * Registers a language handler for CSS.\n *\n *\n * To use, include prettify.js and this file in your HTML page.\n * Then put your code in an HTML tag like\n *      <pre class=\"prettyprint lang-css\"></pre>\n *\n *\n * http://www.w3.org/TR/CSS21/grammar.html Section G2 defines the lexical\n * grammar.  This scheme does not recognize keywords containing escapes.\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         // The space production <s>\n         [PR.PR_PLAIN,       /^[ \\t\\r\\n\\f]+/, null, ' \\t\\r\\n\\f']\n        ],\n        [\n         // Quoted strings.  <string1> and <string2>\n         [PR.PR_STRING,\n          /^\\\"(?:[^\\n\\r\\f\\\\\\\"]|\\\\(?:\\r\\n?|\\n|\\f)|\\\\[\\s\\S])*\\\"/, null],\n         [PR.PR_STRING,\n          /^\\'(?:[^\\n\\r\\f\\\\\\']|\\\\(?:\\r\\n?|\\n|\\f)|\\\\[\\s\\S])*\\'/, null],\n         ['lang-css-str', /^url\\(([^\\)\\\"\\']*)\\)/i],\n         [PR.PR_KEYWORD,\n          /^(?:url|rgb|\\!important|@import|@page|@media|@charset|inherit)(?=[^\\-\\w]|$)/i,\n          null],\n         // A property name -- an identifier followed by a colon.\n         ['lang-css-kw', /^(-?(?:[_a-z]|(?:\\\\[0-9a-f]+ ?))(?:[_a-z0-9\\-]|\\\\(?:\\\\[0-9a-f]+ ?))*)\\s*:/i],\n         // A C style block comment.  The <comment> production.\n         [PR.PR_COMMENT, /^\\/\\*[^*]*\\*+(?:[^\\/*][^*]*\\*+)*\\//],\n         // Escaping text spans\n         [PR.PR_COMMENT, /^(?:<!--|-->)/],\n         // A number possibly containing a suffix.\n         [PR.PR_LITERAL, /^(?:\\d+|\\d*\\.\\d+)(?:%|[a-z]+)?/i],\n         // A hex color\n         [PR.PR_LITERAL, /^#(?:[0-9a-f]{3}){1,2}/i],\n         // An identifier\n         [PR.PR_PLAIN,\n          /^-?(?:[_a-z]|(?:\\\\[\\da-f]+ ?))(?:[_a-z\\d\\-]|\\\\(?:\\\\[\\da-f]+ ?))*/i],\n         // A run of punctuation\n         [PR.PR_PUNCTUATION, /^[^\\s\\w\\'\\\"]+/]\n        ]),\n    ['css']);\nPR.registerLangHandler(\n    PR.createSimpleLexer([],\n        [\n         [PR.PR_KEYWORD,\n          /^-?(?:[_a-z]|(?:\\\\[\\da-f]+ ?))(?:[_a-z\\d\\-]|\\\\(?:\\\\[\\da-f]+ ?))*/i]\n        ]),\n    ['css-kw']);\nPR.registerLangHandler(\n    PR.createSimpleLexer([],\n        [\n         [PR.PR_STRING, /^[^\\)\\\"\\']+/]\n        ]),\n    ['css-str']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-hs.js",
    "content": "// Copyright (C) 2009 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n\n/**\n * @fileoverview\n * Registers a language handler for Haskell.\n *\n *\n * To use, include prettify.js and this file in your HTML page.\n * Then put your code in an HTML tag like\n *      <pre class=\"prettyprint lang-hs\">(my lisp code)</pre>\n * The lang-cl class identifies the language as common lisp.\n * This file supports the following language extensions:\n *     lang-cl - Common Lisp\n *     lang-el - Emacs Lisp\n *     lang-lisp - Lisp\n *     lang-scm - Scheme\n *\n *\n * I used http://www.informatik.uni-freiburg.de/~thiemann/haskell/haskell98-report-html/syntax-iso.html\n * as the basis, but ignore the way the ncomment production nests since this\n * makes the lexical grammar irregular.  It might be possible to support\n * ncomments using the lookbehind filter.\n *\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         // Whitespace\n         // whitechar    ->    newline | vertab | space | tab | uniWhite\n         // newline      ->    return linefeed | return | linefeed | formfeed\n         [PR.PR_PLAIN,       /^[\\t\\n\\x0B\\x0C\\r ]+/, null, '\\t\\n\\x0B\\x0C\\r '],\n         // Single line double and single-quoted strings.\n         // char         ->    ' (graphic<' | \\> | space | escape<\\&>) '\n         // string       ->    \" {graphic<\" | \\> | space | escape | gap}\"\n         // escape       ->    \\ ( charesc | ascii | decimal | o octal\n         //                        | x hexadecimal )\n         // charesc      ->    a | b | f | n | r | t | v | \\ | \" | ' | &\n         [PR.PR_STRING,      /^\\\"(?:[^\\\"\\\\\\n\\x0C\\r]|\\\\[\\s\\S])*(?:\\\"|$)/,\n          null, '\"'],\n         [PR.PR_STRING,      /^\\'(?:[^\\'\\\\\\n\\x0C\\r]|\\\\[^&])\\'?/,\n          null, \"'\"],\n         // decimal      ->    digit{digit}\n         // octal        ->    octit{octit}\n         // hexadecimal  ->    hexit{hexit}\n         // integer      ->    decimal\n         //               |    0o octal | 0O octal\n         //               |    0x hexadecimal | 0X hexadecimal\n         // float        ->    decimal . decimal [exponent]\n         //               |    decimal exponent\n         // exponent     ->    (e | E) [+ | -] decimal\n         [PR.PR_LITERAL,\n          /^(?:0o[0-7]+|0x[\\da-f]+|\\d+(?:\\.\\d+)?(?:e[+\\-]?\\d+)?)/i,\n          null, '0123456789']\n        ],\n        [\n         // Haskell does not have a regular lexical grammar due to the nested\n         // ncomment.\n         // comment      ->    dashes [ any<symbol> {any}] newline\n         // ncomment     ->    opencom ANYseq {ncomment ANYseq}closecom\n         // dashes       ->    '--' {'-'}\n         // opencom      ->    '{-'\n         // closecom     ->    '-}'\n         [PR.PR_COMMENT,     /^(?:(?:--+(?:[^\\r\\n\\x0C]*)?)|(?:\\{-(?:[^-]|-+[^-\\}])*-\\}))/],\n         // reservedid   ->    case | class | data | default | deriving | do\n         //               |    else | if | import | in | infix | infixl | infixr\n         //               |    instance | let | module | newtype | of | then\n         //               |    type | where | _\n         [PR.PR_KEYWORD,     /^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\\']|$)/, null],\n         // qvarid       ->    [ modid . ] varid\n         // qconid       ->    [ modid . ] conid\n         // varid        ->    (small {small | large | digit | ' })<reservedid>\n         // conid        ->    large {small | large | digit | ' }\n         // modid        ->    conid\n         // small        ->    ascSmall | uniSmall | _\n         // ascSmall     ->    a | b | ... | z\n         // uniSmall     ->    any Unicode lowercase letter\n         // large        ->    ascLarge | uniLarge\n         // ascLarge     ->    A | B | ... | Z\n         // uniLarge     ->    any uppercase or titlecase Unicode letter\n         [PR.PR_PLAIN,  /^(?:[A-Z][\\w\\']*\\.)*[a-zA-Z][\\w\\']*/],\n         // matches the symbol production\n         [PR.PR_PUNCTUATION, /^[^\\t\\n\\x0B\\x0C\\r a-zA-Z0-9\\'\\\"]+/]\n        ]),\n    ['hs']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-lisp.js",
    "content": "// Copyright (C) 2008 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n\n/**\n * @fileoverview\n * Registers a language handler for Common Lisp and related languages.\n *\n *\n * To use, include prettify.js and this file in your HTML page.\n * Then put your code in an HTML tag like\n *      <pre class=\"prettyprint lang-lisp\">(my lisp code)</pre>\n * The lang-cl class identifies the language as common lisp.\n * This file supports the following language extensions:\n *     lang-cl - Common Lisp\n *     lang-el - Emacs Lisp\n *     lang-lisp - Lisp\n *     lang-scm - Scheme\n *\n *\n * I used http://www.devincook.com/goldparser/doc/meta-language/grammar-LISP.htm\n * as the basis, but added line comments that start with ; and changed the atom\n * production to disallow unquoted semicolons.\n *\n * \"Name\"    = 'LISP'\n * \"Author\"  = 'John McCarthy'\n * \"Version\" = 'Minimal'\n * \"About\"   = 'LISP is an abstract language that organizes ALL'\n *           | 'data around \"lists\".'\n *\n * \"Start Symbol\" = [s-Expression]\n *\n * {Atom Char}   = {Printable} - {Whitespace} - [()\"\\'']\n *\n * Atom = ( {Atom Char} | '\\'{Printable} )+\n *\n * [s-Expression] ::= [Quote] Atom\n *                  | [Quote] '(' [Series] ')'\n *                  | [Quote] '(' [s-Expression] '.' [s-Expression] ')'\n *\n * [Series] ::= [s-Expression] [Series]\n *            |\n *\n * [Quote]  ::= ''      !Quote = do not evaluate\n *            |\n *\n *\n * I used <a href=\"http://gigamonkeys.com/book/\">Practical Common Lisp</a> as\n * the basis for the reserved word list.\n *\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         ['opn',             /^\\(/, null, '('],\n         ['clo',             /^\\)/, null, ')'],\n         // A line comment that starts with ;\n         [PR.PR_COMMENT,     /^;[^\\r\\n]*/, null, ';'],\n         // Whitespace\n         [PR.PR_PLAIN,       /^[\\t\\n\\r \\xA0]+/, null, '\\t\\n\\r \\xA0'],\n         // A double quoted, possibly multi-line, string.\n         [PR.PR_STRING,      /^\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S])*(?:\\\"|$)/, null, '\"']\n        ],\n        [\n         [PR.PR_KEYWORD,     /^(?:block|c[ad]+r|catch|cons|defun|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\\b/, null],\n         [PR.PR_LITERAL,\n          /^[+\\-]?(?:0x[0-9a-f]+|\\d+\\/\\d+|(?:\\.\\d+|\\d+(?:\\.\\d*)?)(?:[ed][+\\-]?\\d+)?)/i],\n         // A single quote possibly followed by a word that optionally ends with\n         // = ! or ?.\n         [PR.PR_LITERAL,\n          /^\\'(?:-*(?:\\w|\\\\[\\x21-\\x7e])(?:[\\w-]*|\\\\[\\x21-\\x7e])[=!?]?)?/],\n         // A word that optionally ends with = ! or ?.\n         [PR.PR_PLAIN,\n          /^-*(?:[a-z_]|\\\\[\\x21-\\x7e])(?:[\\w-]*|\\\\[\\x21-\\x7e])[=!?]?/i],\n         // A printable non-space non-special character\n         [PR.PR_PUNCTUATION, /^[^\\w\\t\\n\\r \\xA0()\\\"\\\\\\';]+/]\n        ]),\n    ['cl', 'el', 'lisp', 'scm']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-lua.js",
    "content": "// Copyright (C) 2008 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n\n/**\n * @fileoverview\n * Registers a language handler for Lua.\n *\n *\n * To use, include prettify.js and this file in your HTML page.\n * Then put your code in an HTML tag like\n *      <pre class=\"prettyprint lang-lua\">(my Lua code)</pre>\n *\n *\n * I used http://www.lua.org/manual/5.1/manual.html#2.1\n * Because of the long-bracket concept used in strings and comments, Lua does\n * not have a regular lexical grammar, but luckily it fits within the space\n * of irregular grammars supported by javascript regular expressions.\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         // Whitespace\n         [PR.PR_PLAIN,       /^[\\t\\n\\r \\xA0]+/, null, '\\t\\n\\r \\xA0'],\n         // A double or single quoted, possibly multi-line, string.\n         [PR.PR_STRING,      /^(?:\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S])*(?:\\\"|$)|\\'(?:[^\\'\\\\]|\\\\[\\s\\S])*(?:\\'|$))/, null, '\"\\'']\n        ],\n        [\n         // A comment is either a line comment that starts with two dashes, or\n         // two dashes preceding a long bracketed block.\n         [PR.PR_COMMENT, /^--(?:\\[(=*)\\[[\\s\\S]*?(?:\\]\\1\\]|$)|[^\\r\\n]*)/],\n         // A long bracketed block not preceded by -- is a string.\n         [PR.PR_STRING,  /^\\[(=*)\\[[\\s\\S]*?(?:\\]\\1\\]|$)/],\n         [PR.PR_KEYWORD, /^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\\b/, null],\n         // A number is a hex integer literal, a decimal real literal, or in\n         // scientific notation.\n         [PR.PR_LITERAL,\n          /^[+-]?(?:0x[\\da-f]+|(?:(?:\\.\\d+|\\d+(?:\\.\\d*)?)(?:e[+\\-]?\\d+)?))/i],\n         // An identifier\n         [PR.PR_PLAIN, /^[a-z_]\\w*/i],\n         // A run of punctuation\n         [PR.PR_PUNCTUATION, /^[^\\w\\t\\n\\r \\xA0][^\\w\\t\\n\\r \\xA0\\\"\\'\\-\\+=]*/]\n        ]),\n    ['lua']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-ml.js",
    "content": "// Copyright (C) 2008 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n\n/**\n * @fileoverview\n * Registers a language handler for OCaml, SML, F# and similar languages.\n *\n * Based on the lexical grammar at\n * http://research.microsoft.com/fsharp/manual/spec2.aspx#_Toc202383715\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         // Whitespace is made up of spaces, tabs and newline characters.\n         [PR.PR_PLAIN,       /^[\\t\\n\\r \\xA0]+/, null, '\\t\\n\\r \\xA0'],\n         // #if ident/#else/#endif directives delimit conditional compilation\n         // sections\n         [PR.PR_COMMENT,\n          /^#(?:if[\\t\\n\\r \\xA0]+(?:[a-z_$][\\w\\']*|``[^\\r\\n\\t`]*(?:``|$))|else|endif|light)/i,\n          null, '#'],\n         // A double or single quoted, possibly multi-line, string.\n         // F# allows escaped newlines in strings.\n         [PR.PR_STRING,      /^(?:\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S])*(?:\\\"|$)|\\'(?:[^\\'\\\\]|\\\\[\\s\\S])*(?:\\'|$))/, null, '\"\\'']\n        ],\n        [\n         // Block comments are delimited by (* and *) and may be\n         // nested. Single-line comments begin with // and extend to\n         // the end of a line.\n         // TODO: (*...*) comments can be nested.  This does not handle that.\n         [PR.PR_COMMENT,     /^(?:\\/\\/[^\\r\\n]*|\\(\\*[\\s\\S]*?\\*\\))/],\n         [PR.PR_KEYWORD,     /^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\\b/],\n         // A number is a hex integer literal, a decimal real literal, or in\n         // scientific notation.\n         [PR.PR_LITERAL,\n          /^[+\\-]?(?:0x[\\da-f]+|(?:(?:\\.\\d+|\\d+(?:\\.\\d*)?)(?:e[+\\-]?\\d+)?))/i],\n         [PR.PR_PLAIN,       /^(?:[a-z_]\\w*[!?#]?|``[^\\r\\n\\t`]*(?:``|$))/i],\n         // A printable non-space non-special character\n         [PR.PR_PUNCTUATION, /^[^\\t\\n\\r \\xA0\\\"\\'\\w]+/]\n        ]),\n    ['fs', 'ml']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-proto.js",
    "content": "// Copyright (C) 2006 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n/**\n * @fileoverview\n * Registers a language handler for Protocol Buffers as described at\n * http://code.google.com/p/protobuf/.\n *\n * Based on the lexical grammar at\n * http://research.microsoft.com/fsharp/manual/spec2.aspx#_Toc202383715\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(PR.sourceDecorator({\n        keywords: (\n            'bool bytes default double enum extend extensions false fixed32 '\n            + 'fixed64 float group import int32 int64 max message option '\n            + 'optional package repeated required returns rpc service '\n            + 'sfixed32 sfixed64 sint32 sint64 string syntax to true uint32 '\n            + 'uint64'),\n        cStyleComments: true\n      }), ['proto']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-sql.js",
    "content": "// Copyright (C) 2008 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n\n/**\n * @fileoverview\n * Registers a language handler for SQL.\n *\n *\n * To use, include prettify.js and this file in your HTML page.\n * Then put your code in an HTML tag like\n *      <pre class=\"prettyprint lang-sql\">(my SQL code)</pre>\n *\n *\n * http://savage.net.au/SQL/sql-99.bnf.html is the basis for the grammar, and\n * http://msdn.microsoft.com/en-us/library/aa238507(SQL.80).aspx as the basis\n * for the keyword list.\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         // Whitespace\n         [PR.PR_PLAIN,       /^[\\t\\n\\r \\xA0]+/, null, '\\t\\n\\r \\xA0'],\n         // A double or single quoted, possibly multi-line, string.\n         [PR.PR_STRING,      /^(?:\"(?:[^\\\"\\\\]|\\\\.)*\"|'(?:[^\\'\\\\]|\\\\.)*')/, null,\n          '\"\\'']\n        ],\n        [\n         // A comment is either a line comment that starts with two dashes, or\n         // two dashes preceding a long bracketed block.\n         [PR.PR_COMMENT, /^(?:--[^\\r\\n]*|\\/\\*[\\s\\S]*?(?:\\*\\/|$))/],\n         [PR.PR_KEYWORD, /^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\\w-]|$)/i, null],\n         // A number is a hex integer literal, a decimal real literal, or in\n         // scientific notation.\n         [PR.PR_LITERAL,\n          /^[+-]?(?:0x[\\da-f]+|(?:(?:\\.\\d+|\\d+(?:\\.\\d*)?)(?:e[+\\-]?\\d+)?))/i],\n         // An identifier\n         [PR.PR_PLAIN, /^[a-z_][\\w-]*/i],\n         // A run of punctuation\n         [PR.PR_PUNCTUATION, /^[^\\w\\t\\n\\r \\xA0\\\"\\'][^\\w\\t\\n\\r \\xA0+\\-\\\"\\']*/]\n        ]),\n    ['sql']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-vb.js",
    "content": "// Copyright (C) 2009 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n\n/**\n * @fileoverview\n * Registers a language handler for various flavors of basic.\n *\n *\n * To use, include prettify.js and this file in your HTML page.\n * Then put your code in an HTML tag like\n *      <pre class=\"prettyprint lang-vb\"></pre>\n *\n *\n * http://msdn.microsoft.com/en-us/library/aa711638(VS.71).aspx defines the\n * visual basic grammar lexical grammar.\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         // Whitespace\n         [PR.PR_PLAIN,       /^[\\t\\n\\r \\xA0\\u2028\\u2029]+/, null, '\\t\\n\\r \\xA0\\u2028\\u2029'],\n         // A double quoted string with quotes escaped by doubling them.\n         // A single character can be suffixed with C.\n         [PR.PR_STRING,      /^(?:[\\\"\\u201C\\u201D](?:[^\\\"\\u201C\\u201D]|[\\\"\\u201C\\u201D]{2})(?:[\\\"\\u201C\\u201D]c|$)|[\\\"\\u201C\\u201D](?:[^\\\"\\u201C\\u201D]|[\\\"\\u201C\\u201D]{2})*(?:[\\\"\\u201C\\u201D]|$))/i, null,\n          '\"\\u201C\\u201D'],\n         // A comment starts with a single quote and runs until the end of the\n         // line.\n         [PR.PR_COMMENT,     /^[\\'\\u2018\\u2019][^\\r\\n\\u2028\\u2029]*/, null, '\\'\\u2018\\u2019']\n        ],\n        [\n         [PR.PR_KEYWORD, /^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\\b/i, null],\n         // A second comment form\n         [PR.PR_COMMENT, /^REM[^\\r\\n\\u2028\\u2029]*/i],\n         // A boolean, numeric, or date literal.\n         [PR.PR_LITERAL,\n          /^(?:True\\b|False\\b|Nothing\\b|\\d+(?:E[+\\-]?\\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\\d*\\.\\d+(?:E[+\\-]?\\d+)?[FRD]?|#\\s+(?:\\d+[\\-\\/]\\d+[\\-\\/]\\d+(?:\\s+\\d+:\\d+(?::\\d+)?(\\s*(?:AM|PM))?)?|\\d+:\\d+(?::\\d+)?(\\s*(?:AM|PM))?)\\s+#)/i],\n         // An identifier?\n         [PR.PR_PLAIN, /^(?:(?:[a-z]|_\\w)\\w*|\\[(?:[a-z]|_\\w)\\w*\\])/i],\n         // A run of punctuation\n         [PR.PR_PUNCTUATION,\n          /^[^\\w\\t\\n\\r \\\"\\'\\[\\]\\xA0\\u2018\\u2019\\u201C\\u201D\\u2028\\u2029]+/],\n         // Square brackets\n         [PR.PR_PUNCTUATION, /^(?:\\[|\\])/]\n        ]),\n    ['vb', 'vbs']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/lang-wiki.js",
    "content": "// Copyright (C) 2009 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n/**\n * @fileoverview\n * Registers a language handler for Wiki pages.\n *\n * Based on WikiSyntax at http://code.google.com/p/support/wiki/WikiSyntax\n *\n * @author mikesamuel@gmail.com\n */\n\nPR.registerLangHandler(\n    PR.createSimpleLexer(\n        [\n         // Whitespace\n         [PR.PR_PLAIN,       /^[\\t \\xA0a-gi-z0-9]+/, null,\n          '\\t \\xA0abcdefgijklmnopqrstuvwxyz0123456789'],\n         // Wiki formatting\n         [PR.PR_PUNCTUATION, /^[=*~\\^\\[\\]]+/, null, '=*~^[]']\n        ],\n        [\n         // Meta-info like #summary, #labels, etc.\n         ['lang-wiki.meta',  /(?:^^|\\r\\n?|\\n)(#[a-z]+)\\b/],\n         // A WikiWord\n         [PR.PR_LITERAL,     /^(?:[A-Z][a-z][a-z0-9]+[A-Z][a-z][a-zA-Z0-9]+)\\b/\n          ],\n         // A preformatted block in an unknown language\n         ['lang-',           /^\\{\\{\\{([\\s\\S]+?)\\}\\}\\}/],\n         // A block of source code in an unknown language\n         ['lang-',           /^`([^\\r\\n`]+)`/],\n         // An inline URL.\n         [PR.PR_STRING,\n          /^https?:\\/\\/[^\\/?#\\s]*(?:\\/[^?#\\s]*)?(?:\\?[^#\\s]*)?(?:#\\S*)?/i],\n         [PR.PR_PLAIN,       /^(?:\\r\\n|[\\s\\S])[^#=*~^A-Zh\\{`\\[\\r\\n]*/]\n        ]),\n    ['wiki']);\n\nPR.registerLangHandler(\n    PR.createSimpleLexer([[PR.PR_KEYWORD, /^#[a-z]+/i, null, '#']], []),\n    ['wiki.meta']);\n"
  },
  {
    "path": "GoogleCodePrettify/src/prettify.css",
    "content": "/* Pretty printing styles. Used with prettify.js. */\n\n.str { color: #B1D631; font-style: italic; }\n.kwd { color: #527AA2; }\n.com { color: #666; font-style: italic; }\n.typ { color: #FAF4C6; }\n.lit { color: #527AA2; }\n.pun { color: #FF8613; }\n.pln { color: #FAF4C6; }\n.tag { color: #527AA2; }\n.atn { color: #FAF4C6; }\n.atv { color: #B1D631; }\n.dec { color: #FAF4C6; }\ntable.prettyprint-table { padding: 2px; border: 1px solid #000; background: #222; color: #eee; font-size: 13px; margin: 0; font: 12px/1.5 'andale mono','lucida console',monospace; }\ntable.prettyprint-table pre, table.prettyprint-table table {margin: 0; background: #222; border: none; font-size: 13px;}\npre.prettyprint tr:hover td {background: #333}\ntable.prettyprint-table td.number {color: #666; font-family: \"Courier New\",Courier,monospace }\n.prettyprint-box {width: 100%; display: block; overflow-x: auto}\ntable.prettyprint-table td {padding: 2px 4px}\n\n@media print {\n  .str { color: #060; }\n  .kwd { color: #006; font-weight: bold; }\n  .com { color: #600; font-style: italic; }\n  .typ { color: #404; font-weight: bold; }\n  .lit { color: #044; }\n  .pun { color: #440; }\n  .pln { color: #000; }\n  .tag { color: #006; font-weight: bold; }\n  .atn { color: #404; }\n  .atv { color: #060; }\n}\n"
  },
  {
    "path": "GoogleCodePrettify/src/prettify.js",
    "content": "// Copyright (C) 2006 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n/**\n * @fileoverview\n * some functions for browser-side pretty printing of code contained in html.\n * <p>\n *\n * For a fairly comprehensive set of languages see the\n * <a href=\"http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs\">README</a>\n * file that came with this source.  At a minimum, the lexer should work on a\n * number of languages including C and friends, Java, Python, Bash, SQL, HTML,\n * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk\n * and a subset of Perl, but, because of commenting conventions, doesn't work on\n * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.\n * <p>\n * Usage: <ol>\n * <li> include this source file in an html page via\n *   {@code <script type=\"text/javascript\" src=\"/path/to/prettify.js\"></script>}\n * <li> define style rules.  See the example page for examples.\n * <li> mark the {@code <pre>} and {@code <code>} tags in your source with\n *    {@code class=prettyprint.}\n *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty\n *    printer needs to do more substantial DOM manipulations to support that, so\n *    some css styles may not be preserved.\n * </ol>\n * That's it.  I wanted to keep the API as simple as possible, so there's no\n * need to specify which language the code is in, but if you wish, you can add\n * another class to the {@code <pre>} or {@code <code>} element to specify the\n * language, as in {@code <pre class=\"prettyprint lang-java\">}.  Any class that\n * starts with \"lang-\" followed by a file extension, specifies the file type.\n * See the \"lang-*.js\" files in this directory for code that implements\n * per-language file handlers.\n * <p>\n * Change log:<br>\n * cbeust, 2006/08/22\n * <blockquote>\n *   Java annotations (start with \"@\") are now captured as literals (\"lit\")\n * </blockquote>\n * @requires console\n * @overrides window\n */\n\n// JSLint declarations\n/*global console, document, navigator, setTimeout, window */\n\n/**\n * Split {@code prettyPrint} into multiple timeouts so as not to interfere with\n * UI events.\n * If set to {@code false}, {@code prettyPrint()} is synchronous.\n */\nwindow['PR_SHOULD_USE_CONTINUATION'] = true;\n\n/** the number of characters between tab columns */\nwindow['PR_TAB_WIDTH'] = 8;\n\n/** Walks the DOM returning a properly escaped version of innerHTML.\n  * @param {Node} node\n  * @param {Array.<string>} out output buffer that receives chunks of HTML.\n  */\nwindow['PR_normalizedHtml']\n\n/** Contains functions for creating and registering new language handlers.\n  * @type {Object}\n  */\n  = window['PR']\n\n/** Pretty print a chunk of code.\n  *\n  * @param {string} sourceCodeHtml code as html\n  * @return {string} code as html, but prettier\n  */\n  = window['prettyPrintOne']\n/** Find all the {@code <pre>} and {@code <code>} tags in the DOM with\n  * {@code class=prettyprint} and prettify them.\n  * @param {Function?} opt_whenDone if specified, called when the last entry\n  *     has been finished.\n  */\n  = window['prettyPrint'] = void 0;\n\n/** browser detection. @extern @returns false if not IE, otherwise the major version. */\nwindow['_pr_isIE6'] = function () {\n  var ieVersion = navigator && navigator.userAgent &&\n      navigator.userAgent.match(/\\bMSIE ([678])\\./);\n  ieVersion = ieVersion ? +ieVersion[1] : false;\n  window['_pr_isIE6'] = function () { return ieVersion; };\n  return ieVersion;\n};\n\n\n(function () {\n  // Keyword lists for various languages.\n  var FLOW_CONTROL_KEYWORDS =\n      \"break continue do else for if return while \";\n  var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + \"auto case char const default \" +\n      \"double enum extern float goto int long register short signed sizeof \" +\n      \"static struct switch typedef union unsigned void volatile \";\n  var COMMON_KEYWORDS = C_KEYWORDS + \"catch class delete false import \" +\n      \"new operator private protected public this throw true try typeof \";\n  var CPP_KEYWORDS = COMMON_KEYWORDS + \"alignof align_union asm axiom bool \" +\n      \"concept concept_map const_cast constexpr decltype \" +\n      \"dynamic_cast explicit export friend inline late_check \" +\n      \"mutable namespace nullptr reinterpret_cast static_assert static_cast \" +\n      \"template typeid typename using virtual wchar_t where \";\n  var JAVA_KEYWORDS = COMMON_KEYWORDS +\n      \"abstract boolean byte extends final finally implements import \" +\n      \"instanceof null native package strictfp super synchronized throws \" +\n      \"transient \";\n  var CSHARP_KEYWORDS = JAVA_KEYWORDS +\n      \"as base by checked decimal delegate descending event \" +\n      \"fixed foreach from group implicit in interface internal into is lock \" +\n      \"object out override orderby params partial readonly ref sbyte sealed \" +\n      \"stackalloc string select uint ulong unchecked unsafe ushort var \";\n  var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +\n      \"debugger eval export function get null set undefined var with \" +\n      \"Infinity NaN \";\n  var PERL_KEYWORDS = \"caller delete die do dump elsif eval exit foreach for \" +\n      \"goto if import last local my next no our print package redo require \" +\n      \"sub undef unless until use wantarray while BEGIN END \";\n  var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + \"and as assert class def del \" +\n      \"elif except exec finally from global import in is lambda \" +\n      \"nonlocal not or pass print raise try with yield \" +\n      \"False True None \";\n  var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + \"alias and begin case class def\" +\n      \" defined elsif end ensure false in module next nil not or redo rescue \" +\n      \"retry self super then true undef unless until when yield BEGIN END \";\n  var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + \"case done elif esac eval fi \" +\n      \"function in local set then until \";\n  var ALL_KEYWORDS = (\n      CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +\n      PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);\n\n  // token style names.  correspond to css classes\n  /** token style for a string literal */\n  var PR_STRING = 'str';\n  /** token style for a keyword */\n  var PR_KEYWORD = 'kwd';\n  /** token style for a comment */\n  var PR_COMMENT = 'com';\n  /** token style for a type */\n  var PR_TYPE = 'typ';\n  /** token style for a literal value.  e.g. 1, null, true. */\n  var PR_LITERAL = 'lit';\n  /** token style for a punctuation string. */\n  var PR_PUNCTUATION = 'pun';\n  /** token style for a punctuation string. */\n  var PR_PLAIN = 'pln';\n\n  /** token style for an sgml tag. */\n  var PR_TAG = 'tag';\n  /** token style for a markup declaration such as a DOCTYPE. */\n  var PR_DECLARATION = 'dec';\n  /** token style for embedded source. */\n  var PR_SOURCE = 'src';\n  /** token style for an sgml attribute name. */\n  var PR_ATTRIB_NAME = 'atn';\n  /** token style for an sgml attribute value. */\n  var PR_ATTRIB_VALUE = 'atv';\n\n  /**\n   * A class that indicates a section of markup that is not code, e.g. to allow\n   * embedding of line numbers within code listings.\n   */\n  var PR_NOCODE = 'nocode';\n\n  /** A set of tokens that can precede a regular expression literal in\n    * javascript.\n    * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full\n    * list, but I've removed ones that might be problematic when seen in\n    * languages that don't support regular expression literals.\n    *\n    * <p>Specifically, I've removed any keywords that can't precede a regexp\n    * literal in a syntactically legal javascript program, and I've removed the\n    * \"in\" keyword since it's not a keyword in many languages, and might be used\n    * as a count of inches.\n    *\n    * <p>The link a above does not accurately describe EcmaScript rules since\n    * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works\n    * very well in practice.\n    *\n    * @private\n    */\n  var REGEXP_PRECEDER_PATTERN = function () {\n      var preceders = [\n          \"!\", \"!=\", \"!==\", \"#\", \"%\", \"%=\", \"&\", \"&&\", \"&&=\",\n          \"&=\", \"(\", \"*\", \"*=\", /* \"+\", */ \"+=\", \",\", /* \"-\", */ \"-=\",\n          \"->\", /*\".\", \"..\", \"...\", handled below */ \"/\", \"/=\", \":\", \"::\", \";\",\n          \"<\", \"<<\", \"<<=\", \"<=\", \"=\", \"==\", \"===\", \">\",\n          \">=\", \">>\", \">>=\", \">>>\", \">>>=\", \"?\", \"@\", \"[\",\n          \"^\", \"^=\", \"^^\", \"^^=\", \"{\", \"|\", \"|=\", \"||\",\n          \"||=\", \"~\" /* handles =~ and !~ */,\n          \"break\", \"case\", \"continue\", \"delete\",\n          \"do\", \"else\", \"finally\", \"instanceof\",\n          \"return\", \"throw\", \"try\", \"typeof\"\n          ];\n      var pattern = '(?:^^|[+-]';\n      for (var i = 0; i < preceders.length; ++i) {\n        pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\\\$1');\n      }\n      pattern += ')\\\\s*';  // matches at end, and matches empty string\n      return pattern;\n      // CAVEAT: this does not properly handle the case where a regular\n      // expression immediately follows another since a regular expression may\n      // have flags for case-sensitivity and the like.  Having regexp tokens\n      // adjacent is not valid in any language I'm aware of, so I'm punting.\n      // TODO: maybe style special characters inside a regexp as punctuation.\n    }();\n\n  // Define regexps here so that the interpreter doesn't have to create an\n  // object each time the function containing them is called.\n  // The language spec requires a new object created even if you don't access\n  // the $1 members.\n  var pr_amp = /&/g;\n  var pr_lt = /</g;\n  var pr_gt = />/g;\n  var pr_quot = /\\\"/g;\n  /** like textToHtml but escapes double quotes to be attribute safe. */\n  function attribToHtml(str) {\n    return str.replace(pr_amp, '&amp;')\n        .replace(pr_lt, '&lt;')\n        .replace(pr_gt, '&gt;')\n        .replace(pr_quot, '&quot;');\n  }\n\n  /** escapest html special characters to html. */\n  function textToHtml(str) {\n    return str.replace(pr_amp, '&amp;')\n        .replace(pr_lt, '&lt;')\n        .replace(pr_gt, '&gt;');\n  }\n\n\n  var pr_ltEnt = /&lt;/g;\n  var pr_gtEnt = /&gt;/g;\n  var pr_aposEnt = /&apos;/g;\n  var pr_quotEnt = /&quot;/g;\n  var pr_ampEnt = /&amp;/g;\n  var pr_nbspEnt = /&nbsp;/g;\n  /** unescapes html to plain text. */\n  function htmlToText(html) {\n    var pos = html.indexOf('&');\n    if (pos < 0) { return html; }\n    // Handle numeric entities specially.  We can't use functional substitution\n    // since that doesn't work in older versions of Safari.\n    // These should be rare since most browsers convert them to normal chars.\n    for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0;) {\n      var end = html.indexOf(';', pos);\n      if (end >= 0) {\n        var num = html.substring(pos + 3, end);\n        var radix = 10;\n        if (num && num.charAt(0) === 'x') {\n          num = num.substring(1);\n          radix = 16;\n        }\n        var codePoint = parseInt(num, radix);\n        if (!isNaN(codePoint)) {\n          html = (html.substring(0, pos) + String.fromCharCode(codePoint) +\n                  html.substring(end + 1));\n        }\n      }\n    }\n\n    return html.replace(pr_ltEnt, '<')\n        .replace(pr_gtEnt, '>')\n        .replace(pr_aposEnt, \"'\")\n        .replace(pr_quotEnt, '\"')\n        .replace(pr_nbspEnt, ' ')\n        .replace(pr_ampEnt, '&');\n  }\n\n  /** is the given node's innerHTML normally unescaped? */\n  function isRawContent(node) {\n    return 'XMP' === node.tagName;\n  }\n\n  var newlineRe = /[\\r\\n]/g;\n  /**\n   * Are newlines and adjacent spaces significant in the given node's innerHTML?\n   */\n  function isPreformatted(node, content) {\n    // PRE means preformatted, and is a very common case, so don't create\n    // unnecessary computed style objects.\n    if ('PRE' === node.tagName) { return true; }\n    if (!newlineRe.test(content)) { return true; }  // Don't care\n    var whitespace = '';\n    // For disconnected nodes, IE has no currentStyle.\n    if (node.currentStyle) {\n      whitespace = node.currentStyle.whiteSpace;\n    } else if (window.getComputedStyle) {\n      // Firefox makes a best guess if node is disconnected whereas Safari\n      // returns the empty string.\n      whitespace = window.getComputedStyle(node, null).whiteSpace;\n    }\n    return !whitespace || whitespace === 'pre';\n  }\n\n  function normalizedHtml(node, out) {\n    switch (node.nodeType) {\n      case 1:  // an element\n        var name = node.tagName.toLowerCase();\n        out.push('<', name);\n        for (var i = 0; i < node.attributes.length; ++i) {\n          var attr = node.attributes[i];\n          if (!attr.specified) { continue; }\n          out.push(' ');\n          normalizedHtml(attr, out);\n        }\n        out.push('>');\n        for (var child = node.firstChild; child; child = child.nextSibling) {\n          normalizedHtml(child, out);\n        }\n        if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {\n          out.push('<\\/', name, '>');\n        }\n        break;\n      case 2: // an attribute\n        out.push(node.name.toLowerCase(), '=\"', attribToHtml(node.value), '\"');\n        break;\n      case 3: case 4: // text\n        out.push(textToHtml(node.nodeValue));\n        break;\n    }\n  }\n\n  /**\n   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally\n   * matches the union o the sets o strings matched d by the input RegExp.\n   * Since it matches globally, if the input strings have a start-of-input\n   * anchor (/^.../), it is ignored for the purposes of unioning.\n   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.\n   * @return {RegExp} a global regex.\n   */\n  function combinePrefixPatterns(regexs) {\n    var capturedGroupIndex = 0;\n\n    var needToFoldCase = false;\n    var ignoreCase = false;\n    for (var i = 0, n = regexs.length; i < n; ++i) {\n      var regex = regexs[i];\n      if (regex.ignoreCase) {\n        ignoreCase = true;\n      } else if (/[a-z]/i.test(regex.source.replace(\n                     /\\\\u[0-9a-f]{4}|\\\\x[0-9a-f]{2}|\\\\[^ux]/gi, ''))) {\n        needToFoldCase = true;\n        ignoreCase = false;\n        break;\n      }\n    }\n\n    function decodeEscape(charsetPart) {\n      if (charsetPart.charAt(0) !== '\\\\') { return charsetPart.charCodeAt(0); }\n      switch (charsetPart.charAt(1)) {\n        case 'b': return 8;\n        case 't': return 9;\n        case 'n': return 0xa;\n        case 'v': return 0xb;\n        case 'f': return 0xc;\n        case 'r': return 0xd;\n        case 'u': case 'x':\n          return parseInt(charsetPart.substring(2), 16)\n              || charsetPart.charCodeAt(1);\n        case '0': case '1': case '2': case '3': case '4':\n        case '5': case '6': case '7':\n          return parseInt(charsetPart.substring(1), 8);\n        default: return charsetPart.charCodeAt(1);\n      }\n    }\n\n    function encodeEscape(charCode) {\n      if (charCode < 0x20) {\n        return (charCode < 0x10 ? '\\\\x0' : '\\\\x') + charCode.toString(16);\n      }\n      var ch = String.fromCharCode(charCode);\n      if (ch === '\\\\' || ch === '-' || ch === '[' || ch === ']') {\n        ch = '\\\\' + ch;\n      }\n      return ch;\n    }\n\n    function caseFoldCharset(charSet) {\n      var charsetParts = charSet.substring(1, charSet.length - 1).match(\n          new RegExp(\n              '\\\\\\\\u[0-9A-Fa-f]{4}'\n              + '|\\\\\\\\x[0-9A-Fa-f]{2}'\n              + '|\\\\\\\\[0-3][0-7]{0,2}'\n              + '|\\\\\\\\[0-7]{1,2}'\n              + '|\\\\\\\\[\\\\s\\\\S]'\n              + '|-'\n              + '|[^-\\\\\\\\]',\n              'g'));\n      var groups = [];\n      var ranges = [];\n      var inverse = charsetParts[0] === '^';\n      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {\n        var p = charsetParts[i];\n        switch (p) {\n          case '\\\\B': case '\\\\b':\n          case '\\\\D': case '\\\\d':\n          case '\\\\S': case '\\\\s':\n          case '\\\\W': case '\\\\w':\n            groups.push(p);\n            continue;\n        }\n        var start = decodeEscape(p);\n        var end;\n        if (i + 2 < n && '-' === charsetParts[i + 1]) {\n          end = decodeEscape(charsetParts[i + 2]);\n          i += 2;\n        } else {\n          end = start;\n        }\n        ranges.push([start, end]);\n        // If the range might intersect letters, then expand it.\n        if (!(end < 65 || start > 122)) {\n          if (!(end < 65 || start > 90)) {\n            ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);\n          }\n          if (!(end < 97 || start > 122)) {\n            ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);\n          }\n        }\n      }\n\n      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]\n      // -> [[1, 12], [14, 14], [16, 17]]\n      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });\n      var consolidatedRanges = [];\n      var lastRange = [NaN, NaN];\n      for (var i = 0; i < ranges.length; ++i) {\n        var range = ranges[i];\n        if (range[0] <= lastRange[1] + 1) {\n          lastRange[1] = Math.max(lastRange[1], range[1]);\n        } else {\n          consolidatedRanges.push(lastRange = range);\n        }\n      }\n\n      var out = ['['];\n      if (inverse) { out.push('^'); }\n      out.push.apply(out, groups);\n      for (var i = 0; i < consolidatedRanges.length; ++i) {\n        var range = consolidatedRanges[i];\n        out.push(encodeEscape(range[0]));\n        if (range[1] > range[0]) {\n          if (range[1] + 1 > range[0]) { out.push('-'); }\n          out.push(encodeEscape(range[1]));\n        }\n      }\n      out.push(']');\n      return out.join('');\n    }\n\n    function allowAnywhereFoldCaseAndRenumberGroups(regex) {\n      // Split into character sets, escape sequences, punctuation strings\n      // like ('(', '(?:', ')', '^'), and runs of characters that do not\n      // include any of the above.\n      var parts = regex.source.match(\n          new RegExp(\n              '(?:'\n              + '\\\\[(?:[^\\\\x5C\\\\x5D]|\\\\\\\\[\\\\s\\\\S])*\\\\]'  // a character set\n              + '|\\\\\\\\u[A-Fa-f0-9]{4}'  // a unicode escape\n              + '|\\\\\\\\x[A-Fa-f0-9]{2}'  // a hex escape\n              + '|\\\\\\\\[0-9]+'  // a back-reference or octal escape\n              + '|\\\\\\\\[^ux0-9]'  // other escape sequence\n              + '|\\\\(\\\\?[:!=]'  // start of a non-capturing group\n              + '|[\\\\(\\\\)\\\\^]'  // start/emd of a group, or line start\n              + '|[^\\\\x5B\\\\x5C\\\\(\\\\)\\\\^]+'  // run of other characters\n              + ')',\n              'g'));\n      var n = parts.length;\n\n      // Maps captured group numbers to the number they will occupy in\n      // the output or to -1 if that has not been determined, or to\n      // undefined if they need not be capturing in the output.\n      var capturedGroups = [];\n\n      // Walk over and identify back references to build the capturedGroups\n      // mapping.\n      for (var i = 0, groupIndex = 0; i < n; ++i) {\n        var p = parts[i];\n        if (p === '(') {\n          // groups are 1-indexed, so max group index is count of '('\n          ++groupIndex;\n        } else if ('\\\\' === p.charAt(0)) {\n          var decimalValue = +p.substring(1);\n          if (decimalValue && decimalValue <= groupIndex) {\n            capturedGroups[decimalValue] = -1;\n          }\n        }\n      }\n\n      // Renumber groups and reduce capturing groups to non-capturing groups\n      // where possible.\n      for (var i = 1; i < capturedGroups.length; ++i) {\n        if (-1 === capturedGroups[i]) {\n          capturedGroups[i] = ++capturedGroupIndex;\n        }\n      }\n      for (var i = 0, groupIndex = 0; i < n; ++i) {\n        var p = parts[i];\n        if (p === '(') {\n          ++groupIndex;\n          if (capturedGroups[groupIndex] === undefined) {\n            parts[i] = '(?:';\n          }\n        } else if ('\\\\' === p.charAt(0)) {\n          var decimalValue = +p.substring(1);\n          if (decimalValue && decimalValue <= groupIndex) {\n            parts[i] = '\\\\' + capturedGroups[groupIndex];\n          }\n        }\n      }\n\n      // Remove any prefix anchors so that the output will match anywhere.\n      // ^^ really does mean an anchored match though.\n      for (var i = 0, groupIndex = 0; i < n; ++i) {\n        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }\n      }\n\n      // Expand letters to groupts to handle mixing of case-sensitive and\n      // case-insensitive patterns if necessary.\n      if (regex.ignoreCase && needToFoldCase) {\n        for (var i = 0; i < n; ++i) {\n          var p = parts[i];\n          var ch0 = p.charAt(0);\n          if (p.length >= 2 && ch0 === '[') {\n            parts[i] = caseFoldCharset(p);\n          } else if (ch0 !== '\\\\') {\n            // TODO: handle letters in numeric escapes.\n            parts[i] = p.replace(\n                /[a-zA-Z]/g,\n                function (ch) {\n                  var cc = ch.charCodeAt(0);\n                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';\n                });\n          }\n        }\n      }\n\n      return parts.join('');\n    }\n\n    var rewritten = [];\n    for (var i = 0, n = regexs.length; i < n; ++i) {\n      var regex = regexs[i];\n      if (regex.global || regex.multiline) { throw new Error('' + regex); }\n      rewritten.push(\n          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');\n    }\n\n    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');\n  }\n\n  var PR_innerHtmlWorks = null;\n  function getInnerHtml(node) {\n    // inner html is hopelessly broken in Safari 2.0.4 when the content is\n    // an html description of well formed XML and the containing tag is a PRE\n    // tag, so we detect that case and emulate innerHTML.\n    if (null === PR_innerHtmlWorks) {\n      var testNode = document.createElement('PRE');\n      testNode.appendChild(\n          document.createTextNode('<!DOCTYPE foo PUBLIC \"foo bar\">\\n<foo />'));\n      PR_innerHtmlWorks = !/</.test(testNode.innerHTML);\n    }\n\n    if (PR_innerHtmlWorks) {\n      var content = node.innerHTML;\n      // XMP tags contain unescaped entities so require special handling.\n      if (isRawContent(node)) {\n        content = textToHtml(content);\n      } else if (!isPreformatted(node, content)) {\n        content = content.replace(/(<br\\s*\\/?>)[\\r\\n]+/g, '$1')\n            .replace(/(?:[\\r\\n]+[ \\t]*)+/g, ' ');\n      }\n      return content;\n    }\n\n    var out = [];\n    for (var child = node.firstChild; child; child = child.nextSibling) {\n      normalizedHtml(child, out);\n    }\n    return out.join('');\n  }\n\n  /** returns a function that expand tabs to spaces.  This function can be fed\n    * successive chunks of text, and will maintain its own internal state to\n    * keep track of how tabs are expanded.\n    * @return {function (string) : string} a function that takes\n    *   plain text and return the text with tabs expanded.\n    * @private\n    */\n  function makeTabExpander(tabWidth) {\n    var SPACES = '                ';\n    var charInLine = 0;\n\n    return function (plainText) {\n      // walk over each character looking for tabs and newlines.\n      // On tabs, expand them.  On newlines, reset charInLine.\n      // Otherwise increment charInLine\n      var out = null;\n      var pos = 0;\n      for (var i = 0, n = plainText.length; i < n; ++i) {\n        var ch = plainText.charAt(i);\n\n        switch (ch) {\n          case '\\t':\n            if (!out) { out = []; }\n            out.push(plainText.substring(pos, i));\n            // calculate how much space we need in front of this part\n            // nSpaces is the amount of padding -- the number of spaces needed\n            // to move us to the next column, where columns occur at factors of\n            // tabWidth.\n            var nSpaces = tabWidth - (charInLine % tabWidth);\n            charInLine += nSpaces;\n            for (; nSpaces >= 0; nSpaces -= SPACES.length) {\n              out.push(SPACES.substring(0, nSpaces));\n            }\n            pos = i + 1;\n            break;\n          case '\\n':\n            charInLine = 0;\n            break;\n          default:\n            ++charInLine;\n        }\n      }\n      if (!out) { return plainText; }\n      out.push(plainText.substring(pos));\n      return out.join('');\n    };\n  }\n\n  var pr_chunkPattern = new RegExp(\n      '[^<]+'  // A run of characters other than '<'\n      + '|<\\!--[\\\\s\\\\S]*?--\\>'  // an HTML comment\n      + '|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>'  // a CDATA section\n      // a probable tag that should not be highlighted\n      + '|<\\/?[a-zA-Z](?:[^>\\\"\\']|\\'[^\\']*\\'|\\\"[^\\\"]*\\\")*>'\n      + '|<',  // A '<' that does not begin a larger chunk\n      'g');\n  var pr_commentPrefix = /^<\\!--/;\n  var pr_cdataPrefix = /^<!\\[CDATA\\[/;\n  var pr_brPrefix = /^<br\\b/i;\n  var pr_tagNameRe = /^<(\\/?)([a-zA-Z][a-zA-Z0-9]*)/;\n\n  /** split markup into chunks of html tags (style null) and\n    * plain text (style {@link #PR_PLAIN}), converting tags which are\n    * significant for tokenization (<br>) into their textual equivalent.\n    *\n    * @param {string} s html where whitespace is considered significant.\n    * @return {Object} source code and extracted tags.\n    * @private\n    */\n  function extractTags(s) {\n    // since the pattern has the 'g' modifier and defines no capturing groups,\n    // this will return a list of all chunks which we then classify and wrap as\n    // PR_Tokens\n    var matches = s.match(pr_chunkPattern);\n    var sourceBuf = [];\n    var sourceBufLen = 0;\n    var extractedTags = [];\n    if (matches) {\n      for (var i = 0, n = matches.length; i < n; ++i) {\n        var match = matches[i];\n        if (match.length > 1 && match.charAt(0) === '<') {\n          if (pr_commentPrefix.test(match)) { continue; }\n          if (pr_cdataPrefix.test(match)) {\n            // strip CDATA prefix and suffix.  Don't unescape since it's CDATA\n            sourceBuf.push(match.substring(9, match.length - 3));\n            sourceBufLen += match.length - 12;\n          } else if (pr_brPrefix.test(match)) {\n            // <br> tags are lexically significant so convert them to text.\n            // This is undone later.\n            sourceBuf.push('\\n');\n            ++sourceBufLen;\n          } else {\n            if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {\n              // A <span class=\"nocode\"> will start a section that should be\n              // ignored.  Continue walking the list until we see a matching end\n              // tag.\n              var name = match.match(pr_tagNameRe)[2];\n              var depth = 1;\n              var j;\n              end_tag_loop:\n              for (j = i + 1; j < n; ++j) {\n                var name2 = matches[j].match(pr_tagNameRe);\n                if (name2 && name2[2] === name) {\n                  if (name2[1] === '/') {\n                    if (--depth === 0) { break end_tag_loop; }\n                  } else {\n                    ++depth;\n                  }\n                }\n              }\n              if (j < n) {\n                extractedTags.push(\n                    sourceBufLen, matches.slice(i, j + 1).join(''));\n                i = j;\n              } else {  // Ignore unclosed sections.\n                extractedTags.push(sourceBufLen, match);\n              }\n            } else {\n              extractedTags.push(sourceBufLen, match);\n            }\n          }\n        } else {\n          var literalText = htmlToText(match);\n          sourceBuf.push(literalText);\n          sourceBufLen += literalText.length;\n        }\n      }\n    }\n    return { source: sourceBuf.join(''), tags: extractedTags };\n  }\n\n  /** True if the given tag contains a class attribute with the nocode class. */\n  function isNoCodeTag(tag) {\n    return !!tag\n        // First canonicalize the representation of attributes\n        .replace(/\\s(\\w+)\\s*=\\s*(?:\\\"([^\\\"]*)\\\"|'([^\\']*)'|(\\S+))/g,\n                 ' $1=\"$2$3$4\"')\n        // Then look for the attribute we want.\n        .match(/[cC][lL][aA][sS][sS]=\\\"[^\\\"]*\\bnocode\\b/);\n  }\n\n  /**\n   * Apply the given language handler to sourceCode and add the resulting\n   * decorations to out.\n   * @param {number} basePos the index of sourceCode within the chunk of source\n   *    whose decorations are already present on out.\n   */\n  function appendDecorations(basePos, sourceCode, langHandler, out) {\n    if (!sourceCode) { return; }\n    var job = {\n      source: sourceCode,\n      basePos: basePos\n    };\n    langHandler(job);\n    out.push.apply(out, job.decorations);\n  }\n\n  /** Given triples of [style, pattern, context] returns a lexing function,\n    * The lexing function interprets the patterns to find token boundaries and\n    * returns a decoration list of the form\n    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]\n    * where index_n is an index into the sourceCode, and style_n is a style\n    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to\n    * all characters in sourceCode[index_n-1:index_n].\n    *\n    * The stylePatterns is a list whose elements have the form\n    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].\n    *\n    * Style is a style constant like PR_PLAIN, or can be a string of the\n    * form 'lang-FOO', where FOO is a language extension describing the\n    * language of the portion of the token in $1 after pattern executes.\n    * E.g., if style is 'lang-lisp', and group 1 contains the text\n    * '(hello (world))', then that portion of the token will be passed to the\n    * registered lisp handler for formatting.\n    * The text before and after group 1 will be restyled using this decorator\n    * so decorators should take care that this doesn't result in infinite\n    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks\n    * something like ['lang-js', /<[s]cript>(.+?)<\\/script>/].  This may match\n    * '<script>foo()<\\/script>', which would cause the current decorator to\n    * be called with '<script>' which would not match the same rule since\n    * group 1 must not be empty, so it would be instead styled as PR_TAG by\n    * the generic tag rule.  The handler registered for the 'js' extension would\n    * then be called with 'foo()', and finally, the current decorator would\n    * be called with '<\\/script>' which would not match the original rule and\n    * so the generic tag rule would identify it as a tag.\n    *\n    * Pattern must only match prefixes, and if it matches a prefix, then that\n    * match is considered a token with the same style.\n    *\n    * Context is applied to the last non-whitespace, non-comment token\n    * recognized.\n    *\n    * Shortcut is an optional string of characters, any of which, if the first\n    * character, gurantee that this pattern and only this pattern matches.\n    *\n    * @param {Array} shortcutStylePatterns patterns that always start with\n    *   a known character.  Must have a shortcut string.\n    * @param {Array} fallthroughStylePatterns patterns that will be tried in\n    *   order if the shortcut ones fail.  May have shortcuts.\n    *\n    * @return {function (Object)} a\n    *   function that takes source code and returns a list of decorations.\n    */\n  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {\n    var shortcuts = {};\n    var tokenizer;\n    (function () {\n      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);\n      var allRegexs = [];\n      var regexKeys = {};\n      for (var i = 0, n = allPatterns.length; i < n; ++i) {\n        var patternParts = allPatterns[i];\n        var shortcutChars = patternParts[3];\n        if (shortcutChars) {\n          for (var c = shortcutChars.length; --c >= 0;) {\n            shortcuts[shortcutChars.charAt(c)] = patternParts;\n          }\n        }\n        var regex = patternParts[1];\n        var k = '' + regex;\n        if (!regexKeys.hasOwnProperty(k)) {\n          allRegexs.push(regex);\n          regexKeys[k] = null;\n        }\n      }\n      allRegexs.push(/[\\0-\\uffff]/);\n      tokenizer = combinePrefixPatterns(allRegexs);\n    })();\n\n    var nPatterns = fallthroughStylePatterns.length;\n    var notWs = /\\S/;\n\n    /**\n     * Lexes job.source and produces an output array job.decorations of style\n     * classes preceded by the position at which they start in job.source in\n     * order.\n     *\n     * @param {Object} job an object like {@code\n     *    source: {string} sourceText plain text,\n     *    basePos: {int} position of job.source in the larger chunk of\n     *        sourceCode.\n     * }\n     */\n    var decorate = function (job) {\n      var sourceCode = job.source, basePos = job.basePos;\n      /** Even entries are positions in source in ascending order.  Odd enties\n        * are style markers (e.g., PR_COMMENT) that run from that position until\n        * the end.\n        * @type {Array.<number|string>}\n        */\n      var decorations = [basePos, PR_PLAIN];\n      var pos = 0;  // index into sourceCode\n      var tokens = sourceCode.match(tokenizer) || [];\n      var styleCache = {};\n\n      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {\n        var token = tokens[ti];\n        var style = styleCache[token];\n        var match = void 0;\n\n        var isEmbedded;\n        if (typeof style === 'string') {\n          isEmbedded = false;\n        } else {\n          var patternParts = shortcuts[token.charAt(0)];\n          if (patternParts) {\n            match = token.match(patternParts[1]);\n            style = patternParts[0];\n          } else {\n            for (var i = 0; i < nPatterns; ++i) {\n              patternParts = fallthroughStylePatterns[i];\n              match = token.match(patternParts[1]);\n              if (match) {\n                style = patternParts[0];\n                break;\n              }\n            }\n\n            if (!match) {  // make sure that we make progress\n              style = PR_PLAIN;\n            }\n          }\n\n          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);\n          if (isEmbedded && !(match && typeof match[1] === 'string')) {\n            isEmbedded = false;\n            style = PR_SOURCE;\n          }\n\n          if (!isEmbedded) { styleCache[token] = style; }\n        }\n\n        var tokenStart = pos;\n        pos += token.length;\n\n        if (!isEmbedded) {\n          decorations.push(basePos + tokenStart, style);\n        } else {  // Treat group 1 as an embedded block of source code.\n          var embeddedSource = match[1];\n          var embeddedSourceStart = token.indexOf(embeddedSource);\n          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;\n          if (match[2]) {\n            // If embeddedSource can be blank, then it would match at the\n            // beginning which would cause us to infinitely recurse on the\n            // entire token, so we catch the right context in match[2].\n            embeddedSourceEnd = token.length - match[2].length;\n            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;\n          }\n          var lang = style.substring(5);\n          // Decorate the left of the embedded source\n          appendDecorations(\n              basePos + tokenStart,\n              token.substring(0, embeddedSourceStart),\n              decorate, decorations);\n          // Decorate the embedded source\n          appendDecorations(\n              basePos + tokenStart + embeddedSourceStart,\n              embeddedSource,\n              langHandlerForExtension(lang, embeddedSource),\n              decorations);\n          // Decorate the right of the embedded section\n          appendDecorations(\n              basePos + tokenStart + embeddedSourceEnd,\n              token.substring(embeddedSourceEnd),\n              decorate, decorations);\n        }\n      }\n      job.decorations = decorations;\n    };\n    return decorate;\n  }\n\n  /** returns a function that produces a list of decorations from source text.\n    *\n    * This code treats \", ', and ` as string delimiters, and \\ as a string\n    * escape.  It does not recognize perl's qq() style strings.\n    * It has no special handling for double delimiter escapes as in basic, or\n    * the tripled delimiters used in python, but should work on those regardless\n    * although in those cases a single string literal may be broken up into\n    * multiple adjacent string literals.\n    *\n    * It recognizes C, C++, and shell style comments.\n    *\n    * @param {Object} options a set of optional parameters.\n    * @return {function (Object)} a function that examines the source code\n    *     in the input job and builds the decoration list.\n    */\n  function sourceDecorator(options) {\n    var shortcutStylePatterns = [], fallthroughStylePatterns = [];\n    if (options['tripleQuotedStrings']) {\n      // '''multi-line-string''', 'single-line-string', and double-quoted\n      shortcutStylePatterns.push(\n          [PR_STRING,  /^(?:\\'\\'\\'(?:[^\\'\\\\]|\\\\[\\s\\S]|\\'{1,2}(?=[^\\']))*(?:\\'\\'\\'|$)|\\\"\\\"\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S]|\\\"{1,2}(?=[^\\\"]))*(?:\\\"\\\"\\\"|$)|\\'(?:[^\\\\\\']|\\\\[\\s\\S])*(?:\\'|$)|\\\"(?:[^\\\\\\\"]|\\\\[\\s\\S])*(?:\\\"|$))/,\n           null, '\\'\"']);\n    } else if (options['multiLineStrings']) {\n      // 'multi-line-string', \"multi-line-string\"\n      shortcutStylePatterns.push(\n          [PR_STRING,  /^(?:\\'(?:[^\\\\\\']|\\\\[\\s\\S])*(?:\\'|$)|\\\"(?:[^\\\\\\\"]|\\\\[\\s\\S])*(?:\\\"|$)|\\`(?:[^\\\\\\`]|\\\\[\\s\\S])*(?:\\`|$))/,\n           null, '\\'\"`']);\n    } else {\n      // 'single-line-string', \"single-line-string\"\n      shortcutStylePatterns.push(\n          [PR_STRING,\n           /^(?:\\'(?:[^\\\\\\'\\r\\n]|\\\\.)*(?:\\'|$)|\\\"(?:[^\\\\\\\"\\r\\n]|\\\\.)*(?:\\\"|$))/,\n           null, '\"\\'']);\n    }\n    if (options['verbatimStrings']) {\n      // verbatim-string-literal production from the C# grammar.  See issue 93.\n      fallthroughStylePatterns.push(\n          [PR_STRING, /^@\\\"(?:[^\\\"]|\\\"\\\")*(?:\\\"|$)/, null]);\n    }\n    if (options['hashComments']) {\n      if (options['cStyleComments']) {\n        // Stop C preprocessor declarations at an unclosed open comment\n        shortcutStylePatterns.push(\n            [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\\b|[^\\r\\n]*)/,\n             null, '#']);\n        fallthroughStylePatterns.push(\n            [PR_STRING,\n             /^<(?:(?:(?:\\.\\.\\/)*|\\/?)(?:[\\w-]+(?:\\/[\\w-]+)+)?[\\w-]+\\.h|[a-z]\\w*)>/,\n             null]);\n      } else {\n        shortcutStylePatterns.push([PR_COMMENT, /^#[^\\r\\n]*/, null, '#']);\n      }\n    }\n    if (options['cStyleComments']) {\n      fallthroughStylePatterns.push([PR_COMMENT, /^\\/\\/[^\\r\\n]*/, null]);\n      fallthroughStylePatterns.push(\n          [PR_COMMENT, /^\\/\\*[\\s\\S]*?(?:\\*\\/|$)/, null]);\n    }\n    if (options['regexLiterals']) {\n      var REGEX_LITERAL = (\n          // A regular expression literal starts with a slash that is\n          // not followed by * or / so that it is not confused with\n          // comments.\n          '/(?=[^/*])'\n          // and then contains any number of raw characters,\n          + '(?:[^/\\\\x5B\\\\x5C]'\n          // escape sequences (\\x5C),\n          +    '|\\\\x5C[\\\\s\\\\S]'\n          // or non-nesting character sets (\\x5B\\x5D);\n          +    '|\\\\x5B(?:[^\\\\x5C\\\\x5D]|\\\\x5C[\\\\s\\\\S])*(?:\\\\x5D|$))+'\n          // finally closed by a /.\n          + '/');\n      fallthroughStylePatterns.push(\n          ['lang-regex',\n           new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')\n           ]);\n    }\n\n    var keywords = options['keywords'].replace(/^\\s+|\\s+$/g, '');\n    if (keywords.length) {\n      fallthroughStylePatterns.push(\n          [PR_KEYWORD,\n           new RegExp('^(?:' + keywords.replace(/\\s+/g, '|') + ')\\\\b'), null]);\n    }\n\n    shortcutStylePatterns.push([PR_PLAIN,       /^\\s+/, null, ' \\r\\n\\t\\xA0']);\n    fallthroughStylePatterns.push(\n        // TODO(mikesamuel): recognize non-latin letters and numerals in idents\n        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],\n        [PR_TYPE,        /^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, null],\n        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],\n        [PR_LITERAL,\n         new RegExp(\n             '^(?:'\n             // A hex number\n             + '0x[a-f0-9]+'\n             // or an octal or decimal number,\n             + '|(?:\\\\d(?:_\\\\d+)*\\\\d*(?:\\\\.\\\\d*)?|\\\\.\\\\d\\\\+)'\n             // possibly in scientific notation\n             + '(?:e[+\\\\-]?\\\\d+)?'\n             + ')'\n             // with an optional modifier like UL for unsigned long\n             + '[a-z]*', 'i'),\n         null, '0123456789'],\n        [PR_PUNCTUATION, /^.[^\\s\\w\\.$@\\'\\\"\\`\\/\\#]*/, null]);\n\n    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);\n  }\n\n  var decorateSource = sourceDecorator({\n        'keywords': ALL_KEYWORDS,\n        'hashComments': true,\n        'cStyleComments': true,\n        'multiLineStrings': true,\n        'regexLiterals': true\n      });\n\n  /** Breaks {@code job.source} around style boundaries in\n    * {@code job.decorations} while re-interleaving {@code job.extractedTags},\n    * and leaves the result in {@code job.prettyPrintedHtml}.\n    * @param {Object} job like {\n    *    source: {string} source as plain text,\n    *    extractedTags: {Array.<number|string>} extractedTags chunks of raw\n    *                   html preceded by their position in {@code job.source}\n    *                   in order\n    *    decorations: {Array.<number|string} an array of style classes preceded\n    *                 by the position at which they start in job.source in order\n    * }\n    * @private\n    */\n  function recombineTagsAndDecorations(job) {\n    var sourceText = job.source;\n    var extractedTags = job.extractedTags;\n    var decorations = job.decorations;\n\n    var html = [];\n    // index past the last char in sourceText written to html\n    var outputIdx = 0;\n\n    var openDecoration = null;\n    var currentDecoration = null;\n    var tagPos = 0;  // index into extractedTags\n    var decPos = 0;  // index into decorations\n    var tabExpander = makeTabExpander(window['PR_TAB_WIDTH']);\n\n    var adjacentSpaceRe = /([\\r\\n ]) /g;\n    var startOrSpaceRe = /(^| ) /gm;\n    var newlineRe = /\\r\\n?|\\n/g;\n    var trailingSpaceRe = /[ \\r\\n]$/;\n    var lastWasSpace = true;  // the last text chunk emitted ended with a space.\n\n    // A helper function that is responsible for opening sections of decoration\n    // and outputing properly escaped chunks of source\n    function emitTextUpTo(sourceIdx) {\n      if (sourceIdx > outputIdx) {\n        if (openDecoration && openDecoration !== currentDecoration) {\n          // Close the current decoration\n          html.push('</span>');\n          openDecoration = null;\n        }\n        if (!openDecoration && currentDecoration) {\n          openDecoration = currentDecoration;\n          html.push('<span class=\"', openDecoration, '\">');\n        }\n        // This interacts badly with some wikis which introduces paragraph tags\n        // into pre blocks for some strange reason.\n        // It's necessary for IE though which seems to lose the preformattedness\n        // of <pre> tags when their innerHTML is assigned.\n        // http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html\n        // and it serves to undo the conversion of <br>s to newlines done in\n        // chunkify.\n        var htmlChunk = textToHtml(\n            tabExpander(sourceText.substring(outputIdx, sourceIdx)))\n            .replace(lastWasSpace\n                     ? startOrSpaceRe\n                     : adjacentSpaceRe, '$1&nbsp;');\n        // Keep track of whether we need to escape space at the beginning of the\n        // next chunk.\n        lastWasSpace = trailingSpaceRe.test(htmlChunk);\n        // IE collapses multiple adjacient <br>s into 1 line break.\n        // Prefix every <br> with '&nbsp;' can prevent such IE's behavior.\n        var lineBreakHtml = window['_pr_isIE6']() ? '&nbsp;<br />' : '<br />';\n        html.push(htmlChunk.replace(newlineRe, lineBreakHtml));\n        outputIdx = sourceIdx;\n      }\n    }\n\n    while (true) {\n      // Determine if we're going to consume a tag this time around.  Otherwise\n      // we consume a decoration or exit.\n      var outputTag;\n      if (tagPos < extractedTags.length) {\n        if (decPos < decorations.length) {\n          // Pick one giving preference to extractedTags since we shouldn't open\n          // a new style that we're going to have to immediately close in order\n          // to output a tag.\n          outputTag = extractedTags[tagPos] <= decorations[decPos];\n        } else {\n          outputTag = true;\n        }\n      } else {\n        outputTag = false;\n      }\n      // Consume either a decoration or a tag or exit.\n      if (outputTag) {\n        emitTextUpTo(extractedTags[tagPos]);\n        if (openDecoration) {\n          // Close the current decoration\n          html.push('</span>');\n          openDecoration = null;\n        }\n        html.push(extractedTags[tagPos + 1]);\n        tagPos += 2;\n      } else if (decPos < decorations.length) {\n        emitTextUpTo(decorations[decPos]);\n        currentDecoration = decorations[decPos + 1];\n        decPos += 2;\n      } else {\n        break;\n      }\n    }\n    emitTextUpTo(sourceText.length);\n    if (openDecoration) {\n      html.push('</span>');\n    }\n    job.prettyPrintedHtml = html.join('');\n  }\n\n  /** Maps language-specific file extensions to handlers. */\n  var langHandlerRegistry = {};\n  /** Register a language handler for the given file extensions.\n    * @param {function (Object)} handler a function from source code to a list\n    *      of decorations.  Takes a single argument job which describes the\n    *      state of the computation.   The single parameter has the form\n    *      {@code {\n    *        source: {string} as plain text.\n    *        decorations: {Array.<number|string>} an array of style classes\n    *                     preceded by the position at which they start in\n    *                     job.source in order.\n    *                     The language handler should assigned this field.\n    *        basePos: {int} the position of source in the larger source chunk.\n    *                 All positions in the output decorations array are relative\n    *                 to the larger source chunk.\n    *      } }\n    * @param {Array.<string>} fileExtensions\n    */\n  function registerLangHandler(handler, fileExtensions) {\n    for (var i = fileExtensions.length; --i >= 0;) {\n      var ext = fileExtensions[i];\n      if (!langHandlerRegistry.hasOwnProperty(ext)) {\n        langHandlerRegistry[ext] = handler;\n      } else if ('console' in window) {\n        console.warn('cannot override language handler %s', ext);\n      }\n    }\n  }\n  function langHandlerForExtension(extension, source) {\n    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {\n      // Treat it as markup if the first non whitespace character is a < and\n      // the last non-whitespace character is a >.\n      extension = /^\\s*</.test(source)\n          ? 'default-markup'\n          : 'default-code';\n    }\n    return langHandlerRegistry[extension];\n  }\n  registerLangHandler(decorateSource, ['default-code']);\n  registerLangHandler(\n      createSimpleLexer(\n          [],\n          [\n           [PR_PLAIN,       /^[^<?]+/],\n           [PR_DECLARATION, /^<!\\w[^>]*(?:>|$)/],\n           [PR_COMMENT,     /^<\\!--[\\s\\S]*?(?:-\\->|$)/],\n           // Unescaped content in an unknown language\n           ['lang-',        /^<\\?([\\s\\S]+?)(?:\\?>|$)/],\n           ['lang-',        /^<%([\\s\\S]+?)(?:%>|$)/],\n           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],\n           ['lang-',        /^<xmp\\b[^>]*>([\\s\\S]+?)<\\/xmp\\b[^>]*>/i],\n           // Unescaped content in javascript.  (Or possibly vbscript).\n           ['lang-js',      /^<script\\b[^>]*>([\\s\\S]*?)(<\\/script\\b[^>]*>)/i],\n           // Contains unescaped stylesheet content\n           ['lang-css',     /^<style\\b[^>]*>([\\s\\S]*?)(<\\/style\\b[^>]*>)/i],\n           ['lang-in.tag',  /^(<\\/?[a-z][^<>]*>)/i]\n          ]),\n      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);\n  registerLangHandler(\n      createSimpleLexer(\n          [\n           [PR_PLAIN,        /^[\\s]+/, null, ' \\t\\r\\n'],\n           [PR_ATTRIB_VALUE, /^(?:\\\"[^\\\"]*\\\"?|\\'[^\\']*\\'?)/, null, '\\\"\\'']\n           ],\n          [\n           [PR_TAG,          /^^<\\/?[a-z](?:[\\w.:-]*\\w)?|\\/?>$/i],\n           [PR_ATTRIB_NAME,  /^(?!style[\\s=]|on)[a-z](?:[\\w:-]*\\w)?/i],\n           ['lang-uq.val',   /^=\\s*([^>\\'\\\"\\s]*(?:[^>\\'\\\"\\s\\/]|\\/(?=\\s)))/],\n           [PR_PUNCTUATION,  /^[=<>\\/]+/],\n           ['lang-js',       /^on\\w+\\s*=\\s*\\\"([^\\\"]+)\\\"/i],\n           ['lang-js',       /^on\\w+\\s*=\\s*\\'([^\\']+)\\'/i],\n           ['lang-js',       /^on\\w+\\s*=\\s*([^\\\"\\'>\\s]+)/i],\n           ['lang-css',      /^style\\s*=\\s*\\\"([^\\\"]+)\\\"/i],\n           ['lang-css',      /^style\\s*=\\s*\\'([^\\']+)\\'/i],\n           ['lang-css',      /^style\\s*=\\s*([^\\\"\\'>\\s]+)/i]\n           ]),\n      ['in.tag']);\n  registerLangHandler(\n      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\\s\\S]+/]]), ['uq.val']);\n  registerLangHandler(sourceDecorator({\n          'keywords': CPP_KEYWORDS,\n          'hashComments': true,\n          'cStyleComments': true\n        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);\n  registerLangHandler(sourceDecorator({\n          'keywords': 'null true false'\n        }), ['json']);\n  registerLangHandler(sourceDecorator({\n          'keywords': CSHARP_KEYWORDS,\n          'hashComments': true,\n          'cStyleComments': true,\n          'verbatimStrings': true\n        }), ['cs']);\n  registerLangHandler(sourceDecorator({\n          'keywords': JAVA_KEYWORDS,\n          'cStyleComments': true\n        }), ['java']);\n  registerLangHandler(sourceDecorator({\n          'keywords': SH_KEYWORDS,\n          'hashComments': true,\n          'multiLineStrings': true\n        }), ['bsh', 'csh', 'sh']);\n  registerLangHandler(sourceDecorator({\n          'keywords': PYTHON_KEYWORDS,\n          'hashComments': true,\n          'multiLineStrings': true,\n          'tripleQuotedStrings': true\n        }), ['cv', 'py']);\n  registerLangHandler(sourceDecorator({\n          'keywords': PERL_KEYWORDS,\n          'hashComments': true,\n          'multiLineStrings': true,\n          'regexLiterals': true\n        }), ['perl', 'pl', 'pm']);\n  registerLangHandler(sourceDecorator({\n          'keywords': RUBY_KEYWORDS,\n          'hashComments': true,\n          'multiLineStrings': true,\n          'regexLiterals': true\n        }), ['rb']);\n  registerLangHandler(sourceDecorator({\n          'keywords': JSCRIPT_KEYWORDS,\n          'cStyleComments': true,\n          'regexLiterals': true\n        }), ['js']);\n  registerLangHandler(\n      createSimpleLexer([], [[PR_STRING, /^[\\s\\S]+/]]), ['regex']);\n\n  function applyDecorator(job) {\n    var sourceCodeHtml = job.sourceCodeHtml;\n    var opt_langExtension = job.langExtension;\n\n    // Prepopulate output in case processing fails with an exception.\n    job.prettyPrintedHtml = sourceCodeHtml;\n\n    try {\n      // Extract tags, and convert the source code to plain text.\n      var sourceAndExtractedTags = extractTags(sourceCodeHtml);\n      /** Plain text. @type {string} */\n      var source = sourceAndExtractedTags.source;\n      job.source = source;\n      job.basePos = 0;\n\n      /** Even entries are positions in source in ascending order.  Odd entries\n        * are tags that were extracted at that position.\n        * @type {Array.<number|string>}\n        */\n      job.extractedTags = sourceAndExtractedTags.tags;\n\n      // Apply the appropriate language handler\n      langHandlerForExtension(opt_langExtension, source)(job);\n      // Integrate the decorations and tags back into the source code to produce\n      // a decorated html string which is left in job.prettyPrintedHtml.\n      recombineTagsAndDecorations(job);\n    } catch (e) {\n      if ('console' in window) {\n        console.log(e);\n        console.trace();\n      }\n    }\n  }\n\n  function prettyPrintOne(sourceCodeHtml, opt_langExtension) {\n    var job = {\n      sourceCodeHtml: sourceCodeHtml,\n      langExtension: opt_langExtension\n    };\n    applyDecorator(job);\n    return job.prettyPrintedHtml;\n  }\n\n  function prettyPrint(opt_whenDone) {\n    var isIE678 = window['_pr_isIE6']();\n    var ieNewline = isIE678 === 6 ? '\\r\\n' : '\\r';\n    // See bug 71 and http://stackoverflow.com/questions/136443/why-doesnt-ie7-\n\n    // fetch a list of nodes to rewrite\n    var codeSegments = [\n        document.getElementsByTagName('pre'),\n        document.getElementsByTagName('code'),\n        document.getElementsByTagName('xmp') ];\n    var elements = [];\n    for (var i = 0; i < codeSegments.length; ++i) {\n      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {\n        elements.push(codeSegments[i][j]);\n      }\n    }\n    codeSegments = null;\n\n    var clock = Date;\n    if (!clock['now']) {\n      clock = { 'now': function () { return (new Date).getTime(); } };\n    }\n\n    // The loop is broken into a series of continuations to make sure that we\n    // don't make the browser unresponsive when rewriting a large page.\n    var k = 0;\n    var prettyPrintingJob;\n\n    function doWork() {\n      var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?\n                     clock.now() + 250 /* ms */ :\n                     Infinity);\n      for (; k < elements.length && clock.now() < endTime; k++) {\n        var cs = elements[k];\n        if (cs.className && cs.className.indexOf('prettyprint') >= 0) {\n          // If the classes includes a language extensions, use it.\n          // Language extensions can be specified like\n          //     <pre class=\"prettyprint lang-cpp\">\n          // the language extension \"cpp\" is used to find a language handler as\n          // passed to PR_registerLangHandler.\n          var langExtension = cs.className.match(/\\blang-(\\w+)\\b/);\n          if (langExtension) { langExtension = langExtension[1]; }\n\n          // make sure this is not nested in an already prettified element\n          var nested = false;\n          for (var p = cs.parentNode; p; p = p.parentNode) {\n            if ((p.tagName === 'pre' || p.tagName === 'code' ||\n                 p.tagName === 'xmp') &&\n                p.className && p.className.indexOf('prettyprint') >= 0) {\n              nested = true;\n              break;\n            }\n          }\n          if (!nested) {\n            // fetch the content as a snippet of properly escaped HTML.\n            // Firefox adds newlines at the end.\n            var content = getInnerHtml(cs);\n            content = content.replace(/(?:\\r\\n?|\\n)$/, '');\n\n            // do the pretty printing\n            prettyPrintingJob = {\n              sourceCodeHtml: content,\n              langExtension: langExtension,\n              sourceNode: cs\n            };\n            applyDecorator(prettyPrintingJob);\n            replaceWithPrettyPrintedHtml();\n          }\n        }\n      }\n      if (k < elements.length) {\n        // finish up in a continuation\n        setTimeout(doWork, 250);\n      } else if (opt_whenDone) {\n        opt_whenDone();\n      }\n    }\n\n    function replaceWithPrettyPrintedHtml() {\n      var newContent = prettyPrintingJob.prettyPrintedHtml;\n      if (!newContent) { return; }\n      var cs = prettyPrintingJob.sourceNode;\n\n      // push the prettified html back into the tag.\n      if (!isRawContent(cs)) {\n        // just replace the old html with the new\n        cs.innerHTML = newContent;\n      } else {\n        // we need to change the tag to a <pre> since <xmp>s do not allow\n        // embedded tags such as the span tags used to attach styles to\n        // sections of source code.\n        var pre = document.createElement('PRE');\n        for (var i = 0; i < cs.attributes.length; ++i) {\n          var a = cs.attributes[i];\n          if (a.specified) {\n            var aname = a.name.toLowerCase();\n            if (aname === 'class') {\n              pre.className = a.value;  // For IE 6\n            } else {\n              pre.setAttribute(a.name, a.value);\n            }\n          }\n        }\n        pre.innerHTML = newContent;\n\n        // remove the old\n        cs.parentNode.replaceChild(pre, cs);\n        cs = pre;\n      }\n\n      // Replace <br>s with line-feeds so that copying and pasting works\n      // on IE 6.\n      // Doing this on other browsers breaks lots of stuff since \\r\\n is\n      // treated as two newlines on Firefox, and doing this also slows\n      // down rendering.\n      if (isIE678 && cs.tagName === 'PRE') {\n        var lineBreaks = cs.getElementsByTagName('br');\n        for (var j = lineBreaks.length; --j >= 0;) {\n          var lineBreak = lineBreaks[j];\n          lineBreak.parentNode.replaceChild(\n              document.createTextNode(ieNewline), lineBreak);\n        }\n      }\n    }\n\n    doWork();\n  }\n\n  window['PR_normalizedHtml'] = normalizedHtml;\n  window['prettyPrintOne'] = prettyPrintOne;\n  window['prettyPrint'] = prettyPrint;\n  window['PR'] = {\n        'combinePrefixPatterns': combinePrefixPatterns,\n        'createSimpleLexer': createSimpleLexer,\n        'registerLangHandler': registerLangHandler,\n        'sourceDecorator': sourceDecorator,\n        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,\n        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,\n        'PR_COMMENT': PR_COMMENT,\n        'PR_DECLARATION': PR_DECLARATION,\n        'PR_KEYWORD': PR_KEYWORD,\n        'PR_LITERAL': PR_LITERAL,\n        'PR_NOCODE': PR_NOCODE,\n        'PR_PLAIN': PR_PLAIN,\n        'PR_PUNCTUATION': PR_PUNCTUATION,\n        'PR_SOURCE': PR_SOURCE,\n        'PR_STRING': PR_STRING,\n        'PR_TAG': PR_TAG,\n        'PR_TYPE': PR_TYPE\n      };\n})();\n"
  },
  {
    "path": "GoogleCodeSVN/Action.php",
    "content": "<?php\n\nclass GoogleCodeSVN_Action extends Widget_Abstract_Contents implements Widget_Interface_Do\n{\n    private function parseFileName($fileName, $repositoryPath)\n    {\n        $result = array(\n            'do'            =>  'publish',\n            'allowComment'  =>  $this->options->defaultAllowComment,\n            'allowPing'     =>  $this->options->defaultAllowPing,\n            'allowFeed'     =>  $this->options->defaultAllowFeed\n        );\n    \n        $basePath = Helper::options()->plugin('GoogleCodeSVN')->basePath;\n        $basePath = '/' . trim($basePath, '/') . '/';\n        \n        if (0 !== strpos($fileName, $basePath)) {\n            return false;\n        }\n        \n        $path = substr($fileName, strlen($basePath));\n        $part = explode('/', $path);\n        \n        if (2 != count($part)) {\n            return false;\n        }\n        \n        list($categoryName, $baseName) = $part;\n        list($slug) = explode('.', $baseName);\n        \n        $result['slug'] = $slug;\n        \n        $post = $this->db->fetchRow($this->db->select()\n        ->from('table.contents')->where('slug = ?', $slug)->limit(1));\n        \n        if (!empty($post)) {\n            if ('post' != $post['type']) {\n                return false;\n            } else {\n                $result['cid'] = $post['cid'];\n            }\n        }\n        \n        /** 将目录作为分类缩略名处理 */\n        $categorySlug = Typecho_Common::slugName($categoryName);\n        \n        $category = $this->db->fetchRow($this->db->select()\n        ->from('table.metas')->where('slug = ? OR name = ?', $categorySlug, $categoryName)\n        ->where('type = ?', 'category')->limit(1));\n        \n        /** 如果分类不存在则直接重建分类 */\n        if (empty($category)) {\n            $input['name'] = $categoryName;\n            $input['slug'] = $categorySlug;\n            $input['type'] = 'category';\n            $input['description'] = $categoryName;\n            $input['do'] = 'insert';\n            \n            $this->widget('Widget_Metas_Category_Edit', NULL, $input, false)->action();\n            $result['category'] = array($this->widget('Widget_Notice')->getHighlightId());\n        } else {\n            $result['category'] = array($category['mid']);\n        }\n        \n        $url = rtrim($repositoryPath, '/') . $fileName;\n        \n        $client = Typecho_Http_Client::get('Curl', 'Socket');\n        if (false == $client) {\n            return false;\n        }\n        \n        $client->send($url);\n        $result['text'] = '';\n        $result['title'] = '';\n        \n        if (200 == $client->getResponseStatus() || 304 == $client->getResponseStatus()) {\n            $response = trim($client->getResponseBody());\n            \n            list($title, $text) = explode(\"\\n\", $response, 2);\n            $result['title'] = $title;\n            $result['text'] = $text;\n        }\n        \n        return $result;\n    }\n\n    public function action()\n    {\n        /** 验证合法性 */\n        if (!isset($_SERVER['HTTP_GOOGLE_CODE_PROJECT_HOSTING_HOOK_HMAC'])) {\n            return;\n        }\n    \n        $googleSecretInfo = $_SERVER['HTTP_GOOGLE_CODE_PROJECT_HOSTING_HOOK_HMAC'];\n        $revisionData = file_get_contents('php://input');\n        \n        if (empty($revisionData)) {\n            return;\n        }\n        \n        $secretVerify = hash_hmac(\"md5\", $revisionData, Helper::options()->plugin('GoogleCodeSVN')->secretKey);\n        \n        if ($googleSecretInfo != $secretVerify) {\n            return;\n        }\n        \n        $data = Typecho_Json::decode($revisionData);\n        \n        if (!$data) {\n            return;\n        }\n        \n        /** 登录用户 */\n        $master = $this->db->fetchRow($this->db->select()->from('table.users')\n            ->where('group = ?', 'administrator')\n            ->order('uid', Typecho_Db::SORT_ASC)\n            ->limit(1));\n        \n        if (empty($master)) {\n            return false;\n        } else if (!$this->user->simpleLogin($master['uid'])) {\n            return false;\n        }\n        \n        if (isset($data->revisions) && is_array($data->revisions)) {\n            foreach ($data->revisions as $revision) {\n                if (!empty($revision->added)) {\n                    foreach ($revision->added as $file) {\n                        $input = $this->parseFileName($file, $data->repository_path);\n                        if ($input) {\n                            $this->widget('Widget_Contents_Post_Edit', NULL, $input, false)->action();\n                        }\n                    }\n                }\n                \n                if (!empty($revision->modified)) {\n                    foreach ($revision->modified as $file) {\n                        $input = $this->parseFileName($file, $data->repository_path);\n                        if ($input) {\n                            $this->widget('Widget_Contents_Post_Edit', NULL, $input, false)->action();\n                        }\n                    }\n                }\n                \n                if (!empty($revision->removed)) {\n                    foreach ($revision->removed as $file) {\n                        $input = $this->parseFileName($file, $data->repository_path);\n                        if ($input && isset($input['cid'])) {\n                            $postId = $input['cid'];\n                            $this->widget('Widget_Contents_Post_Edit', NULL, \"cid={$postId}\", false)->deletePost();\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "GoogleCodeSVN/Plugin.php",
    "content": "<?php\n/**\n * google code svn 同步文章\n * \n * @package Google Code SVN Transmit\n * @author qining\n * @version 1.0.0\n * @dependence 10.6.24-*\n * @link http://typecho.org\n */\nclass GoogleCodeSVN_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        if (false == Typecho_Http_Client::get()) {\n            throw new Typecho_Plugin_Exception(_t('对不起, 您的主机不支持 php-curl 扩展而且没有打开 allow_url_fopen 功能, 无法正常使用此功能'));\n        }\n    \n        Helper::addAction('googlecode-svn', 'GoogleCodeSVN_Action');\n        return _t('请在插件设置里设置 Google Code 的SVN参数') . $error;\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate()\n    {\n        Helper::removeAction('googlecode-svn');\n    }\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $secretKey = new Typecho_Widget_Helper_Form_Element_Text('secretKey', NULL, NULL,\n        _t('安全密钥'), _t('请在你的Google Code项目的管理员面板的source区的最下方找到此项'));\n        $form->addInput($secretKey->addRule('required', _t('必须填写安全密钥')));\n        \n        $basePath = new Typecho_Widget_Helper_Form_Element_Text('basePath', NULL, '/trunk',\n        _t('SVN目录'), _t('填写需要监控的SVN目录'));\n        $form->addInput($basePath->addRule('required', _t('必须填写数据库用户名')));\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n}\n"
  },
  {
    "path": "LaTex/Plugin.php",
    "content": "<?php\n/**\n * LaTex 公式解析\n * \n * @package LaTex\n * @author mutoo\n * @version 1.1.0\n * @link http://blog.mutoo.im/LaTex.html\n */\nclass LaTex_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Archive')->footer = array('LaTex_Plugin', 'footer');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate()\n    {}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){\n        $mark = new Typecho_Widget_Helper_Form_Element_Text('mark', NULL, 'latex', _t('自定义标记'), _t('在 Markdown 语法环境下使用以下代码进行公式转换：<blockquote>```自定义标记<br/>公式<br/>```</blockquote>'));\n        $form->addInput($mark);\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 输出尾部js\n     * \n     * @access public\n     * @param unknown $footer\n     * @return unknown\n     */\n    public static function footer() {\n        $jsUrl = Helper::options()->pluginUrl . '/LaTex/latex.js';\n        echo '<script type=\"text/javascript\" src=\"'. $jsUrl .'\"></script>';\n        $mark = Typecho_Widget::widget('Widget_Options')->plugin('LaTex')->mark;\n        echo '<script type=\"text/javascript\">latex.parse(\"'. $mark. '\");</script>';\n    }\n}\n"
  },
  {
    "path": "LaTex/latex.js",
    "content": "(function(global) {\n\tvar previousLatex = global.latex;\n\n\tglobal.latex = {\n\t\tparse: function(mark) {\n\t\t\tif (!mark) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar $ = document.querySelectorAll.bind(document);\n\t\t\tvar nodes = $('code.lang-' + mark);\n\t\t\tfor (var i = 0, l = nodes.length; i < l; i++) {\n\t\t\t\tvar node = nodes[i];\n\t\t\t\tvar latex_image = document.createElement(\"img\");\n\t\t\t\tlatex_image.src = \"http://latex.codecogs.com/png.latex?\" + node.innerHTML;\n\t\t\t\t// replace with image\n\t\t\t\tvar parent = node.parentNode;\n\t\t\t\tparent.insertBefore(latex_image, node);\n\t\t\t\tparent.removeChild(node);\n\t\t\t}\n\n\t\t},\n\t\tnoConflict: function() {\n\t\t\tglobal.latex = previousLatex;\n\t\t\treturn this;\n\t\t}\n\t}\n\n})(this);"
  },
  {
    "path": "MagikeToTypecho/Action.php",
    "content": "<?php\n\nclass MagikeToTypecho_Action extends Typecho_Widget implements Widget_Interface_Do\n{\n    public function doImport()\n    {\n        $options = $this->widget('Widget_Options');\n        $dbConfig = $options->plugin('MagikeToTypecho');\n\n        /** 初始化一个db */\n        if (Typecho_Db_Adapter_Mysql::isAvailable()) {\n            $db = new Typecho_Db('Mysql', $dbConfig->prefix);\n        } else {\n            $db = new Typecho_Db('Pdo_Mysql', $dbConfig->prefix);\n        }\n        \n        /** 只读即可 */\n        $db->addServer(array (\n          'host' => $dbConfig->host,\n          'user' => $dbConfig->user,\n          'password' => $dbConfig->password,\n          'charset' => 'utf8',\n          'port' => $dbConfig->port,\n          'database' => $dbConfig->database\n        ), Typecho_Db::READ);\n        \n        /** 删除当前内容 */\n        $masterDb = Typecho_Db::get();\n        $this->widget('Widget_Abstract_Contents')->to($contents)->delete($masterDb->sql()->where('1 = 1'));\n        $this->widget('Widget_Abstract_Comments')->to($comments)->delete($masterDb->sql()->where('1 = 1'));\n        $this->widget('Widget_Abstract_Metas')->to($metas)->delete($masterDb->sql()->where('1 = 1'));\n        $this->widget('Widget_Contents_Post_Edit')->to($edit);\n        $this->widget('Widget_Abstract_Users')->to($users)->delete($masterDb->sql()->where('uid <> 1'));\n        $masterDb->query($masterDb->delete('table.relationships')->where('1 = 1'));\n        $userId = $this->widget('Widget_User')->uid;\n        \n        /** 转换用户 */\n        $rows = $db->fetchAll($db->select()->from('table.users'));\n        foreach ($rows as $row) {\n            if (1 != $row['user_id']) {\n                $users->insert(array(\n                    'uid'       =>  $row['user_id'],\n                    'name'      =>  $row['user_name'],\n                    'password'  =>  $row['user_password'],\n                    'mail'      =>  $row['user_mail'],\n                    'url'       =>  $row['user_url'],\n                    'screenName'=>  $row['user_nick'],\n                    'created'   => strtotime($row['user_register']),\n                    'group'     => array_search($row['user_group'], $this->widget('Widget_User')->groups)\n                ));\n            }\n        }\n        \n        /** 转换全局变量 */\n        $rows = $db->fetchAll($db->select()->from('table.statics'));\n        $static = array();\n        foreach ($rows as $row) {\n            $static[$row['static_name']] = $row['static_value'];\n        }\n        \n        /** 转换文件 */\n        $files = $db->fetchAll($db->select()->from('table.files'));\n        if (!is_dir(__TYPECHO_ROOT_DIR__ . '/usr/uploads/')) {\n            mkdir(__TYPECHO_ROOT_DIR__ . '/usr/uploads/', 0766);\n        }\n        \n        $pattern = array();\n        $replace = array();\n        foreach ($files as $file) {\n            $path = __TYPECHO_ROOT_DIR__ . '/data/upload/' . substr($file['file_guid'], 0, 2) . '/' .\n            substr($file['file_guid'], 2, 2) . '/' . $file['file_guid'];\n            \n            if (file_exists($path)) {\n                $file['file_time'] = empty($file['file_time']) ? $options->gmtTime : $file['file_time'];\n                $year = idate('Y', $file['file_time']);\n                $month = idate('m', $file['file_time']);\n                $day = idate('d', $file['file_time']);\n                \n                if (!is_dir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}\")) {\n                    mkdir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}\", 0766);\n                }\n                \n                if (!is_dir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}\")) {\n                    mkdir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}\", 0766);\n                }\n                \n                if (!is_dir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}/{$day}\")) {\n                    mkdir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}/{$day}\", 0766);\n                }\n                \n                $parts = explode('.', $file['file_name']);\n                $ext = array_pop($parts);\n                copy($path, __TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}/{$day}/{$file['file_id']}.{$ext}\");\n                \n                $new = Typecho_Common::url(\"/usr/uploads/{$year}/{$month}/{$day}/{$file['file_id']}.{$ext}\", $options->siteUrl);\n                $old = Typecho_Common::url(\"/res/{$file['file_id']}/{$file['file_name']}\", $static['siteurl'] . '/index.php');\n                $pattern[] = '/' . str_replace('\\/index\\.php', '(\\/index\\.php)?', preg_quote($old, '/')) . '/is';\n                $replace[] = $new;\n            }\n        }\n        \n        /** 转换评论 */\n        $i = 1;\n        \n        while (true) {\n            $result = $db->query($db->select()->from('table.comments')\n            ->order('comment_id', Typecho_Db::SORT_ASC)->page($i, 100));\n            $j = 0;\n            \n            while ($row = $db->fetchRow($result)) {\n                $comments->insert(array(\n                    'coid'      =>  $row['comment_id'],\n                    'cid'       =>  $row['post_id'],\n                    'created'   =>  $row['comment_date'],\n                    'author'    =>  $row['comment_user'],\n                    'authorId'  =>  $row['user_id'],\n                    'ownerId'   =>  $userId,\n                    'mail'      =>  $row['comment_email'],\n                    'url'       =>  $row['comment_homepage'],\n                    'ip'        =>  $row['comment_ip'],\n                    'agent'     =>  $row['comment_agent'],\n                    'text'      =>  $row['comment_text'],\n                    'type'      =>  $row['comment_type'],\n                    'status'    =>  $row['comment_publish'],\n                    'parent'    =>  $row['comment_parent']\n                ));\n                $j ++;\n                unset($row);\n            }\n            \n            if ($j < 100) {\n                break;\n            }\n            \n            $i ++;\n            unset($result);\n        }\n        \n        /** 转换分类 */\n        $cats = $db->fetchAll($db->select()->from('table.categories'));\n        foreach ($cats as $cat) {\n            $metas->insert(array(\n                'mid'           =>  $cat['category_id'],\n                'name'          =>  $cat['category_name'],\n                'slug'          =>  $cat['category_postname'],\n                'description'   =>  $cat['category_describe'],\n                'count'         =>  0,\n                'type'          =>  'category',\n                'order'         =>  $cat['category_sort']\n            ));\n        }\n        \n        /** 转换内容 */\n        $i = 1;\n        \n        while (true) {\n            $result = $db->query($db->select()->from('table.posts')\n            ->order('post_id', Typecho_Db::SORT_ASC)->page($i, 100));\n            $j = 0;\n            \n            while ($row = $db->fetchRow($result)) {\n                $row['post_content'] = preg_replace(\n                array(\"/\\s*<p>/is\", \"/\\s*<\\/p>\\s*/is\", \"/\\s*<br\\s*\\/>\\s*/is\",\n                \"/\\s*<(div|blockquote|pre|table|ol|ul)>/is\", \"/<\\/(div|blockquote|pre|table|ol|ul)>\\s*/is\"),\n                array('', \"\\n\\n\", \"\\n\", \"\\n\\n<\\\\1>\", \"</\\\\1>\\n\\n\"), \n                $row['post_content']);\n            \n                $contents->insert(array(\n                    'cid'           =>  $row['post_id'],\n                    'title'         =>  $row['post_title'],\n                    'slug'          =>  $row['post_name'],\n                    'created'       =>  $row['post_time'],\n                    'modified'      =>  $row['post_edit_time'],\n                    'text'          =>  preg_replace($pattern, $replace, $row['post_content']),\n                    'order'         =>  0,\n                    'authorId'      =>  $row['user_id'],\n                    'template'      =>  NULL,\n                    'type'          =>  $row['post_is_page'] ? 'page' : 'post',\n                    'status'        =>  $row['post_is_draft'] ? 'draft' : 'publish',\n                    'password'      =>  $row['post_password'],\n                    'commentsNum'   =>  $row['post_comment_num'],\n                    'allowComment'  =>  $row['post_allow_comment'],\n                    'allowFeed'     =>  $row['post_allow_feed'],\n                    'allowPing'     =>  $row['post_allow_ping']\n                ));\n                \n                /** 插入分类关系 */\n                $edit->setCategories($row['post_id'], array($row['category_id']), !$row['post_is_draft']);\n                \n                /** 设置标签 */\n                $edit->setTags($row['post_id'], $row['post_tags'], !$row['post_is_draft']);\n                \n                $j ++;\n                unset($row);\n            }\n            \n            if ($j < 100) {\n                break;\n            }\n            \n            $i ++;\n            unset($result);\n        }\n        \n        $this->widget('Widget_Notice')->set(_t(\"数据已经转换完成\"), NULL, 'success');\n        $this->response->goBack();\n    }\n\n    public function action()\n    {\n        $this->widget('Widget_User')->pass('administrator');\n        $this->on($this->request->isPost())->doImport();\n    }\n}\n"
  },
  {
    "path": "MagikeToTypecho/Plugin.php",
    "content": "<?php\n/**\n * 将 Magike 数据库中的数据转换为 Typecho\n * \n * @package Magike to Typecho\n * @author qining\n * @version 1.0.0\n * @link http://typecho.org\n */\nclass MagikeToTypecho_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        if (!Typecho_Db_Adapter_Mysql::isAvailable() && !Typecho_Db_Adapter_Pdo_Mysql::isAvailable()) {\n            throw new Typecho_Plugin_Exception(_t('没有找到任何可用的 Mysql 适配器'));\n        }\n        \n        $error = NULL;\n        if ((!is_dir(__TYPECHO_ROOT_DIR__ . '/usr/uploads/') || !is_writeable(__TYPECHO_ROOT_DIR__ . '/usr/uploads/'))\n        && !is_writeable(__TYPECHO_ROOT_DIR__ . '/usr/')) {\n            $error = '<br /><strong>' . _t('%s 目录不可写, 可能会导致附件转换不成功', __TYPECHO_ROOT_DIR__ . '/usr/uploads/') . '</strong>';\n        }\n    \n        Helper::addPanel(1, 'MagikeToTypecho/panel.php', _t('从Magike导入数据'), _t('从Magike导入数据'), 'administrator');\n        Helper::addAction('magike-to-typecho', 'MagikeToTypecho_Action');\n        return _t('请在插件设置里设置 Magike 所在的数据库参数') . $error;\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate()\n    {\n        Helper::removeAction('magike-to-typecho');\n        Helper::removePanel(1, 'MagikeToTypecho/panel.php');\n    }\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $host = new Typecho_Widget_Helper_Form_Element_Text('host', NULL, 'localhost',\n        _t('数据库地址'), _t('请填写 Magike 所在的数据库地址'));\n        $form->addInput($host->addRule('required', _t('必须填写一个数据库地址')));\n        \n        $port = new Typecho_Widget_Helper_Form_Element_Text('port', NULL, '3306',\n        _t('数据库端口'), _t('Magike 所在的数据库服务器端口'));\n        $port->input->setAttribute('class', 'mini');\n        $form->addInput($port->addRule('required', _t('必须填写数据库端口'))\n        ->addRule('isInteger', _t('端口号必须是纯数字')));\n        \n        $user = new Typecho_Widget_Helper_Form_Element_Text('user', NULL, 'root',\n        _t('数据库用户名'));\n        $form->addInput($user->addRule('required', _t('必须填写数据库用户名')));\n        \n        $password = new Typecho_Widget_Helper_Form_Element_Password('password', NULL, NULL,\n        _t('数据库密码'));\n        $form->addInput($password);\n        \n        $database = new Typecho_Widget_Helper_Form_Element_Text('database', NULL, 'magike',\n        _t('数据库名称'), _t('Magike 所在的数据库名称'));\n        $form->addInput($database->addRule('required', _t('您必须填写数据库名称')));\n    \n        $prefix = new Typecho_Widget_Helper_Form_Element_Text('prefix', NULL, 'mg_',\n        _t('表前缀'), _t('所有 Magike 数据表的前缀'));\n        $form->addInput($prefix->addRule('required', _t('您必须填写表前缀')));\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n}\n"
  },
  {
    "path": "MagikeToTypecho/panel.php",
    "content": "<?php\nif (!defined('__TYPECHO_ROOT_DIR__')) {\n    exit;\n}\n\n$success = true;\ntry {\n    $dbConfig = $options->plugin('MagikeToTypecho');\n\n    /** 初始化一个db */\n    if (Typecho_Db_Adapter_Mysql::isAvailable()) {\n        $magikeDb = new Typecho_Db('Mysql', $dbConfig->prefix);\n    } else {\n        $magikeDb = new Typecho_Db('Pdo_Mysql', $dbConfig->prefix);\n    }\n\n    /** 只读即可 */\n    $magikeDb->addServer(array (\n      'host' => $dbConfig->host,\n      'user' => $dbConfig->user,\n      'password' => $dbConfig->password,\n      'charset' => 'utf8',\n      'port' => $dbConfig->port,\n      'database' => $dbConfig->database\n    ), Typecho_Db::READ);\n    \n    $rows = $magikeDb->fetchAll($magikeDb->select()->from('table.statics'));\n    $static = array();\n    foreach ($rows as $row) {\n        $static[$row['static_name']] = $row['static_value'];\n    }\n} catch (Typecho_Db_Exception $e) {\n    $success = false;\n}\n\ninclude 'header.php';\ninclude 'menu.php';\n?>\n<div class=\"main\">\n    <div class=\"body body-950\">\n        <?php include 'page-title.php'; ?>\n        <div class=\"container typecho-page-main\">\n            <div class=\"column-22 start-02\">\n                <?php if ($success): ?>\n                <div class=\"message notice typecho-radius-topleft typecho-radius-topright typecho-radius-bottomleft typecho-radius-bottomright\">\n                <form action=\"<?php $options->index('/action/magike-to-typecho'); ?>\" method=\"post\">\n                    <?php _e('我们检测到了 Magike 系统信息, 点击下方的按钮开始数据转换, 数据转换可能会耗时较长.'); ?>\n                    <blockquote>\n                    <ul>\n                        <li><strong><?php echo $static['blog_name']; ?></strong></li>\n                        <li><strong><?php echo $static['description']; ?></strong></li>\n                        <li><strong><?php echo $static['siteurl']; ?></strong></li>\n                    </ul>\n                    </blockquote>\n                    <br />\n                    <p><button type=\"submit\"><?php _e('开始数据转换 &raquo;'); ?></button></p>\n                </form>\n                </div>\n                <?php else: ?>\n                <div class=\"message error\">\n                    <?php _e('我们在连接到 Magike 的数据库时发生了错误, 请<a href=\"%s\">重新设置</a>你的信息.', \n                    Typecho_Common::url('options-plugin.php?config=MagikeToTypecho', $options->adminUrl)); ?>\n                </div>\n                <?php endif; ?>\n            </div>\n        </div>\n    </div>\n</div>\n<?php\ninclude 'copyright.php';\ninclude 'common-js.php';\ninclude 'footer.php';\n?>\n"
  },
  {
    "path": "MathJax.php",
    "content": "<?php\n/**\n * MathJax\n * \n * @package MathJax\n * @author mutoo\n * @version 1.0.0\n * @link http://blog.mutoo.im/mathjax-plugin.html\n */\nclass MathJax implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Archive')->footer = array('MathJax', 'footer');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate()\n    {}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 输出尾部js\n     * \n     * @access public\n     * @param unknown $footer\n     * @return unknown\n     */\n    public static function footer() {\n        echo '<script type=\"text/x-mathjax-config\">MathJax.Hub.Config({tex2jax: {inlineMath: [[\\'$\\',\\'$\\'], [\\'\\\\\\\\(\\',\\'\\\\\\\\)\\']]}});</script><script type=\"text/javascript\" src=\"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>';\n    }\n}\n"
  },
  {
    "path": "PageToLinks.php",
    "content": "<?php\n/**\n * 将页面转化为友情链接列表的插件\n * \n * @package Page To Links\n * @author qining\n * @version 1.0.0\n * @link http://typecho.org\n */\nclass PageToLinks implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate(){}\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 解析并输出\n     * \n     * @access public\n     * @param string $slug 页面标题\n     * @param string $tag 标题的html tag\n     * @param string $listTag 列表的html tag\n     * @return void\n     */\n    public static function output($slug = 'links', $tag = 'h2', $listTag = 'ul')\n    {\n        /** 获取数据库支持 */\n        $db = Typecho_Db::get();\n        \n        /** 获取文本 */\n        $contents = $db->fetchObject($db->select('text')->from('table.contents')\n        ->where('slug = ?', $slug)->limit(1));\n        \n        if (!$contents) {\n            return;\n        }\n        \n        $text = $contents->text;\n        $cats = preg_split(\"/<\\/(ol|ul)>/i\", $text);\n        \n        foreach ($cats as $cat) {\n            $item = trim($cat);\n            \n            if ($item) {\n                $matches = array_map('trim', preg_split(\"/<(ol|ul)[^>]*>/i\", $item));\n                if (2 == count($matches)) {\n                    list ($title, $list) = $matches;\n                    echo \"<$tag>\" . strip_tags($title) . \"</$tag>\";\n                    echo \"<$listTag>\" . $list . \"</$listTag>\";\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PostToQzone/Plugin.php",
    "content": "<?php\n/**\n * 将文章同时发布到您的Qzone\n *\n * @package PostToQzone\n * @version 1.0 beta\n * @author blankyao\n * @link http://www.blankyao.cn\n */\ninclude \"phpmailer.php\";\ninclude \"smtp.php\";\nclass PostToQzone_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * activate\n     *\n     * @static\n     * @access public\n     * @return void\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Contents_Post_Edit')->insert =\n            array('PostToQzone_Plugin', 'publish');\n        if(!extension_loaded(\"sockets\")){\n            throw new Typecho_Plugin_Exception(_t('对不起, 您的主机不支持socket扩展, 无法正常使用此功能'));\n        }\n        return _t('请配置您的qq号码以及密码，以便发布文章到Qzone');\n    }\n\n    /**\n     * deactivate\n     *\n     * @static\n     * @access public\n     * @return void\n     */\n    public static function deactivate()\n    {\n    }\n\n    /**\n     * 插件配置面板\n     *\n     * @param Typecho_Widget_Helper_Form $form\n     * @static\n     * @access public\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $qq = new Typecho_Widget_Helper_Form_Element_Text('qq', NULL, NULL,\n        _t('qq号码'), _t('请填写您的qq号码'));\n        $qq->addRule('isInteger', _t('qq号码必须是纯数字'));\n        $form->addInput($qq->addRule('required', _t('必须填写一个qq号码')));\n        $psw = new Typecho_Widget_Helper_Form_Element_Password('psw', NULL, NULL,\n        _t('qq邮箱密码'), _t('请填写您的qq邮箱密码'));\n        $form->addInput($psw->addRule('required', _t('必须填写一个qq邮箱密码')));\n        $title = new Typecho_Widget_Helper_Form_Element_Text('title', NULL, '{post_title}',\n        _t('标题模板'), _t('请填写您的标题模板'));\n        $form->addInput($title->addRule('required', _t('必须填写一个标题模板')));\n        $content = new Typecho_Widget_Helper_Form_Element_Textarea('content', NULL, '{post_content}',\n        _t('内容模板'), _t('请填写您的内容模板'));\n        $form->addInput($content->addRule('required', _t('必须填写一个内容模板')));\n    }\n\n    /**\n     * 个人用户的配置面板\n     *\n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n\n    /**\n     * 发送文章到qzone\n     *\n     * @param mixed $contents 文章结构体\n     * @access public\n     * @return mixed $contents 处理后的文章结构体\n     */\n    public function publish($contents)\n    {\n        //todo:增加一个选项，如果选择发送的qzone的话再发到qzone\n        $options = Typecho_Widget::widget('Widget_Options');\n        $config = $options->plugin('PostToQzone');\n        $config = postToQzoneDefault($config);\n\n        if($config->qq > 1000 && !empty($contents['title'])  && !empty($contents['text'])){\n\n            $post_content = str_replace('{post_content}', $contents['text'], $config->content);\n            $post_content = str_replace('{post_title}', $contents['title'], $post_content);\n\n            $post_title = str_replace('{post_title}', $contents['title'], $config->title);\n\n            $m=new Mailer($config->qq,$config->psw);\n            $m->Halo($post_title,$post_content);\n        }\n        return $contents;\n    }\n}\n\nfunction postToQzoneDefault($config){\n\tif(strpos($config->title,'{post_title}') === false){\n\t\t$config->title = '{post_title}';\n\t}\n\n\tif(strpos($config->content,'{post_content}') === false){\n\t\t$config->content = '{post_content}';\n\t}\n\treturn $config;\n}\n\nclass Mailer extends PHPMailer\n{\n\tvar $qq=null;\n\tfunction Mailer($qq,$psw) {\n\t\t$this->qq=$qq;\n\t\t$this->From\t = \"{$qq}@qq.com\";\n\t\t$this->FromName = $qq;\n\t\t$this->Host\t = \"smtp.qq.com\";\n\t\t$this->Mailer   = \"smtp\";\n\t\t$this->WordWrap = 75;\n\t\t$this->CharSet = Typecho_Widget::widget('Widget_Options')->charset;\n\t\t$this->Encoding = 'base64';\n\t\t$this->SMTPAuth = true;\n\t\t$this->IsHTML(true);\n\t\t$this->Username = $qq;\n\t\t$this->Password = $psw;\n\t}\n\n\tfunction Halo($subject,$body){\n\t\t$this->AddAddress(\"{$this->qq}@qzone.qq.com\", \"{$this->qq}@qzone.qq.com\");\n\t\t$this->Subject = $subject;\n\t\t$this->Body\t= $body;\n\t\treturn $this->Send();\n\t}\n}\n\nclass Crypter\n{\n   var $key;\n\n   function Crypter($clave){\n\t  $this->key = $clave;\n   }\n\n   function keyED($txt) {\n\t  $encrypt_key = md5($this->key);\n\t  $ctr=0;\n\t  $tmp = \"\";\n\t  for ($i=0;$i<strlen($txt);$i++) {\n\t\t if ($ctr==strlen($encrypt_key)) $ctr=0;\n\t\t $tmp.= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1);\n\t\t $ctr++;\n\t  }\n\t  return $tmp;\n   }\n\n   function encrypt($txt){\n\t  srand((double)microtime()*1000000);\n\t  $encrypt_key = md5(rand(0,32000));\n\t  $ctr=0;\n\t  $tmp = \"\";\n\t  for ($i=0;$i<strlen($txt);$i++){\n\t\t if ($ctr==strlen($encrypt_key)) $ctr=0;\n\t\t $tmp.= substr($encrypt_key,$ctr,1) .\n\t\t\t (substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1));\n\t\t $ctr++;\n\t  }\n\t  return base64_encode($this->keyED($tmp));\n   }\n\n   function decrypt($txt) {\n\t  $txt = $this->keyED(base64_decode($txt));\n\t  $tmp = \"\";\n\t  for ($i=0;$i<strlen($txt);$i++){\n\t\t $md5 = substr($txt,$i,1);\n\t\t $i++;\n\t\t $tmp.= (substr($txt,$i,1) ^ $md5);\n\t  }\n\t  return $tmp;\n   }\n}\n"
  },
  {
    "path": "PostToQzone/phpmailer.php",
    "content": "<?php\n/*~ class.phpmailer.php\n.---------------------------------------------------------------------------.\n|  Software: PHPMailer - PHP email class                                    |\n|   Version: 2.0.2                                                          |\n|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |\n|      Info: http://phpmailer.sourceforge.net                               |\n|   Support: http://sourceforge.net/projects/phpmailer/                     |\n| ------------------------------------------------------------------------- |\n|    Author: Andy Prevost (project admininistrator)                         |\n|    Author: Brent R. Matzelle (original founder)                           |\n| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               |\n| Copyright (c) 2001-2003, Brent R. Matzelle                                |\n| ------------------------------------------------------------------------- |\n|   License: Distributed under the Lesser General Public License (LGPL)     |\n|            http://www.gnu.org/copyleft/lesser.html                        |\n| This program is distributed in the hope that it will be useful - WITHOUT  |\n| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |\n| FITNESS FOR A PARTICULAR PURPOSE.                                         |\n| ------------------------------------------------------------------------- |\n| We offer a number of paid services (www.codeworxtech.com):                |\n| - Web Hosting on highly optimized fast and secure servers                 |\n| - Technology Consulting                                                   |\n| - Oursourcing (highly qualified programmers and graphic designers)        |\n'---------------------------------------------------------------------------'\n */\n/**\n * PHPMailer - PHP email transport class\n * @package PHPMailer\n * @author Andy Prevost\n * @copyright 2004 - 2008 Andy Prevost\n */\n\nclass PHPMailer {\n\n  /////////////////////////////////////////////////\n  // PROPERTIES, PUBLIC\n  /////////////////////////////////////////////////\n\n  /**\n   * Email priority (1 = High, 3 = Normal, 5 = low).\n   * @var int\n   */\n  var $Priority          = 3;\n\n  /**\n   * Sets the CharSet of the message.\n   * @var string\n   */\n  var $CharSet           = 'iso-8859-1';\n\n  /**\n   * Sets the Content-type of the message.\n   * @var string\n   */\n  var $ContentType        = 'text/plain';\n\n  /**\n   * Sets the Encoding of the message. Options for this are \"8bit\",\n   * \"7bit\", \"binary\", \"base64\", and \"quoted-printable\".\n   * @var string\n   */\n  var $Encoding          = '8bit';\n\n  /**\n   * Holds the most recent mailer error message.\n   * @var string\n   */\n  var $ErrorInfo         = '';\n\n  /**\n   * Sets the From email address for the message.\n   * @var string\n   */\n  var $From              = 'root@localhost';\n\n  /**\n   * Sets the From name of the message.\n   * @var string\n   */\n  var $FromName          = 'Root User';\n\n  /**\n   * Sets the Sender email (Return-Path) of the message.  If not empty,\n   * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.\n   * @var string\n   */\n  var $Sender            = '';\n\n  /**\n   * Sets the Subject of the message.\n   * @var string\n   */\n  var $Subject           = '';\n\n  /**\n   * Sets the Body of the message.  This can be either an HTML or text body.\n   * If HTML then run IsHTML(true).\n   * @var string\n   */\n  var $Body              = '';\n\n  /**\n   * Sets the text-only body of the message.  This automatically sets the\n   * email to multipart/alternative.  This body can be read by mail\n   * clients that do not have HTML email capability such as mutt. Clients\n   * that can read HTML will view the normal Body.\n   * @var string\n   */\n  var $AltBody           = '';\n\n  /**\n   * Sets word wrapping on the body of the message to a given number of\n   * characters.\n   * @var int\n   */\n  var $WordWrap          = 0;\n\n  /**\n   * Method to send mail: (\"mail\", \"sendmail\", or \"smtp\").\n   * @var string\n   */\n  var $Mailer            = 'mail';\n\n  /**\n   * Sets the path of the sendmail program.\n   * @var string\n   */\n  var $Sendmail          = '/usr/sbin/sendmail';\n\n  /**\n   * Path to PHPMailer plugins.  This is now only useful if the SMTP class\n   * is in a different directory than the PHP include path.\n   * @var string\n   */\n  var $PluginDir         = '';\n\n  /**\n   * Holds PHPMailer version.\n   * @var string\n   */\n  var $Version           = \"2.0.2\";\n\n  /**\n   * Sets the email address that a reading confirmation will be sent.\n   * @var string\n   */\n  var $ConfirmReadingTo  = '';\n\n  /**\n   * Sets the hostname to use in Message-Id and Received headers\n   * and as default HELO string. If empty, the value returned\n   * by SERVER_NAME is used or 'localhost.localdomain'.\n   * @var string\n   */\n  var $Hostname          = '';\n\n  /**\n   * Sets the message ID to be used in the Message-Id header.\n   * If empty, a unique id will be generated.\n   * @var string\n   */\n  var $MessageID         = '';\n\n  /////////////////////////////////////////////////\n  // PROPERTIES FOR SMTP\n  /////////////////////////////////////////////////\n\n  /**\n   * Sets the SMTP hosts.  All hosts must be separated by a\n   * semicolon.  You can also specify a different port\n   * for each host by using this format: [hostname:port]\n   * (e.g. \"smtp1.example.com:25;smtp2.example.com\").\n   * Hosts will be tried in order.\n   * @var string\n   */\n  var $Host        = 'localhost';\n\n  /**\n   * Sets the default SMTP server port.\n   * @var int\n   */\n  var $Port        = 25;\n\n  /**\n   * Sets the SMTP HELO of the message (Default is $Hostname).\n   * @var string\n   */\n  var $Helo        = '';\n\n  /**\n   * Sets connection prefix.\n   * Options are \"\", \"ssl\" or \"tls\"\n   * @var string\n   */\n  var $SMTPSecure = \"\";\n\n  /**\n   * Sets SMTP authentication. Utilizes the Username and Password variables.\n   * @var bool\n   */\n  var $SMTPAuth     = false;\n\n  /**\n   * Sets SMTP username.\n   * @var string\n   */\n  var $Username     = '';\n\n  /**\n   * Sets SMTP password.\n   * @var string\n   */\n  var $Password     = '';\n\n  /**\n   * Sets the SMTP server timeout in seconds. This function will not\n   * work with the win32 version.\n   * @var int\n   */\n  var $Timeout      = 10;\n\n  /**\n   * Sets SMTP class debugging on or off.\n   * @var bool\n   */\n  var $SMTPDebug    = false;\n\n  /**\n   * Prevents the SMTP connection from being closed after each mail\n   * sending.  If this is set to true then to close the connection\n   * requires an explicit call to SmtpClose().\n   * @var bool\n   */\n  var $SMTPKeepAlive = false;\n\n  /**\n   * Provides the ability to have the TO field process individual\n   * emails, instead of sending to entire TO addresses\n   * @var bool\n   */\n  var $SingleTo = false;\n\n  /////////////////////////////////////////////////\n  // PROPERTIES, PRIVATE\n  /////////////////////////////////////////////////\n\n  var $smtp            = NULL;\n  var $to              = array();\n  var $cc              = array();\n  var $bcc             = array();\n  var $ReplyTo         = array();\n  var $attachment      = array();\n  var $CustomHeader    = array();\n  var $message_type    = '';\n  var $boundary        = array();\n  var $language        = array();\n  var $error_count     = 0;\n  var $LE              = \"\\n\";\n  var $sign_key_file   = \"\";\n  var $sign_key_pass   = \"\";\n\n  /////////////////////////////////////////////////\n  // METHODS, VARIABLES\n  /////////////////////////////////////////////////\n\n  /**\n   * Sets message type to HTML.\n   * @param bool $bool\n   * @return void\n   */\n  function IsHTML($bool) {\n    if($bool == true) {\n      $this->ContentType = 'text/html';\n    } else {\n      $this->ContentType = 'text/plain';\n    }\n  }\n\n  /**\n   * Sets Mailer to send message using SMTP.\n   * @return void\n   */\n  function IsSMTP() {\n    $this->Mailer = 'smtp';\n  }\n\n  /**\n   * Sets Mailer to send message using PHP mail() function.\n   * @return void\n   */\n  function IsMail() {\n    $this->Mailer = 'mail';\n  }\n\n  /**\n   * Sets Mailer to send message using the $Sendmail program.\n   * @return void\n   */\n  function IsSendmail() {\n    $this->Mailer = 'sendmail';\n  }\n\n  /**\n   * Sets Mailer to send message using the qmail MTA.\n   * @return void\n   */\n  function IsQmail() {\n    $this->Sendmail = '/var/qmail/bin/sendmail';\n    $this->Mailer = 'sendmail';\n  }\n\n  /////////////////////////////////////////////////\n  // METHODS, RECIPIENTS\n  /////////////////////////////////////////////////\n\n  /**\n   * Adds a \"To\" address.\n   * @param string $address\n   * @param string $name\n   * @return void\n   */\n  function AddAddress($address, $name = '') {\n    $cur = count($this->to);\n    $this->to[$cur][0] = trim($address);\n    $this->to[$cur][1] = $name;\n  }\n\n  /**\n   * Adds a \"Cc\" address. Note: this function works\n   * with the SMTP mailer on win32, not with the \"mail\"\n   * mailer.\n   * @param string $address\n   * @param string $name\n   * @return void\n   */\n  function AddCC($address, $name = '') {\n    $cur = count($this->cc);\n    $this->cc[$cur][0] = trim($address);\n    $this->cc[$cur][1] = $name;\n  }\n\n  /**\n   * Adds a \"Bcc\" address. Note: this function works\n   * with the SMTP mailer on win32, not with the \"mail\"\n   * mailer.\n   * @param string $address\n   * @param string $name\n   * @return void\n   */\n  function AddBCC($address, $name = '') {\n    $cur = count($this->bcc);\n    $this->bcc[$cur][0] = trim($address);\n    $this->bcc[$cur][1] = $name;\n  }\n\n  /**\n   * Adds a \"Reply-To\" address.\n   * @param string $address\n   * @param string $name\n   * @return void\n   */\n  function AddReplyTo($address, $name = '') {\n    $cur = count($this->ReplyTo);\n    $this->ReplyTo[$cur][0] = trim($address);\n    $this->ReplyTo[$cur][1] = $name;\n  }\n\n  /////////////////////////////////////////////////\n  // METHODS, MAIL SENDING\n  /////////////////////////////////////////////////\n\n  /**\n   * Creates message and assigns Mailer. If the message is\n   * not sent successfully then it returns false.  Use the ErrorInfo\n   * variable to view description of the error.\n   * @return bool\n   */\n  function Send() {\n    $header = '';\n    $body = '';\n    $result = true;\n\n    if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {\n      $this->SetError($this->Lang('provide_address'));\n      return false;\n    }\n\n    /* Set whether the message is multipart/alternative */\n    if(!empty($this->AltBody)) {\n      $this->ContentType = 'multipart/alternative';\n    }\n\n    $this->error_count = 0; // reset errors\n    $this->SetMessageType();\n    $header .= $this->CreateHeader();\n    $body = $this->CreateBody();\n\n    if($body == '') {\n      return false;\n    }\n\n    /* Choose the mailer */\n    switch($this->Mailer) {\n      case 'sendmail':\n        $result = $this->SendmailSend($header, $body);\n        break;\n      case 'smtp':\n        $result = $this->SmtpSend($header, $body);\n        break;\n      case 'mail':\n        $result = $this->MailSend($header, $body);\n        break;\n      default:\n        $result = $this->MailSend($header, $body);\n        break;\n        //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported'));\n        //$result = false;\n        //break;\n    }\n\n    return $result;\n  }\n\n  /**\n   * Sends mail using the $Sendmail program.\n   * @access private\n   * @return bool\n   */\n  function SendmailSend($header, $body) {\n    if ($this->Sender != '') {\n      $sendmail = sprintf(\"%s -oi -f %s -t\", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));\n    } else {\n      $sendmail = sprintf(\"%s -oi -t\", escapeshellcmd($this->Sendmail));\n    }\n\n    if(!@$mail = popen($sendmail, 'w')) {\n      $this->SetError($this->Lang('execute') . $this->Sendmail);\n      return false;\n    }\n\n    fputs($mail, $header);\n    fputs($mail, $body);\n\n    $result = pclose($mail);\n    if (version_compare(phpversion(), '4.2.3') == -1) {\n      $result = $result >> 8 & 0xFF;\n    }\n    if($result != 0) {\n      $this->SetError($this->Lang('execute') . $this->Sendmail);\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Sends mail using the PHP mail() function.\n   * @access private\n   * @return bool\n   */\n  function MailSend($header, $body) {\n\n    $to = '';\n    for($i = 0; $i < count($this->to); $i++) {\n      if($i != 0) { $to .= ', '; }\n      $to .= $this->AddrFormat($this->to[$i]);\n    }\n\n    $toArr = split(',', $to);\n\n    $params = sprintf(\"-oi -f %s\", $this->Sender);\n    if ($this->Sender != '' && strlen(ini_get('safe_mode')) < 1) {\n      $old_from = ini_get('sendmail_from');\n      ini_set('sendmail_from', $this->Sender);\n      if ($this->SingleTo === true && count($toArr) > 1) {\n        foreach ($toArr as $key => $val) {\n          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);\n        }\n      } else {\n        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);\n      }\n    } else {\n      if ($this->SingleTo === true && count($toArr) > 1) {\n        foreach ($toArr as $key => $val) {\n          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);\n        }\n      } else {\n        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);\n      }\n    }\n\n    if (isset($old_from)) {\n      ini_set('sendmail_from', $old_from);\n    }\n\n    if(!$rt) {\n      $this->SetError($this->Lang('instantiate'));\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Sends mail via SMTP using PhpSMTP (Author:\n   * Chris Ryan).  Returns bool.  Returns false if there is a\n   * bad MAIL FROM, RCPT, or DATA input.\n   * @access private\n   * @return bool\n   */\n  function SmtpSend($header, $body) {\n    include_once($this->PluginDir . 'smtp.php');\n    $error = '';\n    $bad_rcpt = array();\n\n    if(!$this->SmtpConnect()) {\n      return false;\n    }\n\n    $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;\n    if(!$this->smtp->Mail($smtp_from)) {\n      $error = $this->Lang('from_failed') . $smtp_from;\n      $this->SetError($error);\n      $this->smtp->Reset();\n      return false;\n    }\n\n    /* Attempt to send attach all recipients */\n    for($i = 0; $i < count($this->to); $i++) {\n      if(!$this->smtp->Recipient($this->to[$i][0])) {\n        $bad_rcpt[] = $this->to[$i][0];\n      }\n    }\n    for($i = 0; $i < count($this->cc); $i++) {\n      if(!$this->smtp->Recipient($this->cc[$i][0])) {\n        $bad_rcpt[] = $this->cc[$i][0];\n      }\n    }\n    for($i = 0; $i < count($this->bcc); $i++) {\n      if(!$this->smtp->Recipient($this->bcc[$i][0])) {\n        $bad_rcpt[] = $this->bcc[$i][0];\n      }\n    }\n\n    if(count($bad_rcpt) > 0) { // Create error message\n      for($i = 0; $i < count($bad_rcpt); $i++) {\n        if($i != 0) {\n          $error .= ', ';\n        }\n        $error .= $bad_rcpt[$i];\n      }\n      $error = $this->Lang('recipients_failed') . $error;\n      $this->SetError($error);\n      $this->smtp->Reset();\n      return false;\n    }\n\n    if(!$this->smtp->Data($header . $body)) {\n      $this->SetError($this->Lang('data_not_accepted'));\n      $this->smtp->Reset();\n      return false;\n    }\n    if($this->SMTPKeepAlive == true) {\n      $this->smtp->Reset();\n    } else {\n      $this->SmtpClose();\n    }\n\n    return true;\n  }\n\n  /**\n   * Initiates a connection to an SMTP server.  Returns false if the\n   * operation failed.\n   * @access private\n   * @return bool\n   */\n  function SmtpConnect() {\n    if($this->smtp == NULL) {\n      $this->smtp = new SMTP();\n    }\n\n    $this->smtp->do_debug = $this->SMTPDebug;\n    $hosts = explode(';', $this->Host);\n    $index = 0;\n    $connection = ($this->smtp->Connected());\n\n    /* Retry while there is no connection */\n    while($index < count($hosts) && $connection == false) {\n      $hostinfo = array();\n      if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) {\n        $host = $hostinfo[1];\n        $port = $hostinfo[2];\n      } else {\n        $host = $hosts[$index];\n        $port = $this->Port;\n      }\n\n      if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) {\n        if ($this->Helo != '') {\n          $this->smtp->Hello($this->Helo);\n        } else {\n          $this->smtp->Hello($this->ServerHostname());\n        }\n\n        $connection = true;\n        if($this->SMTPAuth) {\n          if(!$this->smtp->Authenticate($this->Username, $this->Password)) {\n            $this->SetError($this->Lang('authenticate'));\n            $this->smtp->Reset();\n            $connection = false;\n          }\n        }\n      }\n      $index++;\n    }\n    if(!$connection) {\n      $this->SetError($this->Lang('connect_host'));\n    }\n\n    return $connection;\n  }\n\n  /**\n   * Closes the active SMTP session if one exists.\n   * @return void\n   */\n  function SmtpClose() {\n    if($this->smtp != NULL) {\n      if($this->smtp->Connected()) {\n        $this->smtp->Quit();\n        $this->smtp->Close();\n      }\n    }\n  }\n\n  /**\n   * Sets the language for all class error messages.  Returns false\n   * if it cannot load the language file.  The default language type\n   * is English.\n   * @param string $lang_type Type of language (e.g. Portuguese: \"br\")\n   * @param string $lang_path Path to the language file directory\n   * @access public\n   * @return bool\n   */\n  function SetLanguage($lang_type, $lang_path = 'language/') {\n    if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) {\n      include($lang_path.'phpmailer.lang-'.$lang_type.'.php');\n    } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) {\n      include($lang_path.'phpmailer.lang-en.php');\n    } else {\n      $this->SetError('Could not load language file');\n      return false;\n    }\n    $this->language = $PHPMAILER_LANG;\n\n    return true;\n  }\n\n  /////////////////////////////////////////////////\n  // METHODS, MESSAGE CREATION\n  /////////////////////////////////////////////////\n\n  /**\n   * Creates recipient headers.\n   * @access private\n   * @return string\n   */\n  function AddrAppend($type, $addr) {\n    $addr_str = $type . ': ';\n    $addr_str .= $this->AddrFormat($addr[0]);\n    if(count($addr) > 1) {\n      for($i = 1; $i < count($addr); $i++) {\n        $addr_str .= ', ' . $this->AddrFormat($addr[$i]);\n      }\n    }\n    $addr_str .= $this->LE;\n\n    return $addr_str;\n  }\n\n  /**\n   * Formats an address correctly.\n   * @access private\n   * @return string\n   */\n  function AddrFormat($addr) {\n    if(empty($addr[1])) {\n      $formatted = $this->SecureHeader($addr[0]);\n    } else {\n      $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . \" <\" . $this->SecureHeader($addr[0]) . \">\";\n    }\n\n    return $formatted;\n  }\n\n  /**\n   * Wraps message for use with mailers that do not\n   * automatically perform wrapping and for quoted-printable.\n   * Original written by philippe.\n   * @access private\n   * @return string\n   */\n  function WrapText($message, $length, $qp_mode = false) {\n    $soft_break = ($qp_mode) ? sprintf(\" =%s\", $this->LE) : $this->LE;\n    // If utf-8 encoding is used, we will need to make sure we don't\n    // split multibyte characters when we wrap\n    $is_utf8 = (strtolower($this->CharSet) == \"utf-8\");\n\n    $message = $this->FixEOL($message);\n    if (substr($message, -1) == $this->LE) {\n      $message = substr($message, 0, -1);\n    }\n\n    $line = explode($this->LE, $message);\n    $message = '';\n    for ($i=0 ;$i < count($line); $i++) {\n      $line_part = explode(' ', $line[$i]);\n      $buf = '';\n      for ($e = 0; $e<count($line_part); $e++) {\n        $word = $line_part[$e];\n        if ($qp_mode and (strlen($word) > $length)) {\n          $space_left = $length - strlen($buf) - 1;\n          if ($e != 0) {\n            if ($space_left > 20) {\n              $len = $space_left;\n              if ($is_utf8) {\n                $len = $this->UTF8CharBoundary($word, $len);\n              } elseif (substr($word, $len - 1, 1) == \"=\") {\n                $len--;\n              } elseif (substr($word, $len - 2, 1) == \"=\") {\n                $len -= 2;\n              }\n              $part = substr($word, 0, $len);\n              $word = substr($word, $len);\n              $buf .= ' ' . $part;\n              $message .= $buf . sprintf(\"=%s\", $this->LE);\n            } else {\n              $message .= $buf . $soft_break;\n            }\n            $buf = '';\n          }\n          while (strlen($word) > 0) {\n            $len = $length;\n            if ($is_utf8) {\n              $len = $this->UTF8CharBoundary($word, $len);\n            } elseif (substr($word, $len - 1, 1) == \"=\") {\n              $len--;\n            } elseif (substr($word, $len - 2, 1) == \"=\") {\n              $len -= 2;\n            }\n            $part = substr($word, 0, $len);\n            $word = substr($word, $len);\n\n            if (strlen($word) > 0) {\n              $message .= $part . sprintf(\"=%s\", $this->LE);\n            } else {\n              $buf = $part;\n            }\n          }\n        } else {\n          $buf_o = $buf;\n          $buf .= ($e == 0) ? $word : (' ' . $word);\n\n          if (strlen($buf) > $length and $buf_o != '') {\n            $message .= $buf_o . $soft_break;\n            $buf = $word;\n          }\n        }\n      }\n      $message .= $buf . $this->LE;\n    }\n\n    return $message;\n  }\n\n  /**\n   * Finds last character boundary prior to maxLength in a utf-8\n   * quoted (printable) encoded string.\n   * Original written by Colin Brown.\n   * @access private\n   * @param string $encodedText utf-8 QP text\n   * @param int    $maxLength   find last character boundary prior to this length\n   * @return int\n   */\n  function UTF8CharBoundary($encodedText, $maxLength) {\n    $foundSplitPos = false;\n    $lookBack = 3;\n    while (!$foundSplitPos) {\n      $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);\n      $encodedCharPos = strpos($lastChunk, \"=\");\n      if ($encodedCharPos !== false) {\n        // Found start of encoded character byte within $lookBack block.\n        // Check the encoded byte value (the 2 chars after the '=')\n        $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);\n        $dec = hexdec($hex);\n        if ($dec < 128) { // Single byte character.\n          // If the encoded char was found at pos 0, it will fit\n          // otherwise reduce maxLength to start of the encoded char\n          $maxLength = ($encodedCharPos == 0) ? $maxLength :\n          $maxLength - ($lookBack - $encodedCharPos);\n          $foundSplitPos = true;\n        } elseif ($dec >= 192) { // First byte of a multi byte character\n          // Reduce maxLength to split at start of character\n          $maxLength = $maxLength - ($lookBack - $encodedCharPos);\n          $foundSplitPos = true;\n        } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back\n          $lookBack += 3;\n        }\n      } else {\n        // No encoded character found\n        $foundSplitPos = true;\n      }\n    }\n    return $maxLength;\n  }\n\n  /**\n   * Set the body wrapping.\n   * @access private\n   * @return void\n   */\n  function SetWordWrap() {\n    if($this->WordWrap < 1) {\n      return;\n    }\n\n    switch($this->message_type) {\n      case 'alt':\n        /* fall through */\n      case 'alt_attachments':\n        $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);\n        break;\n      default:\n        $this->Body = $this->WrapText($this->Body, $this->WordWrap);\n        break;\n    }\n  }\n\n  /**\n   * Assembles message header.\n   * @access private\n   * @return string\n   */\n  function CreateHeader() {\n    $result = '';\n\n    /* Set the boundaries */\n    $uniq_id = md5(uniqid(time()));\n    $this->boundary[1] = 'b1_' . $uniq_id;\n    $this->boundary[2] = 'b2_' . $uniq_id;\n\n    $result .= $this->HeaderLine('Date', $this->RFCDate());\n    if($this->Sender == '') {\n      $result .= $this->HeaderLine('Return-Path', trim($this->From));\n    } else {\n      $result .= $this->HeaderLine('Return-Path', trim($this->Sender));\n    }\n\n    /* To be created automatically by mail() */\n    if($this->Mailer != 'mail') {\n      if(count($this->to) > 0) {\n        $result .= $this->AddrAppend('To', $this->to);\n      } elseif (count($this->cc) == 0) {\n        $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');\n      }\n      if(count($this->cc) > 0) {\n        $result .= $this->AddrAppend('Cc', $this->cc);\n      }\n    }\n\n    $from = array();\n    $from[0][0] = trim($this->From);\n    $from[0][1] = $this->FromName;\n    $result .= $this->AddrAppend('From', $from);\n\n    /* sendmail and mail() extract Cc from the header before sending */\n    if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) {\n      $result .= $this->AddrAppend('Cc', $this->cc);\n    }\n\n    /* sendmail and mail() extract Bcc from the header before sending */\n    if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {\n      $result .= $this->AddrAppend('Bcc', $this->bcc);\n    }\n\n    if(count($this->ReplyTo) > 0) {\n      $result .= $this->AddrAppend('Reply-To', $this->ReplyTo);\n    }\n\n    /* mail() sets the subject itself */\n    if($this->Mailer != 'mail') {\n      $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));\n    }\n\n    if($this->MessageID != '') {\n      $result .= $this->HeaderLine('Message-ID',$this->MessageID);\n    } else {\n      $result .= sprintf(\"Message-ID: <%s@%s>%s\", $uniq_id, $this->ServerHostname(), $this->LE);\n    }\n    $result .= $this->HeaderLine('X-Priority', $this->Priority);\n    $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']');\n\n    if($this->ConfirmReadingTo != '') {\n      $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');\n    }\n\n    // Add custom headers\n    for($index = 0; $index < count($this->CustomHeader); $index++) {\n      $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));\n    }\n    if (!$this->sign_key_file) {\n      $result .= $this->HeaderLine('MIME-Version', '1.0');\n      $result .= $this->GetMailMIME();\n    }\n\n    return $result;\n  }\n\n  /**\n   * Returns the message MIME.\n   * @access private\n   * @return string\n   */\n  function GetMailMIME() {\n    $result = '';\n    switch($this->message_type) {\n      case 'plain':\n        $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);\n        $result .= sprintf(\"Content-Type: %s; charset=\\\"%s\\\"\", $this->ContentType, $this->CharSet);\n        break;\n      case 'attachments':\n        /* fall through */\n      case 'alt_attachments':\n        if($this->InlineImageExists()){\n          $result .= sprintf(\"Content-Type: %s;%s\\ttype=\\\"text/html\\\";%s\\tboundary=\\\"%s\\\"%s\", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);\n        } else {\n          $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');\n          $result .= $this->TextLine(\"\\tboundary=\\\"\" . $this->boundary[1] . '\"');\n        }\n        break;\n      case 'alt':\n        $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');\n        $result .= $this->TextLine(\"\\tboundary=\\\"\" . $this->boundary[1] . '\"');\n        break;\n    }\n\n    if($this->Mailer != 'mail') {\n      $result .= $this->LE.$this->LE;\n    }\n\n    return $result;\n  }\n\n  /**\n   * Assembles the message body.  Returns an empty string on failure.\n   * @access private\n   * @return string\n   */\n  function CreateBody() {\n    $result = '';\n    if ($this->sign_key_file) {\n      $result .= $this->GetMailMIME();\n    }\n\n    $this->SetWordWrap();\n\n    switch($this->message_type) {\n      case 'alt':\n        $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');\n        $result .= $this->EncodeString($this->AltBody, $this->Encoding);\n        $result .= $this->LE.$this->LE;\n        $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');\n        $result .= $this->EncodeString($this->Body, $this->Encoding);\n        $result .= $this->LE.$this->LE;\n        $result .= $this->EndBoundary($this->boundary[1]);\n        break;\n      case 'plain':\n        $result .= $this->EncodeString($this->Body, $this->Encoding);\n        break;\n      case 'attachments':\n        $result .= $this->GetBoundary($this->boundary[1], '', '', '');\n        $result .= $this->EncodeString($this->Body, $this->Encoding);\n        $result .= $this->LE;\n        $result .= $this->AttachAll();\n        break;\n      case 'alt_attachments':\n        $result .= sprintf(\"--%s%s\", $this->boundary[1], $this->LE);\n        $result .= sprintf(\"Content-Type: %s;%s\" . \"\\tboundary=\\\"%s\\\"%s\", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);\n        $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body\n        $result .= $this->EncodeString($this->AltBody, $this->Encoding);\n        $result .= $this->LE.$this->LE;\n        $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body\n        $result .= $this->EncodeString($this->Body, $this->Encoding);\n        $result .= $this->LE.$this->LE;\n        $result .= $this->EndBoundary($this->boundary[2]);\n        $result .= $this->AttachAll();\n        break;\n    }\n\n    if($this->IsError()) {\n      $result = '';\n    } else if ($this->sign_key_file) {\n      $file = tempnam(\"\", \"mail\");\n      $fp = fopen($file, \"w\");\n      fwrite($fp, $result);\n      fclose($fp);\n      $signed = tempnam(\"\", \"signed\");\n\n      if (@openssl_pkcs7_sign($file, $signed, \"file://\".$this->sign_key_file, array(\"file://\".$this->sign_key_file, $this->sign_key_pass), null)) {\n        $fp = fopen($signed, \"r\");\n        $result = fread($fp, filesize($this->sign_key_file));\n        fclose($fp);\n      } else {\n        $this->SetError($this->Lang(\"signing\").openssl_error_string());\n        $result = '';\n      }\n\n      unlink($file);\n      unlink($signed);\n    }\n\n    return $result;\n  }\n\n  /**\n   * Returns the start of a message boundary.\n   * @access private\n   */\n  function GetBoundary($boundary, $charSet, $contentType, $encoding) {\n    $result = '';\n    if($charSet == '') {\n      $charSet = $this->CharSet;\n    }\n    if($contentType == '') {\n      $contentType = $this->ContentType;\n    }\n    if($encoding == '') {\n      $encoding = $this->Encoding;\n    }\n    $result .= $this->TextLine('--' . $boundary);\n    $result .= sprintf(\"Content-Type: %s; charset = \\\"%s\\\"\", $contentType, $charSet);\n    $result .= $this->LE;\n    $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);\n    $result .= $this->LE;\n\n    return $result;\n  }\n\n  /**\n   * Returns the end of a message boundary.\n   * @access private\n   */\n  function EndBoundary($boundary) {\n    return $this->LE . '--' . $boundary . '--' . $this->LE;\n  }\n\n  /**\n   * Sets the message type.\n   * @access private\n   * @return void\n   */\n  function SetMessageType() {\n    if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {\n      $this->message_type = 'plain';\n    } else {\n      if(count($this->attachment) > 0) {\n        $this->message_type = 'attachments';\n      }\n      if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) {\n        $this->message_type = 'alt';\n      }\n      if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) {\n        $this->message_type = 'alt_attachments';\n      }\n    }\n  }\n\n  /* Returns a formatted header line.\n   * @access private\n   * @return string\n   */\n  function HeaderLine($name, $value) {\n    return $name . ': ' . $value . $this->LE;\n  }\n\n  /**\n   * Returns a formatted mail line.\n   * @access private\n   * @return string\n   */\n  function TextLine($value) {\n    return $value . $this->LE;\n  }\n\n  /////////////////////////////////////////////////\n  // CLASS METHODS, ATTACHMENTS\n  /////////////////////////////////////////////////\n\n  /**\n   * Adds an attachment from a path on the filesystem.\n   * Returns false if the file could not be found\n   * or accessed.\n   * @param string $path Path to the attachment.\n   * @param string $name Overrides the attachment name.\n   * @param string $encoding File encoding (see $Encoding).\n   * @param string $type File extension (MIME) type.\n   * @return bool\n   */\n  function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {\n    if(!@is_file($path)) {\n      $this->SetError($this->Lang('file_access') . $path);\n      return false;\n    }\n\n    $filename = basename($path);\n    if($name == '') {\n      $name = $filename;\n    }\n\n    $cur = count($this->attachment);\n    $this->attachment[$cur][0] = $path;\n    $this->attachment[$cur][1] = $filename;\n    $this->attachment[$cur][2] = $name;\n    $this->attachment[$cur][3] = $encoding;\n    $this->attachment[$cur][4] = $type;\n    $this->attachment[$cur][5] = false; // isStringAttachment\n    $this->attachment[$cur][6] = 'attachment';\n    $this->attachment[$cur][7] = 0;\n\n    return true;\n  }\n\n  /**\n   * Attaches all fs, string, and binary attachments to the message.\n   * Returns an empty string on failure.\n   * @access private\n   * @return string\n   */\n  function AttachAll() {\n    /* Return text of body */\n    $mime = array();\n\n    /* Add all attachments */\n    for($i = 0; $i < count($this->attachment); $i++) {\n      /* Check for string attachment */\n      $bString = $this->attachment[$i][5];\n      if ($bString) {\n        $string = $this->attachment[$i][0];\n      } else {\n        $path = $this->attachment[$i][0];\n      }\n\n      $filename    = $this->attachment[$i][1];\n      $name        = $this->attachment[$i][2];\n      $encoding    = $this->attachment[$i][3];\n      $type        = $this->attachment[$i][4];\n      $disposition = $this->attachment[$i][6];\n      $cid         = $this->attachment[$i][7];\n\n      $mime[] = sprintf(\"--%s%s\", $this->boundary[1], $this->LE);\n      $mime[] = sprintf(\"Content-Type: %s; name=\\\"%s\\\"%s\", $type, $name, $this->LE);\n      $mime[] = sprintf(\"Content-Transfer-Encoding: %s%s\", $encoding, $this->LE);\n\n      if($disposition == 'inline') {\n        $mime[] = sprintf(\"Content-ID: <%s>%s\", $cid, $this->LE);\n      }\n\n      $mime[] = sprintf(\"Content-Disposition: %s; filename=\\\"%s\\\"%s\", $disposition, $name, $this->LE.$this->LE);\n\n      /* Encode as string attachment */\n      if($bString) {\n        $mime[] = $this->EncodeString($string, $encoding);\n        if($this->IsError()) {\n          return '';\n        }\n        $mime[] = $this->LE.$this->LE;\n      } else {\n        $mime[] = $this->EncodeFile($path, $encoding);\n        if($this->IsError()) {\n          return '';\n        }\n        $mime[] = $this->LE.$this->LE;\n      }\n    }\n\n    $mime[] = sprintf(\"--%s--%s\", $this->boundary[1], $this->LE);\n\n    return join('', $mime);\n  }\n\n  /**\n   * Encodes attachment in requested format.  Returns an\n   * empty string on failure.\n   * @access private\n   * @return string\n   */\n  function EncodeFile ($path, $encoding = 'base64') {\n    if(!@$fd = fopen($path, 'rb')) {\n      $this->SetError($this->Lang('file_open') . $path);\n      return '';\n    }\n    $magic_quotes = get_magic_quotes_runtime();\n    set_magic_quotes_runtime(0);\n    $file_buffer = fread($fd, filesize($path));\n    $file_buffer = $this->EncodeString($file_buffer, $encoding);\n    fclose($fd);\n    set_magic_quotes_runtime($magic_quotes);\n\n    return $file_buffer;\n  }\n\n  /**\n   * Encodes string to requested format. Returns an\n   * empty string on failure.\n   * @access private\n   * @return string\n   */\n  function EncodeString ($str, $encoding = 'base64') {\n    $encoded = '';\n    switch(strtolower($encoding)) {\n      case 'base64':\n        /* chunk_split is found in PHP >= 3.0.6 */\n        $encoded = chunk_split(base64_encode($str), 76, $this->LE);\n        break;\n      case '7bit':\n      case '8bit':\n        $encoded = $this->FixEOL($str);\n        if (substr($encoded, -(strlen($this->LE))) != $this->LE)\n          $encoded .= $this->LE;\n        break;\n      case 'binary':\n        $encoded = $str;\n        break;\n      case 'quoted-printable':\n        $encoded = $this->EncodeQP($str);\n        break;\n      default:\n        $this->SetError($this->Lang('encoding') . $encoding);\n        break;\n    }\n    return $encoded;\n  }\n\n  /**\n   * Encode a header string to best of Q, B, quoted or none.\n   * @access private\n   * @return string\n   */\n  function EncodeHeader ($str, $position = 'text') {\n    $x = 0;\n\n    switch (strtolower($position)) {\n      case 'phrase':\n        if (!preg_match('/[\\200-\\377]/', $str)) {\n          /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */\n          $encoded = addcslashes($str, \"\\0..\\37\\177\\\\\\\"\");\n          if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\\'*+\\/=?^_`{|}~ -]/', $str)) {\n            return ($encoded);\n          } else {\n            return (\"\\\"$encoded\\\"\");\n          }\n        }\n        $x = preg_match_all('/[^\\040\\041\\043-\\133\\135-\\176]/', $str, $matches);\n        break;\n      case 'comment':\n        $x = preg_match_all('/[()\"]/', $str, $matches);\n        /* Fall-through */\n      case 'text':\n      default:\n        $x += preg_match_all('/[\\000-\\010\\013\\014\\016-\\037\\177-\\377]/', $str, $matches);\n        break;\n    }\n\n    if ($x == 0) {\n      return ($str);\n    }\n\n    $maxlen = 75 - 7 - strlen($this->CharSet);\n    /* Try to select the encoding which should produce the shortest output */\n    if (strlen($str)/3 < $x) {\n      $encoding = 'B';\n      if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {\n     // Use a custom function which correctly encodes and wraps long\n     // multibyte strings without breaking lines within a character\n        $encoded = $this->Base64EncodeWrapMB($str);\n      } else {\n        $encoded = base64_encode($str);\n        $maxlen -= $maxlen % 4;\n        $encoded = trim(chunk_split($encoded, $maxlen, \"\\n\"));\n      }\n    } else {\n      $encoding = 'Q';\n      $encoded = $this->EncodeQ($str, $position);\n      $encoded = $this->WrapText($encoded, $maxlen, true);\n      $encoded = str_replace('='.$this->LE, \"\\n\", trim($encoded));\n    }\n\n    $encoded = preg_replace('/^(.*)$/m', \" =?\".$this->CharSet.\"?$encoding?\\\\1?=\", $encoded);\n    $encoded = trim(str_replace(\"\\n\", $this->LE, $encoded));\n\n    return $encoded;\n  }\n\n  /**\n   * Checks if a string contains multibyte characters.\n   * @access private\n   * @param string $str multi-byte text to wrap encode\n   * @return bool\n   */\n  function HasMultiBytes($str) {\n    if (function_exists('mb_strlen')) {\n      return (strlen($str) > mb_strlen($str, $this->CharSet));\n    } else { // Assume no multibytes (we can't handle without mbstring functions anyway)\n      return False;\n    }\n  }\n\n  /**\n   * Correctly encodes and wraps long multibyte strings for mail headers\n   * without breaking lines within a character.\n   * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php\n   * @access private\n   * @param string $str multi-byte text to wrap encode\n   * @return string\n   */\n  function Base64EncodeWrapMB($str) {\n    $start = \"=?\".$this->CharSet.\"?B?\";\n    $end = \"?=\";\n    $encoded = \"\";\n\n    $mb_length = mb_strlen($str, $this->CharSet);\n    // Each line must have length <= 75, including $start and $end\n    $length = 75 - strlen($start) - strlen($end);\n    // Average multi-byte ratio\n    $ratio = $mb_length / strlen($str);\n    // Base64 has a 4:3 ratio\n    $offset = $avgLength = floor($length * $ratio * .75);\n\n    for ($i = 0; $i < $mb_length; $i += $offset) {\n      $lookBack = 0;\n\n      do {\n        $offset = $avgLength - $lookBack;\n        $chunk = mb_substr($str, $i, $offset, $this->CharSet);\n        $chunk = base64_encode($chunk);\n        $lookBack++;\n      }\n      while (strlen($chunk) > $length);\n\n      $encoded .= $chunk . $this->LE;\n    }\n\n    // Chomp the last linefeed\n    $encoded = substr($encoded, 0, -strlen($this->LE));\n    return $encoded;\n  }\n\n  /**\n   * Encode string to quoted-printable.\n   * @access private\n   * @return string\n   */\n  function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) {\n    $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');\n    $lines = preg_split('/(?:\\r\\n|\\r|\\n)/', $input);\n    $eol = \"\\r\\n\";\n    $escape = '=';\n    $output = '';\n    while( list(, $line) = each($lines) ) {\n      $linlen = strlen($line);\n      $newline = '';\n      for($i = 0; $i < $linlen; $i++) {\n        $c = substr( $line, $i, 1 );\n        $dec = ord( $c );\n        if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E\n          $c = '=2E';\n        }\n        if ( $dec == 32 ) {\n          if ( $i == ( $linlen - 1 ) ) { // convert space at eol only\n            $c = '=20';\n          } else if ( $space_conv ) {\n            $c = '=20';\n          }\n        } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode \"\\t\", which is *not* required\n          $h2 = floor($dec/16);\n          $h1 = floor($dec%16);\n          $c = $escape.$hex[$h2].$hex[$h1];\n        }\n        if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted\n          $output .= $newline.$escape.$eol; //  soft line break; \" =\\r\\n\" is okay\n          $newline = '';\n          // check if newline first character will be point or not\n          if ( $dec == 46 ) {\n            $c = '=2E';\n          }\n        }\n        $newline .= $c;\n      } // end of for\n      $output .= $newline.$eol;\n    } // end of while\n    return trim($output);\n  }\n\n  /**\n   * Encode string to q encoding.\n   * @access private\n   * @return string\n   */\n  function EncodeQ ($str, $position = 'text') {\n    /* There should not be any EOL in the string */\n    $encoded = preg_replace(\"[\\r\\n]\", '', $str);\n\n    switch (strtolower($position)) {\n      case 'phrase':\n        $encoded = preg_replace(\"/([^A-Za-z0-9!*+\\/ -])/e\", \"'='.sprintf('%02X', ord('\\\\1'))\", $encoded);\n        break;\n      case 'comment':\n        $encoded = preg_replace(\"/([\\(\\)\\\"])/e\", \"'='.sprintf('%02X', ord('\\\\1'))\", $encoded);\n      case 'text':\n      default:\n        /* Replace every high ascii, control =, ? and _ characters */\n        $encoded = preg_replace('/([\\000-\\011\\013\\014\\016-\\037\\075\\077\\137\\177-\\377])/e',\n              \"'='.sprintf('%02X', ord('\\\\1'))\", $encoded);\n        break;\n    }\n\n    /* Replace every spaces to _ (more readable than =20) */\n    $encoded = str_replace(' ', '_', $encoded);\n\n    return $encoded;\n  }\n\n  /**\n   * Adds a string or binary attachment (non-filesystem) to the list.\n   * This method can be used to attach ascii or binary data,\n   * such as a BLOB record from a database.\n   * @param string $string String attachment data.\n   * @param string $filename Name of the attachment.\n   * @param string $encoding File encoding (see $Encoding).\n   * @param string $type File extension (MIME) type.\n   * @return void\n   */\n  function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {\n    /* Append to $attachment array */\n    $cur = count($this->attachment);\n    $this->attachment[$cur][0] = $string;\n    $this->attachment[$cur][1] = $filename;\n    $this->attachment[$cur][2] = $filename;\n    $this->attachment[$cur][3] = $encoding;\n    $this->attachment[$cur][4] = $type;\n    $this->attachment[$cur][5] = true; // isString\n    $this->attachment[$cur][6] = 'attachment';\n    $this->attachment[$cur][7] = 0;\n  }\n\n  /**\n   * Adds an embedded attachment.  This can include images, sounds, and\n   * just about any other document.  Make sure to set the $type to an\n   * image type.  For JPEG images use \"image/jpeg\" and for GIF images\n   * use \"image/gif\".\n   * @param string $path Path to the attachment.\n   * @param string $cid Content ID of the attachment.  Use this to identify\n   *        the Id for accessing the image in an HTML form.\n   * @param string $name Overrides the attachment name.\n   * @param string $encoding File encoding (see $Encoding).\n   * @param string $type File extension (MIME) type.\n   * @return bool\n   */\n  function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {\n\n    if(!@is_file($path)) {\n      $this->SetError($this->Lang('file_access') . $path);\n      return false;\n    }\n\n    $filename = basename($path);\n    if($name == '') {\n      $name = $filename;\n    }\n\n    /* Append to $attachment array */\n    $cur = count($this->attachment);\n    $this->attachment[$cur][0] = $path;\n    $this->attachment[$cur][1] = $filename;\n    $this->attachment[$cur][2] = $name;\n    $this->attachment[$cur][3] = $encoding;\n    $this->attachment[$cur][4] = $type;\n    $this->attachment[$cur][5] = false;\n    $this->attachment[$cur][6] = 'inline';\n    $this->attachment[$cur][7] = $cid;\n\n    return true;\n  }\n\n  /**\n   * Returns true if an inline attachment is present.\n   * @access private\n   * @return bool\n   */\n  function InlineImageExists() {\n    $result = false;\n    for($i = 0; $i < count($this->attachment); $i++) {\n      if($this->attachment[$i][6] == 'inline') {\n        $result = true;\n        break;\n      }\n    }\n\n    return $result;\n  }\n\n  /////////////////////////////////////////////////\n  // CLASS METHODS, MESSAGE RESET\n  /////////////////////////////////////////////////\n\n  /**\n   * Clears all recipients assigned in the TO array.  Returns void.\n   * @return void\n   */\n  function ClearAddresses() {\n    $this->to = array();\n  }\n\n  /**\n   * Clears all recipients assigned in the CC array.  Returns void.\n   * @return void\n   */\n  function ClearCCs() {\n    $this->cc = array();\n  }\n\n  /**\n   * Clears all recipients assigned in the BCC array.  Returns void.\n   * @return void\n   */\n  function ClearBCCs() {\n    $this->bcc = array();\n  }\n\n  /**\n   * Clears all recipients assigned in the ReplyTo array.  Returns void.\n   * @return void\n   */\n  function ClearReplyTos() {\n    $this->ReplyTo = array();\n  }\n\n  /**\n   * Clears all recipients assigned in the TO, CC and BCC\n   * array.  Returns void.\n   * @return void\n   */\n  function ClearAllRecipients() {\n    $this->to = array();\n    $this->cc = array();\n    $this->bcc = array();\n  }\n\n  /**\n   * Clears all previously set filesystem, string, and binary\n   * attachments.  Returns void.\n   * @return void\n   */\n  function ClearAttachments() {\n    $this->attachment = array();\n  }\n\n  /**\n   * Clears all custom headers.  Returns void.\n   * @return void\n   */\n  function ClearCustomHeaders() {\n    $this->CustomHeader = array();\n  }\n\n  /////////////////////////////////////////////////\n  // CLASS METHODS, MISCELLANEOUS\n  /////////////////////////////////////////////////\n\n  /**\n   * Adds the error message to the error container.\n   * Returns void.\n   * @access private\n   * @return void\n   */\n  function SetError($msg) {\n    $this->error_count++;\n    $this->ErrorInfo = $msg;\n  }\n\n  /**\n   * Returns the proper RFC 822 formatted date.\n   * @access private\n   * @return string\n   */\n  function RFCDate() {\n    $tz = date('Z');\n    $tzs = ($tz < 0) ? '-' : '+';\n    $tz = abs($tz);\n    $tz = (int)($tz/3600)*100 + ($tz%3600)/60;\n    $result = sprintf(\"%s %s%04d\", date('D, j M Y H:i:s'), $tzs, $tz);\n\n    return $result;\n  }\n\n  /**\n   * Returns the appropriate server variable.  Should work with both\n   * PHP 4.1.0+ as well as older versions.  Returns an empty string\n   * if nothing is found.\n   * @access private\n   * @return mixed\n   */\n  function ServerVar($varName) {\n    global $HTTP_SERVER_VARS;\n    global $HTTP_ENV_VARS;\n\n    if(!isset($_SERVER)) {\n      $_SERVER = $HTTP_SERVER_VARS;\n      if(!isset($_SERVER['REMOTE_ADDR'])) {\n        $_SERVER = $HTTP_ENV_VARS; // must be Apache\n      }\n    }\n\n    if(isset($_SERVER[$varName])) {\n      return $_SERVER[$varName];\n    } else {\n      return '';\n    }\n  }\n\n  /**\n   * Returns the server hostname or 'localhost.localdomain' if unknown.\n   * @access private\n   * @return string\n   */\n  function ServerHostname() {\n    if ($this->Hostname != '') {\n      $result = $this->Hostname;\n    } elseif ($this->ServerVar('SERVER_NAME') != '') {\n      $result = $this->ServerVar('SERVER_NAME');\n    } else {\n      $result = 'localhost.localdomain';\n    }\n\n    return $result;\n  }\n\n  /**\n   * Returns a message in the appropriate language.\n   * @access private\n   * @return string\n   */\n  function Lang($key) {\n    if(count($this->language) < 1) {\n      $this->SetLanguage('en'); // set the default language\n    }\n\n    if(isset($this->language[$key])) {\n      return $this->language[$key];\n    } else {\n      return 'Language string failed to load: ' . $key;\n    }\n  }\n\n  /**\n   * Returns true if an error occurred.\n   * @return bool\n   */\n  function IsError() {\n    return ($this->error_count > 0);\n  }\n\n  /**\n   * Changes every end of line from CR or LF to CRLF.\n   * @access private\n   * @return string\n   */\n  function FixEOL($str) {\n    $str = str_replace(\"\\r\\n\", \"\\n\", $str);\n    $str = str_replace(\"\\r\", \"\\n\", $str);\n    $str = str_replace(\"\\n\", $this->LE, $str);\n    return $str;\n  }\n\n  /**\n   * Adds a custom header.\n   * @return void\n   */\n  function AddCustomHeader($custom_header) {\n    $this->CustomHeader[] = explode(':', $custom_header, 2);\n  }\n\n  /**\n   * Evaluates the message and returns modifications for inline images and backgrounds\n   * @access public\n   * @return $message\n   */\n  function MsgHTML($message,$basedir='') {\n    preg_match_all(\"/(src|background)=\\\"(.*)\\\"/Ui\", $message, $images);\n    if(isset($images[2])) {\n      foreach($images[2] as $i => $url) {\n        // do not change urls for absolute images (thanks to corvuscorax)\n        if (!preg_match('/^[A-z][A-z]*:\\/\\//',$url)) {\n          $filename = basename($url);\n          $directory = dirname($url);\n          ($directory == '.')?$directory='':'';\n          $cid = 'cid:' . md5($filename);\n          $fileParts = split(\"\\.\", $filename);\n          $ext = $fileParts[1];\n          $mimeType = $this->_mime_types($ext);\n          if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; }\n          if ( strlen($directory) > 1 && substr($basedir,-1) != '/') { $directory .= '/'; }\n          $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType);\n          if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) {\n            $message = preg_replace(\"/\".$images[1][$i].\"=\\\"\".preg_quote($url, '/').\"\\\"/Ui\", $images[1][$i].\"=\\\"\".$cid.\"\\\"\", $message);\n          }\n        }\n      }\n    }\n    $this->IsHTML(true);\n    $this->Body = $message;\n    $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\\/\\\\1>/s','',$message)));\n    if ( !empty($textMsg) && empty($this->AltBody) ) {\n      $this->AltBody = $textMsg;\n    }\n    if ( empty($this->AltBody) ) {\n      $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . \"\\n\\n\";\n    }\n  }\n\n  /**\n   * Gets the mime type of the embedded or inline image\n   * @access private\n   * @return mime type of ext\n   */\n  function _mime_types($ext = '') {\n    $mimes = array(\n      'hqx'  =>  'application/mac-binhex40',\n      'cpt'   =>  'application/mac-compactpro',\n      'doc'   =>  'application/msword',\n      'bin'   =>  'application/macbinary',\n      'dms'   =>  'application/octet-stream',\n      'lha'   =>  'application/octet-stream',\n      'lzh'   =>  'application/octet-stream',\n      'exe'   =>  'application/octet-stream',\n      'class' =>  'application/octet-stream',\n      'psd'   =>  'application/octet-stream',\n      'so'    =>  'application/octet-stream',\n      'sea'   =>  'application/octet-stream',\n      'dll'   =>  'application/octet-stream',\n      'oda'   =>  'application/oda',\n      'pdf'   =>  'application/pdf',\n      'ai'    =>  'application/postscript',\n      'eps'   =>  'application/postscript',\n      'ps'    =>  'application/postscript',\n      'smi'   =>  'application/smil',\n      'smil'  =>  'application/smil',\n      'mif'   =>  'application/vnd.mif',\n      'xls'   =>  'application/vnd.ms-excel',\n      'ppt'   =>  'application/vnd.ms-powerpoint',\n      'wbxml' =>  'application/vnd.wap.wbxml',\n      'wmlc'  =>  'application/vnd.wap.wmlc',\n      'dcr'   =>  'application/x-director',\n      'dir'   =>  'application/x-director',\n      'dxr'   =>  'application/x-director',\n      'dvi'   =>  'application/x-dvi',\n      'gtar'  =>  'application/x-gtar',\n      'php'   =>  'application/x-httpd-php',\n      'php4'  =>  'application/x-httpd-php',\n      'php3'  =>  'application/x-httpd-php',\n      'phtml' =>  'application/x-httpd-php',\n      'phps'  =>  'application/x-httpd-php-source',\n      'js'    =>  'application/x-javascript',\n      'swf'   =>  'application/x-shockwave-flash',\n      'sit'   =>  'application/x-stuffit',\n      'tar'   =>  'application/x-tar',\n      'tgz'   =>  'application/x-tar',\n      'xhtml' =>  'application/xhtml+xml',\n      'xht'   =>  'application/xhtml+xml',\n      'zip'   =>  'application/zip',\n      'mid'   =>  'audio/midi',\n      'midi'  =>  'audio/midi',\n      'mpga'  =>  'audio/mpeg',\n      'mp2'   =>  'audio/mpeg',\n      'mp3'   =>  'audio/mpeg',\n      'aif'   =>  'audio/x-aiff',\n      'aiff'  =>  'audio/x-aiff',\n      'aifc'  =>  'audio/x-aiff',\n      'ram'   =>  'audio/x-pn-realaudio',\n      'rm'    =>  'audio/x-pn-realaudio',\n      'rpm'   =>  'audio/x-pn-realaudio-plugin',\n      'ra'    =>  'audio/x-realaudio',\n      'rv'    =>  'video/vnd.rn-realvideo',\n      'wav'   =>  'audio/x-wav',\n      'bmp'   =>  'image/bmp',\n      'gif'   =>  'image/gif',\n      'jpeg'  =>  'image/jpeg',\n      'jpg'   =>  'image/jpeg',\n      'jpe'   =>  'image/jpeg',\n      'png'   =>  'image/png',\n      'tiff'  =>  'image/tiff',\n      'tif'   =>  'image/tiff',\n      'css'   =>  'text/css',\n      'html'  =>  'text/html',\n      'htm'   =>  'text/html',\n      'shtml' =>  'text/html',\n      'txt'   =>  'text/plain',\n      'text'  =>  'text/plain',\n      'log'   =>  'text/plain',\n      'rtx'   =>  'text/richtext',\n      'rtf'   =>  'text/rtf',\n      'xml'   =>  'text/xml',\n      'xsl'   =>  'text/xml',\n      'mpeg'  =>  'video/mpeg',\n      'mpg'   =>  'video/mpeg',\n      'mpe'   =>  'video/mpeg',\n      'qt'    =>  'video/quicktime',\n      'mov'   =>  'video/quicktime',\n      'avi'   =>  'video/x-msvideo',\n      'movie' =>  'video/x-sgi-movie',\n      'doc'   =>  'application/msword',\n      'word'  =>  'application/msword',\n      'xl'    =>  'application/excel',\n      'eml'   =>  'message/rfc822'\n    );\n    return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];\n  }\n\n  /**\n   * Set (or reset) Class Objects (variables)\n   *\n   * Usage Example:\n   * $page->set('X-Priority', '3');\n   *\n   * @access public\n   * @param string $name Parameter Name\n   * @param mixed $value Parameter Value\n   * NOTE: will not work with arrays, there are no arrays to set/reset\n   */\n  function set ( $name, $value = '' ) {\n    if ( isset($this->$name) ) {\n      $this->$name = $value;\n    } else {\n      $this->SetError('Cannot set or reset variable ' . $name);\n      return false;\n    }\n  }\n\n  /**\n   * Read a file from a supplied filename and return it.\n   *\n   * @access public\n   * @param string $filename Parameter File Name\n   */\n  function getFile($filename) {\n    $return = '';\n    if ($fp = fopen($filename, 'rb')) {\n      while (!feof($fp)) {\n        $return .= fread($fp, 1024);\n      }\n      fclose($fp);\n      return $return;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * Strips newlines to prevent header injection.\n   * @access private\n   * @param string $str String\n   * @return string\n   */\n  function SecureHeader($str) {\n    $str = trim($str);\n    $str = str_replace(\"\\r\", \"\", $str);\n    $str = str_replace(\"\\n\", \"\", $str);\n    return $str;\n  }\n\n  /**\n   * Set the private key file and password to sign the message.\n   *\n   * @access public\n   * @param string $key_filename Parameter File Name\n   * @param string $key_pass Password for private key\n   */\n  function Sign($key_filename, $key_pass) {\n    $this->sign_key_file = $key_filename;\n    $this->sign_key_pass = $key_pass;\n  }\n\n}\n\n?>\n"
  },
  {
    "path": "PostToQzone/smtp.php",
    "content": "<?php\n/*~ class.smtp.php\n.---------------------------------------------------------------------------.\n|  Software: PHPMailer - PHP email class                                    |\n|   Version: 2.0.2                                                          |\n|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |\n|      Info: http://phpmailer.sourceforge.net                               |\n|   Support: http://sourceforge.net/projects/phpmailer/                     |\n| ------------------------------------------------------------------------- |\n|    Author: Andy Prevost (project admininistrator)                         |\n|    Author: Brent R. Matzelle (original founder)                           |\n| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               |\n| Copyright (c) 2001-2003, Brent R. Matzelle                                |\n| ------------------------------------------------------------------------- |\n|   License: Distributed under the Lesser General Public License (LGPL)     |\n|            http://www.gnu.org/copyleft/lesser.html                        |\n| This program is distributed in the hope that it will be useful - WITHOUT  |\n| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |\n| FITNESS FOR A PARTICULAR PURPOSE.                                         |\n| ------------------------------------------------------------------------- |\n| We offer a number of paid services (www.codeworxtech.com):                |\n| - Web Hosting on highly optimized fast and secure servers                 |\n| - Technology Consulting                                                   |\n| - Oursourcing (highly qualified programmers and graphic designers)        |\n'---------------------------------------------------------------------------'\n */\n/**\n * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP\n * commands except TURN which will always return a not implemented\n * error. SMTP also provides some utility methods for sending mail\n * to an SMTP server.\n * @package PHPMailer\n * @author Chris Ryan\n */\n\nclass SMTP\n{\n  /**\n   *  SMTP server port\n   *  @var int\n   */\n  var $SMTP_PORT = 25;\n\n  /**\n   *  SMTP reply line ending\n   *  @var string\n   */\n  var $CRLF = \"\\r\\n\";\n\n  /**\n   *  Sets whether debugging is turned on\n   *  @var bool\n   */\n  var $do_debug;       # the level of debug to perform\n\n  /**\n   *  Sets VERP use on/off (default is off)\n   *  @var bool\n   */\n  var $do_verp = false;\n\n  /**#@+\n   * @access private\n   */\n  var $smtp_conn;      # the socket to the server\n  var $error;          # error if any on the last call\n  var $helo_rply;      # the reply the server sent to us for HELO\n  /**#@-*/\n\n  /**\n   * Initialize the class so that the data is in a known state.\n   * @access public\n   * @return void\n   */\n  function SMTP() {\n    $this->smtp_conn = 0;\n    $this->error = null;\n    $this->helo_rply = null;\n\n    $this->do_debug = 0;\n  }\n\n  /*************************************************************\n   *                    CONNECTION FUNCTIONS                  *\n   ***********************************************************/\n\n  /**\n   * Connect to the server specified on the port specified.\n   * If the port is not specified use the default SMTP_PORT.\n   * If tval is specified then a connection will try and be\n   * established with the server for that number of seconds.\n   * If tval is not specified the default is 30 seconds to\n   * try on the connection.\n   *\n   * SMTP CODE SUCCESS: 220\n   * SMTP CODE FAILURE: 421\n   * @access public\n   * @return bool\n   */\n  function Connect($host,$port=0,$tval=30) {\n    # set the error val to null so there is no confusion\n    $this->error = null;\n\n    # make sure we are __not__ connected\n    if($this->connected()) {\n      # ok we are connected! what should we do?\n      # for now we will just give an error saying we\n      # are already connected\n      $this->error = array(\"error\" => \"Already connected to a server\");\n      return false;\n    }\n\n    if(empty($port)) {\n      $port = $this->SMTP_PORT;\n    }\n\n    #connect to the smtp server\n    $this->smtp_conn = fsockopen($host,    # the host of the server\n                                 $port,    # the port to use\n                                 $errno,   # error number if any\n                                 $errstr,  # error message if any\n                                 $tval);   # give up after ? secs\n    # verify we connected properly\n    if(empty($this->smtp_conn)) {\n      $this->error = array(\"error\" => \"Failed to connect to server\",\n                           \"errno\" => $errno,\n                           \"errstr\" => $errstr);\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": $errstr ($errno)\" . $this->CRLF;\n      }\n      return false;\n    }\n\n    # sometimes the SMTP server takes a little longer to respond\n    # so we will give it a longer timeout for the first read\n    // Windows still does not have support for this timeout function\n    if(substr(PHP_OS, 0, 3) != \"WIN\")\n     socket_set_timeout($this->smtp_conn, $tval, 0);\n\n    # get any announcement stuff\n    $announce = $this->get_lines();\n\n    # set the timeout  of any socket functions at 1/10 of a second\n    //if(function_exists(\"socket_set_timeout\"))\n    //   socket_set_timeout($this->smtp_conn, 0, 100000);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $announce;\n    }\n\n    return true;\n  }\n\n  /**\n   * Performs SMTP authentication.  Must be run after running the\n   * Hello() method.  Returns true if successfully authenticated.\n   * @access public\n   * @return bool\n   */\n  function Authenticate($username, $password) {\n    // Start authentication\n    fputs($this->smtp_conn,\"AUTH LOGIN\" . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($code != 334) {\n      $this->error =\n        array(\"error\" => \"AUTH not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n\n    // Send encoded username\n    fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($code != 334) {\n      $this->error =\n        array(\"error\" => \"Username not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n\n    // Send encoded password\n    fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($code != 235) {\n      $this->error =\n        array(\"error\" => \"Password not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Returns true if connected to a server otherwise false\n   * @access private\n   * @return bool\n   */\n  function Connected() {\n    if(!empty($this->smtp_conn)) {\n      $sock_status = socket_get_status($this->smtp_conn);\n      if($sock_status[\"eof\"]) {\n        # hmm this is an odd situation... the socket is\n        # valid but we are not connected anymore\n        if($this->do_debug >= 1) {\n            echo \"SMTP -> NOTICE:\" . $this->CRLF .\n                 \"EOF caught while checking if connected\";\n        }\n        $this->Close();\n        return false;\n      }\n      return true; # everything looks good\n    }\n    return false;\n  }\n\n  /**\n   * Closes the socket and cleans up the state of the class.\n   * It is not considered good to use this function without\n   * first trying to use QUIT.\n   * @access public\n   * @return void\n   */\n  function Close() {\n    $this->error = null; # so there is no confusion\n    $this->helo_rply = null;\n    if(!empty($this->smtp_conn)) {\n      # close the connection and cleanup\n      fclose($this->smtp_conn);\n      $this->smtp_conn = 0;\n    }\n  }\n\n  /***************************************************************\n   *                        SMTP COMMANDS                       *\n   *************************************************************/\n\n  /**\n   * Issues a data command and sends the msg_data to the server\n   * finializing the mail transaction. $msg_data is the message\n   * that is to be send with the headers. Each header needs to be\n   * on a single line followed by a <CRLF> with the message headers\n   * and the message body being seperated by and additional <CRLF>.\n   *\n   * Implements rfc 821: DATA <CRLF>\n   *\n   * SMTP CODE INTERMEDIATE: 354\n   *     [data]\n   *     <CRLF>.<CRLF>\n   *     SMTP CODE SUCCESS: 250\n   *     SMTP CODE FAILURE: 552,554,451,452\n   * SMTP CODE FAILURE: 451,554\n   * SMTP CODE ERROR  : 500,501,503,421\n   * @access public\n   * @return bool\n   */\n  function Data($msg_data) {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Data() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"DATA\" . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 354) {\n      $this->error =\n        array(\"error\" => \"DATA command not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n\n    # the server is ready to accept data!\n    # according to rfc 821 we should not send more than 1000\n    # including the CRLF\n    # characters on a single line so we will break the data up\n    # into lines by \\r and/or \\n then if needed we will break\n    # each of those into smaller lines to fit within the limit.\n    # in addition we will be looking for lines that start with\n    # a period '.' and append and additional period '.' to that\n    # line. NOTE: this does not count towards are limit.\n\n    # normalize the line breaks so we know the explode works\n    $msg_data = str_replace(\"\\r\\n\",\"\\n\",$msg_data);\n    $msg_data = str_replace(\"\\r\",\"\\n\",$msg_data);\n    $lines = explode(\"\\n\",$msg_data);\n\n    # we need to find a good way to determine is headers are\n    # in the msg_data or if it is a straight msg body\n    # currently I am assuming rfc 822 definitions of msg headers\n    # and if the first field of the first line (':' sperated)\n    # does not contain a space then it _should_ be a header\n    # and we can process all lines before a blank \"\" line as\n    # headers.\n    $field = substr($lines[0],0,strpos($lines[0],\":\"));\n    $in_headers = false;\n    if(!empty($field) && !strstr($field,\" \")) {\n      $in_headers = true;\n    }\n\n    $max_line_length = 998; # used below; set here for ease in change\n\n    while(list(,$line) = @each($lines)) {\n      $lines_out = null;\n      if($line == \"\" && $in_headers) {\n        $in_headers = false;\n      }\n      # ok we need to break this line up into several\n      # smaller lines\n      while(strlen($line) > $max_line_length) {\n        $pos = strrpos(substr($line,0,$max_line_length),\" \");\n\n        # Patch to fix DOS attack\n        if(!$pos) {\n          $pos = $max_line_length - 1;\n        }\n\n        $lines_out[] = substr($line,0,$pos);\n        $line = substr($line,$pos + 1);\n        # if we are processing headers we need to\n        # add a LWSP-char to the front of the new line\n        # rfc 822 on long msg headers\n        if($in_headers) {\n          $line = \"\\t\" . $line;\n        }\n      }\n      $lines_out[] = $line;\n\n      # now send the lines to the server\n      while(list(,$line_out) = @each($lines_out)) {\n        if(strlen($line_out) > 0)\n        {\n          if(substr($line_out, 0, 1) == \".\") {\n            $line_out = \".\" . $line_out;\n          }\n        }\n        fputs($this->smtp_conn,$line_out . $this->CRLF);\n      }\n    }\n\n    # ok all the message data has been sent so lets get this\n    # over with aleady\n    fputs($this->smtp_conn, $this->CRLF . \".\" . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => \"DATA not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Expand takes the name and asks the server to list all the\n   * people who are members of the _list_. Expand will return\n   * back and array of the result or false if an error occurs.\n   * Each value in the array returned has the format of:\n   *     [ <full-name> <sp> ] <path>\n   * The definition of <path> is defined in rfc 821\n   *\n   * Implements rfc 821: EXPN <SP> <string> <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE FAILURE: 550\n   * SMTP CODE ERROR  : 500,501,502,504,421\n   * @access public\n   * @return string array\n   */\n  function Expand($name) {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n            \"error\" => \"Called Expand() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"EXPN \" . $name . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => \"EXPN not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n\n    # parse the reply and place in our array to return to user\n    $entries = explode($this->CRLF,$rply);\n    while(list(,$l) = @each($entries)) {\n      $list[] = substr($l,4);\n    }\n\n    return $list;\n  }\n\n  /**\n   * Sends the HELO command to the smtp server.\n   * This makes sure that we and the server are in\n   * the same known state.\n   *\n   * Implements from rfc 821: HELO <SP> <domain> <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE ERROR  : 500, 501, 504, 421\n   * @access public\n   * @return bool\n   */\n  function Hello($host=\"\") {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n            \"error\" => \"Called Hello() without being connected\");\n      return false;\n    }\n\n    # if a hostname for the HELO was not specified determine\n    # a suitable one to send\n    if(empty($host)) {\n      # we need to determine some sort of appopiate default\n      # to send to the server\n      $host = \"localhost\";\n    }\n\n    // Send extended hello first (RFC 2821)\n    if(!$this->SendHello(\"EHLO\", $host))\n    {\n      if(!$this->SendHello(\"HELO\", $host))\n          return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Sends a HELO/EHLO command.\n   * @access private\n   * @return bool\n   */\n  function SendHello($hello, $host) {\n    fputs($this->smtp_conn, $hello . \" \" . $host . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER: \" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => $hello . \" not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n\n    $this->helo_rply = $rply;\n\n    return true;\n  }\n\n  /**\n   * Gets help information on the keyword specified. If the keyword\n   * is not specified then returns generic help, ussually contianing\n   * A list of keywords that help is available on. This function\n   * returns the results back to the user. It is up to the user to\n   * handle the returned data. If an error occurs then false is\n   * returned with $this->error set appropiately.\n   *\n   * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>\n   *\n   * SMTP CODE SUCCESS: 211,214\n   * SMTP CODE ERROR  : 500,501,502,504,421\n   * @access public\n   * @return string\n   */\n  function Help($keyword=\"\") {\n    $this->error = null; # to avoid confusion\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Help() without being connected\");\n      return false;\n    }\n\n    $extra = \"\";\n    if(!empty($keyword)) {\n      $extra = \" \" . $keyword;\n    }\n\n    fputs($this->smtp_conn,\"HELP\" . $extra . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 211 && $code != 214) {\n      $this->error =\n        array(\"error\" => \"HELP not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n\n    return $rply;\n  }\n\n  /**\n   * Starts a mail transaction from the email address specified in\n   * $from. Returns true if successful or false otherwise. If True\n   * the mail transaction is started and then one or more Recipient\n   * commands may be called followed by a Data command.\n   *\n   * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE SUCCESS: 552,451,452\n   * SMTP CODE SUCCESS: 500,501,421\n   * @access public\n   * @return bool\n   */\n  function Mail($from) {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Mail() without being connected\");\n      return false;\n    }\n\n    $useVerp = ($this->do_verp ? \"XVERP\" : \"\");\n    fputs($this->smtp_conn,\"MAIL FROM:<\" . $from . \">\" . $useVerp . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => \"MAIL not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Sends the command NOOP to the SMTP server.\n   *\n   * Implements from rfc 821: NOOP <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE ERROR  : 500, 421\n   * @access public\n   * @return bool\n   */\n  function Noop() {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Noop() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"NOOP\" . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => \"NOOP not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Sends the quit command to the server and then closes the socket\n   * if there is no error or the $close_on_error argument is true.\n   *\n   * Implements from rfc 821: QUIT <CRLF>\n   *\n   * SMTP CODE SUCCESS: 221\n   * SMTP CODE ERROR  : 500\n   * @access public\n   * @return bool\n   */\n  function Quit($close_on_error=true) {\n    $this->error = null; # so there is no confusion\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Quit() without being connected\");\n      return false;\n    }\n\n    # send the quit command to the server\n    fputs($this->smtp_conn,\"quit\" . $this->CRLF);\n\n    # get any good-bye messages\n    $byemsg = $this->get_lines();\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $byemsg;\n    }\n\n    $rval = true;\n    $e = null;\n\n    $code = substr($byemsg,0,3);\n    if($code != 221) {\n      # use e as a tmp var cause Close will overwrite $this->error\n      $e = array(\"error\" => \"SMTP server rejected quit command\",\n                 \"smtp_code\" => $code,\n                 \"smtp_rply\" => substr($byemsg,4));\n      $rval = false;\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $e[\"error\"] . \": \" .\n                 $byemsg . $this->CRLF;\n      }\n    }\n\n    if(empty($e) || $close_on_error) {\n      $this->Close();\n    }\n\n    return $rval;\n  }\n\n  /**\n   * Sends the command RCPT to the SMTP server with the TO: argument of $to.\n   * Returns true if the recipient was accepted false if it was rejected.\n   *\n   * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250,251\n   * SMTP CODE FAILURE: 550,551,552,553,450,451,452\n   * SMTP CODE ERROR  : 500,501,503,421\n   * @access public\n   * @return bool\n   */\n  function Recipient($to) {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Recipient() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"RCPT TO:<\" . $to . \">\" . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250 && $code != 251) {\n      $this->error =\n        array(\"error\" => \"RCPT not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Sends the RSET command to abort and transaction that is\n   * currently in progress. Returns true if successful false\n   * otherwise.\n   *\n   * Implements rfc 821: RSET <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE ERROR  : 500,501,504,421\n   * @access public\n   * @return bool\n   */\n  function Reset() {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Reset() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"RSET\" . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => \"RSET failed\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Starts a mail transaction from the email address specified in\n   * $from. Returns true if successful or false otherwise. If True\n   * the mail transaction is started and then one or more Recipient\n   * commands may be called followed by a Data command. This command\n   * will send the message to the users terminal if they are logged\n   * in.\n   *\n   * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE SUCCESS: 552,451,452\n   * SMTP CODE SUCCESS: 500,501,502,421\n   * @access public\n   * @return bool\n   */\n  function Send($from) {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Send() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"SEND FROM:\" . $from . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => \"SEND not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Starts a mail transaction from the email address specified in\n   * $from. Returns true if successful or false otherwise. If True\n   * the mail transaction is started and then one or more Recipient\n   * commands may be called followed by a Data command. This command\n   * will send the message to the users terminal if they are logged\n   * in and send them an email.\n   *\n   * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE SUCCESS: 552,451,452\n   * SMTP CODE SUCCESS: 500,501,502,421\n   * @access public\n   * @return bool\n   */\n  function SendAndMail($from) {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n          \"error\" => \"Called SendAndMail() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"SAML FROM:\" . $from . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => \"SAML not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Starts a mail transaction from the email address specified in\n   * $from. Returns true if successful or false otherwise. If True\n   * the mail transaction is started and then one or more Recipient\n   * commands may be called followed by a Data command. This command\n   * will send the message to the users terminal if they are logged\n   * in or mail it to them if they are not.\n   *\n   * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE SUCCESS: 552,451,452\n   * SMTP CODE SUCCESS: 500,501,502,421\n   * @access public\n   * @return bool\n   */\n  function SendOrMail($from) {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n          \"error\" => \"Called SendOrMail() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"SOML FROM:\" . $from . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250) {\n      $this->error =\n        array(\"error\" => \"SOML not accepted from server\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * This is an optional command for SMTP that this class does not\n   * support. This method is here to make the RFC821 Definition\n   * complete for this class and __may__ be implimented in the future\n   *\n   * Implements from rfc 821: TURN <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250\n   * SMTP CODE FAILURE: 502\n   * SMTP CODE ERROR  : 500, 503\n   * @access public\n   * @return bool\n   */\n  function Turn() {\n    $this->error = array(\"error\" => \"This method, TURN, of the SMTP \".\n                                    \"is not implemented\");\n    if($this->do_debug >= 1) {\n      echo \"SMTP -> NOTICE: \" . $this->error[\"error\"] . $this->CRLF;\n    }\n    return false;\n  }\n\n  /**\n   * Verifies that the name is recognized by the server.\n   * Returns false if the name could not be verified otherwise\n   * the response from the server is returned.\n   *\n   * Implements rfc 821: VRFY <SP> <string> <CRLF>\n   *\n   * SMTP CODE SUCCESS: 250,251\n   * SMTP CODE FAILURE: 550,551,553\n   * SMTP CODE ERROR  : 500,501,502,421\n   * @access public\n   * @return int\n   */\n  function Verify($name) {\n    $this->error = null; # so no confusion is caused\n\n    if(!$this->connected()) {\n      $this->error = array(\n              \"error\" => \"Called Verify() without being connected\");\n      return false;\n    }\n\n    fputs($this->smtp_conn,\"VRFY \" . $name . $this->CRLF);\n\n    $rply = $this->get_lines();\n    $code = substr($rply,0,3);\n\n    if($this->do_debug >= 2) {\n      echo \"SMTP -> FROM SERVER:\" . $this->CRLF . $rply;\n    }\n\n    if($code != 250 && $code != 251) {\n      $this->error =\n        array(\"error\" => \"VRFY failed on name '$name'\",\n              \"smtp_code\" => $code,\n              \"smtp_msg\" => substr($rply,4));\n      if($this->do_debug >= 1) {\n        echo \"SMTP -> ERROR: \" . $this->error[\"error\"] .\n                 \": \" . $rply . $this->CRLF;\n      }\n      return false;\n    }\n    return $rply;\n  }\n\n  /*******************************************************************\n   *                       INTERNAL FUNCTIONS                       *\n   ******************************************************************/\n\n  /**\n   * Read in as many lines as possible\n   * either before eof or socket timeout occurs on the operation.\n   * With SMTP we can tell if we have more lines to read if the\n   * 4th character is '-' symbol. If it is a space then we don't\n   * need to read anything else.\n   * @access private\n   * @return string\n   */\n  function get_lines() {\n    $data = \"\";\n    while($str = @fgets($this->smtp_conn,515)) {\n      if($this->do_debug >= 4) {\n        echo \"SMTP -> get_lines(): \\$data was \\\"$data\\\"\" .\n                 $this->CRLF;\n        echo \"SMTP -> get_lines(): \\$str is \\\"$str\\\"\" .\n                 $this->CRLF;\n      }\n      $data .= $str;\n      if($this->do_debug >= 4) {\n        echo \"SMTP -> get_lines(): \\$data is \\\"$data\\\"\" . $this->CRLF;\n      }\n      # if the 4th character is a space then we are done reading\n      # so just break the loop\n      if(substr($str,3,1) == \" \") { break; }\n    }\n    return $data;\n  }\n\n}\n\n\n ?>\n"
  },
  {
    "path": "README.md",
    "content": "plugins\n=======\n\nTypecho插件列表\n"
  },
  {
    "path": "SaeUpload/Plugin.php",
    "content": "<?php\n/**\n * <a href=\"http://sae.sina.com.cn\" target=\"_blank\">Sina App Engine</a>专用的文件上传插件，使用Storage做持久化存储。\n * \n * @package SaeUpload\n * @author Kimi\n * @version 1.0.0 Beta\n * @link http://www.ccvita.com/491.html\n */\nclass SaeUpload_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Upload')->uploadHandle = array('SaeUpload_Plugin', 'uploadHandle');\n        Typecho_Plugin::factory('Widget_Upload')->modifyHandle = array('SaeUpload_Plugin', 'modifyHandle');\n        Typecho_Plugin::factory('Widget_Upload')->deleteHandle = array('SaeUpload_Plugin', 'deleteHandle');\n        Typecho_Plugin::factory('Widget_Upload')->attachmentHandle = array('SaeUpload_Plugin', 'attachmentHandle');\n        Typecho_Plugin::factory('Widget_Upload')->attachmentDataHandle = array('SaeUpload_Plugin', 'attachmentDataHandle');\n        \n        return _t('请您在 <a href=\"http://sae.sina.com.cn/?m=storage&app_id='.$_SERVER['HTTP_APPNAME'].'\" target=\"_blank\">Sina App Engine控制面板</a> 中创建Storage的Domain: 名称固定为 <strong>typechoupload</strong>');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $domainName = new Typecho_Widget_Helper_Form_Element_Text('saestoragedomain', NULL, 'typechoupload',\n        _t('Domain名称'), _t('请您在 <a href=\"http://sae.sina.com.cn/?m=storage&app_id='.$_SERVER['HTTP_APPNAME'].'\" target=\"_blank\">Sina App Engine控制面板</a> 中创建Storage的Domain: 名称固定为 <strong>typechoupload</strong>'));\n        $form->addInput($domainName->addRule(array('SaeUpload_Plugin', 'validateDomainName'), _t('Domain名称错误，或者未上传文件！')));\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 验证Sina App Engine Storage中DomainName是否存在\n     * \n     * @access public\n     * @param string $domainName domainName\n     * @return boolean\n     */\n    public static function validateDomainName($domainName)\n    {\n        return true;\n        /*\n        $stor = new SaeStorage();\n        $ret = $stor->getFilesNum($domainName);\n        if ($ret) {\n            return true;\n        } else {\n            return false;\n        }\n        */\n    }\n\n    /**\n     * 上传文件处理函数\n     *\n     * @access public\n     * @param array $file 上传的文件\n     * @return mixed\n     */\n    public static function uploadHandle($file)\n    {\n        if (empty($file['name'])) {\n            return false;\n        }\n\n        $fileName = preg_split(\"(\\/|\\\\|:)\", $file['name']);\n        $file['name'] = array_pop($fileName);\n        \n        //获取扩展名\n        $ext = '';\n        $part = explode('.', $file['name']);\n        if (($length = count($part)) > 1) {\n            $ext = strtolower($part[$length - 1]);\n        }\n\n        if (!self::checkFileType($ext)) {\n            return false;\n        }\n\n        //获取文件名\n        $fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext;\n        $path = $path . '/' . $fileName;//add for mkdir\n\n        $stor = new SaeStorage();\n        $options = Typecho_Widget::widget('Widget_Options');\n        $SaeStorageDomain = $options->plugin('SaeUpload')->saestoragedomain;\n\n        if (isset($file['tmp_name'])) {\n            //移动上传文件\n            if (!$path = $stor->upload($SaeStorageDomain,$fileName,$file['tmp_name'])) {\n                return false;\n            }\n        } else if (isset($file['bits'])) {\n            //直接写入文件\n            if (!$path = $stor->write($SaeStorageDomain,$fileName,$file['bits'])) {\n                return false;\n            }\n        } else {\n            return false;\n        }\n\n        if (!isset($file['size'])) {\n            $attr = $stor->getAttr($SaeStorageDomain,$fileName,array('length'));\n            $file['size'] = $attr['length'];\n        }\n\n        //返回相对存储路径\n        return array(\n            'name' => $file['name'],\n            'path' => $fileName,\n            'size' => $file['size'],\n            'type' => $ext,\n            'mime' => Typecho_Common::mimeContentType($path)\n        );\n    }\n\n    /**\n     * 修改文件处理函数\n     *\n     * @access public\n     * @param array $content 老文件\n     * @param array $file 新上传的文件\n     * @return mixed\n     */\n    public static function modifyHandle($content, $file)\n    {\n        if (empty($file['name'])) {\n            return false;\n        }\n\n        $fileName = preg_split(\"(\\/|\\\\|:)\", $file['name']);\n        $file['name'] = array_pop($fileName);\n        \n        //获取扩展名\n        $ext = '';\n        $part = explode('.', $file['name']);\n        if (($length = count($part)) > 1) {\n            $ext = strtolower($part[$length - 1]);\n        }\n\n        if ($content['attachment']->type != $ext) {\n            return false;\n        }\n\n        //获取文件名\n        $fileName = $content['attachment']->path;\n        $path = $path . '/' . $fileName;//add for mkdir\n\n        $stor = new SaeStorage();\n        $options = Typecho_Widget::widget('Widget_Options');\n        $SaeStorageDomain = $options->plugin('SaeUpload')->saestoragedomain;\n\n        if (isset($file['tmp_name'])) {\n            //移动上传文件\n            if (!$path = $stor->upload($SaeStorageDomain,$fileName,$file['tmp_name'])) {\n                return false;\n            }\n        } else if (isset($file['bits'])) {\n            //直接写入文件\n            if (!$path = $stor->write($SaeStorageDomain,$fileName,$file['bits'])) {\n                return false;\n            }\n        } else {\n            return false;\n        }\n\n        if (!isset($file['size'])) {\n            $attr = $stor->getAttr($SaeStorageDomain,$fileName,array('length'));\n            $file['size'] = $attr['length'];\n        }\n\n        //返回相对存储路径\n        return array(\n            'name' => $content['attachment']->name,\n            'path' => $content['attachment']->path,\n            'size' => $file['size'],\n            'type' => $content['attachment']->type,\n            'mime' => $content['attachment']->mime\n        );\n    }\n\n    /**\n     * 删除文件\n     *\n     * @access public\n     * @param array $content 文件相关信息\n     * @return string\n     */\n    public static function deleteHandle(array $content)\n    {\n        $stor = new SaeStorage();\n        $options = Typecho_Widget::widget('Widget_Options');\n        $SaeStorageDomain = $options->plugin('SaeUpload')->saestoragedomain;\n        return $stor->delete($SaeStorageDomain,$content['attachment']->path);\n    }\n\n    /**\n     * 获取实际文件绝对访问路径\n     *\n     * @access public\n     * @param array $content 文件相关信息\n     * @return string\n     */\n    public static function attachmentHandle(array $content)\n    {\n        $stor = new SaeStorage();\n        $options = Typecho_Widget::widget('Widget_Options');\n        $SaeStorageDomain = $options->plugin('SaeUpload')->saestoragedomain;\n        return $stor->getUrl($SaeStorageDomain,$content['attachment']->path);\n    }\n\n    /**\n     * 获取实际文件数据\n     *\n     * @access public\n     * @param array $content\n     * @return string\n     */\n    public static function attachmentDataHandle(array $content)\n    {\n        $stor = new SaeStorage();\n        $options = Typecho_Widget::widget('Widget_Options');\n        $SaeStorageDomain = $options->plugin('SaeUpload')->saestoragedomain;\n        return $stor->read($SaeStorageDomain,$content['attachment']->path);\n    }\n\n    /**\n     * 检查文件名\n     *\n     * @access private\n     * @param string $ext 扩展名\n     * @return boolean\n     */\n    public static function checkFileType($ext)\n    {\n        $options = Typecho_Widget::widget('Widget_Options');\n        return in_array($ext, $options->allowedAttachmentTypes);\n    }\n}\n"
  },
  {
    "path": "ShareCode/Plugin.php",
    "content": "<?php\n/**\n * 直接在在文章中插入[embed_snipt:{code_id}]（{code_id}为snipt上面的id）就可引用http://snipt.org/上分享的代码\n * \n * @package ShareCode\n * @author blankyao\n * @version 1.0.0\n * @link http://www.blankyao.cn\n */\n\nclass ShareCode_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        /** 前端输出处理接口 */\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->content = array('ShareCode_Plugin', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->excerpt = array('ShareCode_Plugin', 'parse');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n\n    /**\n     * 解析内容\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function parse($value, $lastResult)\n    {\n        $value = empty($lastResult) ? $value : $lastResult;\n        $regex = '/\\[embed_snipt:(.*?)]/i';\n        preg_match_all( $regex, $value, $matches);\n        \n        $count = count($matches[0]);\n        for($i = 0;$i < $count;$i++) {\n            $url = $matches[1][$i];\n            $url = '<script type=\"text/javascript\" src=\"http://embed.snipt.org/'. $url .'\"></script>';\n            \n            $value = str_replace($matches[0][$i], $url, $value);\n        }\n        \n        return $value;\n    }\n}"
  },
  {
    "path": "SimpleCode.php",
    "content": "<?php\n/**\n * 解析内容源代码中的code串\n * \n * @package Simple Code \n * @author qining\n * @version 1.0.2\n * @dependence 9.9.2-*\n * @link http://typecho.org\n */\nclass SimpleCode implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('SimpleCode', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('SimpleCode', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Comments')->contentEx = array('SimpleCode', 'parse');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 解析\n     * \n     * @access public\n     * @param array $matches 解析值\n     * @return string\n     */\n    public static function parseCallback($matches)\n    {\n        return highlight_string(trim($matches[2]), true);\n    }\n    \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function parse($text, $widget, $lastResult)\n    {\n        $text = empty($lastResult) ? $text : $lastResult;\n        \n        if ($widget instanceof Widget_Archive || $widget instanceof Widget_Abstract_Comments) {\n            return preg_replace_callback(\"/<code(\\s*[^>]*)>(.*?)<\\/code>/is\", array('SimpleCode', 'parseCallback'), $text);\n        } else {\n            return $text;\n        }\n    }\n}\n"
  },
  {
    "path": "Textile2/Plugin.php",
    "content": "<?php\n/**\n * This is a wrapper for Jim Riggs' <a href=\"http://jimandlissa.com/project/textilephp\">PHP implementation</a> of <a href=\"http://bradchoate.com/mt-plugins/textile\">Brad Choate's Textile 2</a>.  It is feature compatible with the MovableType plugin. <strong>Does not play well with the Markdown, Textile, or Textile 2 plugins that ship with WordPress.</strong>  Packaged by <a href=\"http://idly.org/\">Adam Gessaman</a>.\n * \n * @package Textile 2 (Improved)\n * @author Jim Riggs\n * @version 2.1.1\n * @dependence 9.9.2-*\n * @link http://jimandlissa.com/project/textilephp\n */\n \nrequire('Textile2/Textile.php');\n\nclass Textile2_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->excerpt = array('Textile2_Plugin', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Contents')->content = array('Textile2_Plugin', 'parse');\n        Typecho_Plugin::factory('Widget_Abstract_Comments')->content = array('Textile2_Plugin', 'parse');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate(){}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $version = new Typecho_Widget_Helper_Form_Element_Radio('version', \n        array('MTTextile' => 'MTTextile - includes Brad Choates\\' extensions.',\n        'Textile' => 'Textile for the Textile purist.'), 'MTTextile',\n        'Textile Flavor');\n        $form->addInput($version->multiMode());\n\n        $filters = new Typecho_Widget_Helper_Form_Element_Checkbox('filters', \n        array('SmartyPants' => 'Apply SmartyPants (provides em and en dashes, and other typographic niceities)',\n        'EducateQuotes' => 'Apply Texturize (applies curly quotes)'),\n        array('SmartyPants', 'EducateQuotes'), 'Text Filters');\n        $form->addInput($filters->multiMode());\n        \n        $headerOffset = new Typecho_Widget_Helper_Form_Element_Select('headerOffset', \n        array('0 (.h1 = .h1)', '1 (.h1 = .h2)', '2 (.h1 = .h3)', '3 (.h1 = .h4)', '4 (.h1 = .h5)', '5 (.h1 = .h6)'),\n        0, 'Header Offset');\n        $form->addInput($headerOffset);\n        \n        $parsing = new Typecho_Widget_Helper_Form_Element_Checkbox('parsing', \n        array('ClearLines' => 'Strip extra spaces from the end of each line.',\n        'PreserveSpaces' => 'Change double-spaces to the HTML entity for an em-space (&8195;).'),\n        NULL, 'Parsing Options');\n        $form->addInput($parsing->multiMode());\n        \n        $inputEncoding = new Typecho_Widget_Helper_Form_Element_Text('inputEncoding', NULL, Helper::options()->charset,\n        _t('Input Character Encoding'));\n        $inputEncoding->input->setAttribute('class', 'mini');\n        $form->addInput($inputEncoding);\n        \n        $encoding = new Typecho_Widget_Helper_Form_Element_Text('encoding', NULL, Helper::options()->charset,\n        _t('Output Character Encoding'));\n        $encoding->input->setAttribute('class', 'mini');\n        $form->addInput($encoding);\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function parse($text, $widget, $lastResult)\n    {\n        $text = empty($lastResult) ? $text : $lastResult;\n        \n        $settings = Helper::options()->plugin('Textile2');\n        \n        if ($settings->version == 'Textile') {\n            $textile = new Textile;\n        } else {\n            $textile = new MTLikeTextile;\n        }\n\n        $textile->options['head_offset'] = $settings->headerOffset;\n        $textile->options['char_encoding'] = $settings->encoding;\n        $textile->options['input_encoding'] = $settings->inputEncoding;\n        \n        $textile->options['do_quotes'] = $settings->filters && in_array('EducateQuotes', $settings->filters);\n        $textile->options['smarty_mode'] = $settings->filters && in_array('SmartyPants', $settings->filters);\n        $textile->options['trim_spaces'] = $settings->parsing && in_array('ClearLines', $settings->parsing);\n        $textile->options['preserve_spaces'] = $settings->parsing && in_array('PreserveSpaces', $settings->parsing);\n\n        return $textile->process($text);\n    }\n}\n"
  },
  {
    "path": "Textile2/Textile.php",
    "content": "<?php\n// @(#) $Id: Textile.php,v 1.13 2005/03/21 15:26:55 jhriggs Exp $\n\n/* This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA\n */\n\n/**\n * The Textile class serves as a wrapper for all Textile\n * functionality. It is not inherently necessary that Textile be a\n * class; however, this is as close as one can get to a namespace in\n * PHP. Wrapping the functionality in a class prevents name\n * collisions and dirtying of the global namespace. The Textile class\n * uses no global variables and will not have any side-effects on\n * other code.\n *\n * @brief Class wrapper for the Textile functionality.\n */\nclass Textile {\n  /**\n   * The @c array containing all of the Textile options for this\n   * object.\n   *\n   * @private\n   */\n  var $options = array();\n\n  /**\n   * The @c string containing the regular expression pattern for a\n   * URL. This variable is initialized by @c _create_re() which is\n   * called in the contructor.\n   *\n   * @private\n   */\n  var $urlre;\n\n  /**\n   * The @c string containing the regular expression pattern for\n   * punctuation characters. This variable is initialized by\n   * @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $punct;\n\n  /**\n   * The @c string containing the regular expression pattern for the\n   * valid vertical alignment codes. This variable is initialized by\n   * @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $valignre;\n\n  /**\n   * The @c string containing the regular expression pattern for the\n   * valid table alignment codes. This variable is initialized by\n   * @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $tblalignre;\n\n  /**\n   * The @c string containing the regular expression pattern for the\n   * valid horizontal alignment codes. This variable is initialized by\n   * @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $halignre;\n\n  /**\n   * The @c string containing the regular expression pattern for the\n   * valid alignment codes. This variable is initialized by\n   * @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $alignre;\n\n  /**\n   * The @c string containing the regular expression pattern for the\n   * valid image alignment codes. This variable is initialized by\n   * @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $imgalignre;\n\n  /**\n   * The @c string containing the regular expression pattern for a\n   * class, ID, and/or padding specification. This variable is\n   * initialized by @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $clstypadre;\n\n  /**\n   * The @c string containing the regular expression pattern for a\n   * class and/or ID specification. This variable is initialized by\n   * @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $clstyre;\n\n  /**\n   * The @c string containing the regular expression pattern for a\n   * class, ID, and/or filter specification. This variable is\n   * initialized by @c _create_re() which is called in the contructor.\n   *\n   * @private\n   */\n  var $clstyfiltre;\n\n  /**\n   * The @c string containing the regular expression pattern for a\n   * code block. This variable is initialized by @c _create_re() which\n   * is called in the contructor.\n   *\n   * @private\n   */\n  var $codere;\n\n  /**\n   * The @c string containing the regular expression pattern for all\n   * block tags. This variable is initialized by @c _create_re() which\n   * is called in the contructor.\n   *\n   * @private\n   */\n  var $blocktags;\n\n  /**\n   * The @c array containing the list of lookup links.\n   *\n   * @private\n   */\n  var $links = array();\n\n  /**\n   * The @c array containing <code>array</code>s of replacement blocks\n   * of text that are temporary removed from the input text to avoid\n   * processing. Different functions use this replacement\n   * functionality, and each shifts its own replacement array into\n   * position 0 and removes it when finished. This avoids having\n   * several replacement variables and/or functions clobbering\n   * eachothers' replacement blocks.\n   *\n   * @private\n   */\n  var $repl = array();\n\n  /**\n   * The @c array containing temporary <code>string</code>s used in\n   * replacement callbacks. *JHR*\n   *\n   * @private\n   */\n  var $tmp = array();\n\n  /**\n   * Instantiates a new Textile object. Optional options\n   * can be passed to initialize the object. Attributes for the\n   * options key are the same as the get/set method names\n   * documented here.\n   *\n   * @param $options The @c array specifying the options to use for\n   *        this object.\n   *\n   * @public\n   */\n  function Textile($options = array()) {\n    $this->options = $options;\n    $this->options['filters'] = ($this->options['filters'] ? $this->options['filters'] : array());\n    $this->options['charset'] = ($this->options['charset'] ? $this->options['charset'] : 'iso-8859-1');\n    $this->options['char_encoding'] = (isset($this->options['char_encoding']) ? $this->options['char_encoding'] : 1);\n    $this->options['do_quotes'] = (isset($this->options['do_quotes']) ? $this->options['do_quotes'] : 1);\n    $this->options['trim_spaces'] = (isset($this->options['trim_spaces']) ? $this->options['trim_spaces'] : 0);\n    $this->options['smarty_mode'] = (isset($this->options['smarty_mode']) ? $this->options['smarty_mode'] : 1);\n    $this->options['preserve_spaces'] = (isset($this->options['preserve_spaces']) ? $this->options['preserve_spaaces'] : 0);\n    $this->options['head_offset'] = (isset($this->options['head_offset']) ? $this->options['head_offset'] : 0);\n\n    if (is_array($this->options['css'])) {\n      $this->css($this->options['css']);\n    }\n    $this->options['macros'] = ($this->options['macros'] ? $this->options['macros'] : $this->default_macros());\n    if (isset($this->options['flavor'])) {\n      $this->flavor($this->options['flavor']);\n    } else {\n      $this->flavor('xhtml1/css');\n    }\n    $this->_create_re();\n  } // function Textile\n\n  // getter/setter methods...\n\n  /**\n   * Used to set Textile attributes. Attribute names are the same\n   * as the get/set method names documented here.\n   *\n   * @param $opt A @c string specifying the name of the option to\n   *        change or an @c array specifying options and values.\n   * @param $value The value for the provided option name.\n   *\n   * @public\n   */\n  function set($opt, $value = NULL) {\n    if (is_array($opt)) {\n      foreach ($opt as $opt => $value) {\n        $this->set($opt, $value);\n      }\n    } else {\n      // the following options have special set methods\n      // that activate upon setting:\n      if ($opt == 'charset') {\n        $this->charset($value);\n      } elseif ($opt == 'css') {\n        $this->css($value);\n      } elseif ($opt == 'flavor') {\n        $this->flavor($value);\n      } else {\n        $this->options[$opt] = $value;\n      }\n    }\n  } // function set\n\n  /**\n   * Used to get Textile attributes. Attribute names are the same\n   * as the get/set method names documented here.\n   *\n   * @param $opt A @c string specifying the name of the option to get.\n   *\n   * @return The value for the provided option.\n   *\n   * @public\n   */\n  function get($opt) {\n    return $this->options[$opt];\n  } // function get\n\n  /**\n   * Gets or sets the \"disable html\" control, which allows you to\n   * prevent HTML tags from being used within the text processed.\n   * Any HTML tags encountered will be removed if disable html is\n   * enabled. Default behavior is to allow HTML.\n   *\n   * @param $disable_html If provided, a @c bool indicating whether or\n   *        not this object should disable HTML.\n   *\n   * @return A true value if this object disables HTML; a false value\n   *         otherwise.\n   *\n   * @public\n   */\n  function disable_html($disable_html = NULL) {\n    if ($disable_html != NULL) {\n      $this->options['disable_html'] = $disable_html;\n    }\n    return ($this->options['disable_html'] ? $this->options['disable_html'] : 0);\n  } // function disable_html\n\n  /**\n   * Gets or sets the relative heading offset, which allows you to\n   * change the heading level used within the text processed. For\n   * example, if the heading offset is '2' and the text contains an\n   * 'h1' block, an \\<h3\\> block will be output.\n   *\n   * @param $head_offset If provided, an @c integer specifying the\n   *        heading offset for this object.\n   *\n   * @return An @c integer containing the heading offset for this\n   *         object.\n   *\n   * @public\n   */\n  function head_offset($head_offset = NULL) {\n    if ($head_offset != NULL) {\n      $this->options['head_offset'] = $head_offset;\n    }\n    return ($this->options['head_offset'] ? $this->options['head_offset'] : 0);\n  } // function head_offset\n\n  /**\n   * Assigns the HTML flavor of output from Textile. Currently\n   * these are the valid choices: html, xhtml (behaves like \"xhtml1\"),\n   * xhtml1, xhtml2. Default flavor is \"xhtml1\".\n   *\n   * Note that the xhtml2 flavor support is experimental and incomplete\n   * (and will remain that way until the XHTML 2.0 draft becomes a\n   * proper recommendation).\n   *\n   * @param $flavor If provided, a @c string specifying the flavor to\n   *        be used for this object.\n   *\n   * @return A @c string containing the flavor for this object.\n   *\n   * @public\n   */\n  function flavor($flavor = NULL) {\n    if ($flavor != NULL) {\n      $this->options['flavor'] = $flavor;\n      if (preg_match('/^xhtml(\\d)?(\\D|$)/', $flavor, $matches)) {\n        if ($matches[1] == '2') {\n          $this->options['_line_open'] = '<l>';\n          $this->options['_line_close'] = '</l>';\n          $this->options['_blockcode_open'] = '<blockcode>';\n          $this->options['_blockcode_close'] = '</blockcode>';\n          $this->options['css_mode'] = 1;\n        } else {\n          // xhtml 1.x\n          $this->options['_line_open'] = '';\n          $this->options['_line_close'] = '<br />';\n          $this->options['_blockcode_open'] = '<pre><code>';\n          $this->options['_blockcode_close'] = '</code></pre>';\n          $this->options['css_mode'] = 1;\n        }\n      } elseif (preg_match('/^html/', $flavor)) {\n        $this->options['_line_open'] = '';\n        $this->options['_line_close'] = '<br>';\n        $this->options['_blockcode_open'] = '<pre><code>';\n        $this->options['_blockcode_close'] = '</code></pre>';\n        $this->options['css_mode'] = preg_match('/\\/css/', $flavor);\n      }\n      if ($this->options['css_mode'] && !isset($this->options['css'])) { $this->_css_defaults(); }\n    }\n    return $this->options['flavor'];\n  } // function flavor\n\n  /**\n   * Gets or sets the css support for Textile. If css is enabled,\n   * Textile will emit CSS rules. You may pass a 1 or 0 to enable\n   * or disable CSS behavior altogether. If you pass an associative array,\n   * you may assign the CSS class names that are used by\n   * Textile. The following key names for such an array are\n   * recognized:\n   *\n   * <ul>\n   * <li><b>class_align_right</b>\n   *\n   * defaults to 'right'</li>\n   *\n   * <li><b>class_align_left</b>\n   *\n   * defaults to 'left'</li>\n   *\n   * <li><b>class_align_center</b>\n   *\n   * defaults to 'center'</li>\n   *\n   * <li><b>class_align_top</b>\n   *\n   * defaults to 'top'</li>\n   *\n   * <li><b>class_align_bottom</b>\n   *\n   * defaults to 'bottom'</li>\n   *\n   * <li><b>class_align_middle</b>\n   *\n   * defaults to 'middle'</li>\n   *\n   * <li><b>class_align_justify</b>\n   *\n   * defaults to 'justify'</li>\n   *\n   * <li><b>class_caps</b>\n   *\n   * defaults to 'caps'</li>\n   *\n   * <li><b>class_footnote</b>\n   *\n   * defaults to 'footnote'</li>\n   *\n   * <li><b>id_footnote_prefix</b>\n   *\n   * defaults to 'fn'</li>\n   *\n   * </ul>\n   *\n   * @param $css If provided, either a @c bool indicating whether or\n   *        not this object should use css or an associative @c array\n   *        specifying class names to use.\n   *\n   * @return Either an associative @c array containing class names\n   *         used by this object, or a true or false value indicating\n   *         whether or not this object uses css.\n   *\n   * @public\n   */\n  function css($css = NULL) {\n    if ($css != NULL) {\n      if (is_array($css)) {\n        $this->options['css'] = $css;\n        $this->options['css_mode'] = 1;\n      } else {\n        $this->options['css_mode'] = $css;\n        if ($this->options['css_mode'] && !isset($this->options['css'])) { $this->_css_defaults(); }\n      }\n    }\n    return ($this->options['css_mode'] ? $this->options['css'] : 0);\n  } // function css\n\n  /**\n   * Gets or sets the character set targetted for publication.\n   * At this time, Textile only changes its behavior\n   * if the 'utf-8' character set is assigned.\n   *\n   * Specifically, if utf-8 is requested, any special characters\n   * created by Textile will be output as native utf-8 characters\n   * rather than HTML entities.\n   *\n   * @param $charset If provided, a @c string specifying the\n   *        characater set to be used for this object.\n   *\n   * @return A @c string containing the character set for this object.\n   *\n   * @public\n   */\n  function charset($charset = NULL) {\n    if ($charset != NULL) {\n        $this->options['charset'] = $charset;\n        if (preg_match('/^utf-?8$/i', $this->options['charset'])) {\n          $this->char_encoding(0);\n        } else {\n          $this->char_encoding(1);\n        }\n    }\n    return $this->options['charset'];\n  } // function charset\n\n  /**\n   * Gets or sets the physical file path to root of document files.\n   * This path is utilized when images are referenced and size\n   * calculations are needed (the getimagesize() function is used to read\n   * the image dimensions).\n   *\n   * @param $docroot If provided, a @c string specifying the document\n   *        root to use for this object.\n   *\n   * @return A @c string containing the docroot for this object.\n   *\n   * @public\n   */\n  function docroot($docroot = NULL) {\n    if ($docroot != NULL) {\n      $this->options['docroot'] = $docroot;\n    }\n    return $this->options['docroot'];\n  } // function docroot\n\n  /**\n   * Gets or sets the 'trim spaces' control flag. If enabled, this\n   * will clear any lines that have only spaces on them (the newline\n   * itself will remain).\n   *\n   * @param $trim_spaces If provided, a @c bool indicating whether or\n   *        not this object should trim spaces.\n   *\n   * @return A true value if this object trims spaces; a false value\n   *         otherwise.\n   *\n   * @public\n   */\n  function trim_spaces($trim_spaces = NULL) {\n    if ($trim_spaces != NULL) {\n      $this->options['trim_spaces'] = $trim_spaces;\n    }\n    return $this->options['trim_spaces'];\n  } // function trim_spaces\n\n  /**\n   * Gets or sets a parameter that is passed to filters.\n   *\n   * @param $filter_param If provided, a parameter that this object\n   *        should pass to filters.\n   *\n   * @return The parameter this object passes to filters.\n   *\n   * @public\n   */\n  function filter_param($filter_param = NULL) {\n    if ($filter_param != NULL) {\n      $this->options['filter_param'] = $filter_param;\n    }\n    return $this->options['filter_param'];\n  } // function filter_param\n\n  /**\n   * Gets or sets the 'preserve spaces' control flag. If enabled, this\n   * will replace any double spaces within the paragraph data with the\n   * \\&amp;#8195; HTML entity (wide space). The default is 0. Spaces will\n   * pass through to the browser unchanged and render as a single space.\n   * Note that this setting has no effect on spaces within \\<pre\\>,\n   * \\<code\\> blocks or \\<script\\> sections.\n   *\n   * @param $preserve_spaces If provided, a @c bool indicating whether\n   *        or not this object should preserve spaces.\n   *\n   * @return A true value if this object preserves spaces; a false\n   *         value otherwise.\n   *\n   * @public\n   */\n  function preserve_spaces($preserve_spaces = NULL) {\n    if ($preserve_spaces != NULL) {\n      $this->options['preserve_spaces'] = $preserve_spaces;\n    }\n    return $this->options['preserve_spaces'];\n  } // function preserve_spaces\n\n  /**\n   * Gets or sets a list of filters to make available for\n   * Textile to use. Returns a hash reference of the currently\n   * assigned filters.\n   *\n   * @param $filters If provided, an @c array of filters to be used\n   *        for this object.\n   *\n   * @return An @c array containing the filters for this object.\n   *\n   * @public\n   */\n  function filters($filters = NULL) {\n    if ($filters != NULL) {\n      $this->options['filters'] = $filters;\n    }\n    return $this->options['filters'];\n  } // function filters\n\n  /**\n   * Gets or sets the character encoding logical flag. If character\n   * encoding is enabled, the htmlentities function is used to\n   * encode special characters. If character encoding is disabled,\n   * only \\<, \\>, \" and & are encoded to HTML entities.\n   *\n   * @param $char_encoding If provided, a @c bool indicating whether\n   *        or not this object should encode special characters.\n   *\n   * @return A true value if this object encodes special characters; a\n   *         false value otherwise.\n   *\n   * @public\n   */\n  function char_encoding($char_encoding = NULL) {\n    if ($char_encoding != NULL) {\n      $this->options['char_encoding'] = $char_encoding;\n    }\n    return $this->options['char_encoding'];\n  } // function char_encoding\n\n  /**\n   * Gets or sets the \"smart quoting\" control flag. Returns the\n   * current setting.\n   *\n   * @param $do_quotes If provided, a @c bool indicating whether or\n   *        not this object should use smart quoting.\n   *\n   * @return A true value if this object uses smart quoting; a false\n   *         value otherwise.\n   *\n   * @public\n   */\n  function handle_quotes($do_quotes = NULL) {\n    if ($do_quotes != NULL) {\n      $this->options['do_quotes'] = $do_quotes;\n    }\n    return $this->options['do_quotes'];\n  } // function handle_quotes\n\n  // end of getter/setter methods\n\n  /**\n   * Creates the class variable regular expression patterns used by\n   * Textile. They are not initialized in the declaration, because\n   * some rely on the others, requiring a @c $this reference.\n   *\n   * PHP does not have the Perl qr operator to quote or precompile\n   * patterns, so to avoid escaping and matching problems, all\n   * patterns must use the same delimiter; this implementation uses\n   * {}. Every use of these patterns within this class has been\n   * changed to use these delimiters. *JHR*\n   *\n   * @private\n   */\n  function _create_re() {\n    // a URL discovery regex. This is from Mastering Regex from O'Reilly.\n    // Some modifications by Brad Choate <brad at bradchoate dot com>\n    $this->urlre = '(?:\n    # Must start out right...\n    (?=[a-zA-Z0-9./#])\n    # Match the leading part (proto://hostname, or just hostname)\n    (?:\n        # ftp://, http://, or https:// leading part\n        (?:ftp|https?|telnet|nntp)://(?:\\w+(?::\\w+)?@)?[-\\w]+(?:\\.\\w[-\\w]*)+\n        |\n        (?:mailto:)?[-\\+\\w]+@[-\\w]+(?:\\.\\w[-\\w]*)+\n        |\n        # or, try to find a hostname with our more specific sub-expression\n        (?i: [a-z0-9] (?:[-a-z0-9]*[a-z0-9])? \\. )+ # sub domains\n        # Now ending .com, etc. For these, require lowercase\n        (?-i: com\\b\n            | edu\\b\n            | biz\\b\n            | gov\\b\n            | in(?:t|fo)\\b # .int or .info\n            | mil\\b\n            | net\\b\n            | org\\b\n            | museum\\b\n            | aero\\b\n            | coop\\b\n            | name\\b\n            | pro\\b\n            | [a-z][a-z]\\b # two-letter country codes\n        )\n    )?\n\n    # Allow an optional port number\n    (?: : \\d+ )?\n\n    # The rest of the URL is optional, and begins with / . . .\n    (?:\n     /?\n     # The rest are heuristics for what seems to work well\n     [^.!,?;:\"\\'<>()\\[\\]{}\\s\\x7F-\\xFF]*\n     (?:\n        [.!,?;:]+  [^.!,?;:\"\\'<>()\\[\\]{}\\s\\x7F-\\xFF]+ #\\'\"\n     )*\n    )?\n)';\n\n    $this->punct = '[\\!\"\\#\\$%&\\'()\\*\\+,\\-\\./:;<=>\\?@\\[\\\\\\\\\\]\\^_`{\\|}\\~]';\n    $this->valignre = '[\\-^~]';\n    $this->tblalignre = '[<>=]';\n    $this->halignre = '(?:<>|[<>=])';\n    $this->alignre = '(?:(?:' . $this->valignre . '|<>' . $this->valignre . '?|' . $this->valignre . '?<>|' . $this->valignre . '?' . $this->halignre . '?|' . $this->halignre . '?' . $this->valignre . '?)(?!\\w))';\n    $this->imgalignre = '(?:(?:[<>]|' . $this->valignre . '){1,2})';\n\n    $this->clstypadre = '(?:\n  (?:\\([A-Za-z0-9_\\- \\#]+\\))\n  |\n  (?:{\n      (?: \\( [^)]+ \\) | [^\\}] )+\n     })\n  |\n  (?:\\(+? (?![A-Za-z0-9_\\-\\#]) )\n  |\n  (?:\\)+?)\n  |\n  (?: \\[ [a-zA-Z\\-]+? \\] )\n)';\n\n    $this->clstyre = '(?:\n  (?:\\([A-Za-z0-9_\\- \\#]+\\))\n  |\n  (?:{\n      [A-Za-z0-9_\\-](?: \\( [^)]+ \\) | [^\\}] )+\n     })\n  |\n  (?: \\[ [a-zA-Z\\-]+? \\] )\n)';\n\n    $this->clstyfiltre = '(?:\n  (?:\\([A-Za-z0-9_\\- \\#]+\\))\n  |\n  (?:{\n      [A-Za-z0-9_\\-](?: \\( [^)]+ \\) | [^\\}] )+\n     })\n  |\n  (?:\\|[^\\|]+\\|)\n  |\n  (?:\\(+?(?![A-Za-z0-9_\\-\\#]))\n  |\n  (?:\\)+)\n  |\n  (?: \\[ [a-zA-Z]+? \\] )\n)';\n\n    $this->codere = '(?:\n    (?:\n      [\\[{]\n      @                           # opening\n      (?:\\[([A-Za-z0-9]+)\\])?     # $1: language id\n      (.+?)                       # $2: code\n      @                           # closing\n      [\\]}]\n    )\n    |\n    (?:\n      (?:^|(?<=[\\s\\(]))\n      @                           # opening\n      (?:\\[([A-Za-z0-9]+)\\])?     # $3: language id\n      ([^\\s].+?[^\\s])             # $4: code itself\n      @                           # closing\n      (?:$|(?=' . $this->punct . '{1,2}|\\s))\n    )\n)';\n\n    $this->blocktags = '\n    <\n    (( /? ( h[1-6]\n     | p\n     | pre\n     | div\n     | table\n     | t[rdh]\n     | [ou]l\n     | li\n     | block(?:quote|code)\n     | form\n     | input\n     | select\n     | option\n     | textarea\n     )\n    [ >]\n    )\n    | !--\n    )\n';\n  } // function _create_re\n\n  /**\n   * Transforms the provided text using Textile markup rules.\n   *\n   * @param $str The @c string specifying the text to process.\n   *\n   * @return A @c string containing the processed (X)HTML.\n   *\n   * @public\n   */\n  function process($str) {\n    /*\n     * Function names in PHP are case insensitive, so function\n     * textile() cannot be redefined.  Thus, this PHP implementation\n     * will only use process().\n     *\n     *   return $this->textile($str);\n     * } // function process\n     *\n     * function textile($str) {\n     */\n\n    // quick translator for abbreviated block names\n    // to their tag\n    $macros = array('bq' => 'blockquote');\n\n    // an array to hold any portions of the text to be preserved\n    // without further processing by Textile\n    array_unshift($this->repl, array());\n\n    // strip out extra newline characters. we're only matching for \\n herein\n    //$str = preg_replace('!(?:\\r?\\n|\\r)!', \"\\n\", $str);\n    $str = preg_replace('!(?:\\015?\\012|\\015)!', \"\\n\", $str);\n\n    // optionally remove trailing spaces\n    if ($this->options['trim_spaces']) { $str = preg_replace('/ +$/m', '', $str); }\n\n    // preserve contents of the '==', 'pre', 'blockcode' sections\n    $str = preg_replace_callback('{(^|\\n\\n)==(.+?)==($|\\n\\n)}s',\n                                 $this->_cb('\"$m[1]\\n\\n\" . $me->_repl($me->repl[0], $me->format_block(array(\"text\" => $m[2]))) . \"\\n\\n$m[3]\"'), $str);\n\n    if (!$this->disable_html()) {\n      // preserve style, script tag contents\n      $str = preg_replace_callback('!(<(style|script)(?:>| .+?>).*?</\\2>)!s', $this->_cb('$me->_repl($me->repl[0], $m[1])'), $str);\n\n      // preserve HTML comments\n      $str = preg_replace_callback('|(<!--.+?-->)|s', $this->_cb('$me->_repl($me->repl[0], $m[1])'), $str);\n\n      // preserve pre block contents, encode contents by default\n      $pre_start = count($this->repl[0]);\n      $str = preg_replace_callback('{(<pre(?: [^>]*)?>)(.+?)(</pre>)}s',\n                                   $this->_cb('\"\\n\\n\" . $me->_repl($me->repl[0], $m[1] . $me->encode_html($m[2], 1) . $m[3]) . \"\\n\\n\"'), $str);\n      // fix code tags within pre blocks we just saved.\n      for ($i = $pre_start; $i < count($this->repl[0]); $i++) {\n        $this->repl[0][$i] = preg_replace('|&lt;(/?)code(.*?)&gt;|s', '<$1code$2>', $this->repl[0][$i]);\n      }\n\n      // preserve code blocks by default, encode contents\n      $str = preg_replace_callback('{(<code(?: [^>]+)?>)(.+?)(</code>)}s',\n                                   $this->_cb('$me->_repl($me->repl[0], $m[1] . $me->encode_html($m[2], 1) . $m[3])'), $str);\n\n      // encode blockcode tag (an XHTML 2 tag) and encode it's\n      // content by default\n      $str = preg_replace_callback('{(<blockcode(?: [^>]+)?>)(.+?)(</blockcode>)}s',\n                                   $this->_cb('\"\\n\\n\" . $me->_repl($me->repl[0], $m[1] . $me->encode_html($m[2], 1) . $m[3]) . \"\\n\\n\"'), $str);\n\n      // preserve PHPish, ASPish code\n      $str = preg_replace_callback('!(<([\\?%]).*?(\\2)>)!s', $this->_cb('$me->_repl($me->repl[0], $m[1])'), $str);\n    }\n\n    // pass through and remove links that follow this format\n    // [id_without_spaces (optional title text)]url\n    // lines like this are stripped from the content, and can be\n    // referred to using the \"link text\":id_without_spaces syntax\n    //$links = array();\n    $str = preg_replace_callback('{(?:\\n|^) [ ]* \\[ ([^ ]+?) [ ]*? (?:\\( (.+?) \\) )?  \\] ((?:(?:ftp|https?|telnet|nntp)://|/)[^ ]+?) [ ]* (\\n|$)}mx',\n                                 $this->_cb('($me->links[$m[1]] = array(\"url\" => $m[3], \"title\" => $m[2])) ? $m[4] : $m[4]'), $str);\n    //$this->links = $links;\n\n    // eliminate starting/ending blank lines\n    $str = preg_replace('/^\\n+/s', '', $str, 1);\n    $str = preg_replace('/\\n+$/s', '', $str, 1);\n\n    // split up text into paragraph blocks, capturing newlines too\n    $para = preg_split('/(\\n{2,})/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);\n    unset($block, $bqlang, $filter, $class, $sticky, $lines,\n          $style, $stickybuff, $lang, $clear);\n\n    $out = '';\n\n    foreach ($para as $para) {\n      if (preg_match('/^\\n+$/s', $para)) {\n        if ($sticky && $stickybuff) {\n          $stickybuff .= $para;\n        } else {\n          $out .= $para;\n        }\n        continue;\n      }\n\n      if ($sticky) {\n        $sticky++;\n      } else {\n        unset($block);\n        unset($class);\n        $style = '';\n        unset($lang);\n      }\n\n      unset($id, $cite, $align, $padleft, $padright, $lines, $buffer);\n      if (preg_match('{^(h[1-6]|p|bq|bc|fn\\d+)\n                        ((?:' . $this->clstyfiltre . '*|' . $this->halignre . ')*)\n                        (\\.\\.?)\n                        (?::(\\d+|' . $this->urlre . '))?\\ (.*)$}sx', $para, $matches)) {\n        if ($sticky) {\n          if ($block == 'bc') {\n            // close our blockcode section\n            $out = preg_replace('/\\n\\n$/', '', $out, 1);\n            $out .= $this->options['_blockcode_close'] . \"\\n\\n\";\n          } elseif ($block == 'bq') {\n            $out = preg_replace('/\\n\\n$/', '', $out, 1);\n            $out .= '</blockquote>' . \"\\n\\n\";\n          } elseif ($block == 'table') {\n            $table_out = $this->format_table(array('text' => $stickybuff));\n            if (!$table_out) { $table_out = ''; }\n            $out .= $table_out;\n            unset($stickybuff);\n          } elseif ($block == 'dl') {\n            $dl_out = $this->format_deflist(array('text' => $stickybuff));\n            if (!$dl_out) { $dl_out = ''; }\n            $out .= $dl_out;\n            unset($stickybuff);\n          }\n          $sticky = 0;\n        }\n        // block macros: h[1-6](class)., bq(class)., bc(class)., p(class).\n        //warn \"paragraph: [[$para]]\\n\\tblock: $1\\n\\tparams: $2\\n\\tcite: $4\";\n        $block = $matches[1];\n        $params = $matches[2];\n        $cite = $matches[4];\n        if ($matches[3] == '..') {\n          $sticky = 1;\n        } else {\n          $sticky = 0;\n          unset($class);\n          unset($bqlang);\n          unset($lang);\n          $style = '';\n          unset($filter);\n        }\n        if (preg_match('/^h([1-6])$/', $block, $matches2)) {\n          if ($this->options['head_offset']) {\n            $block = 'h' . ($matches2[1] + $this->options['head_offset']);\n          }\n        }\n        if (preg_match('{(' . $this->halignre . '+)}', $params, $matches2)) {\n          $align = $matches2[1];\n          $params = preg_replace('{' . $this->halignre . '+}', '', $params, 1);\n        }\n        if ($params) {\n          if (preg_match('/\\|(.+)\\|/', $params, $matches2)) {\n            $filter = $matches2[1];\n            $params = preg_replace('/\\|.+?\\|/', '', $params, 1);\n          }\n          if (preg_match('/{([^}]+)}/', $params, $matches2)) {\n            $style = $matches2[1];\n            $style = preg_replace('/\\n/', ' ', $style);\n            $params = preg_replace('/{[^}]+}/', '', $params);\n          }\n          if (preg_match('/\\(([A-Za-z0-9_\\-\\ ]+?)(?:\\#(.+?))?\\)/', $params, $matches2) ||\n              preg_match('/\\(([A-Za-z0-9_\\-\\ ]+?)?(?:\\#(.+?))\\)/', $params, $matches2)) {\n            if ($matches2[1] || $matches2[2]) {\n              $class = $matches2[1];\n              $id = $matches2[2];\n              if ($class) {\n                $params = preg_replace('/\\([A-Za-z0-9_\\-\\ ]+?(#.*?)?\\)/', '', $params);\n              } elseif ($id) {\n                $params = preg_replace('/\\(#.+?\\)/', '', $params);\n              }\n            }\n          }\n          if (preg_match('/(\\(+)/', $params, $matches2)) {\n            $padleft = strlen($matches2[1]);\n            $params = preg_replace('/\\(+/', '', $params, 1);\n          }\n          if (preg_match('/(\\)+)/', $params, $matches2)) {\n            $padright = strlen($matches2[1]);\n            $params = preg_replace('/\\)+/', '', $params, 1);\n          }\n          if (preg_match('/\\[(.+?)\\]/', $params, $matches2)) {\n            $lang = $matches2[1];\n            if ($block == 'bc') {\n              $bqlang = $lang;\n              unset($lang);\n            }\n            $params = preg_replace('/\\[.+?\\]/', '', $params, 1);\n          }\n        }\n        // warn \"settings:\\n\\tblock: $block\\n\\tpadleft: $padleft\\n\\tpadright: $padright\\n\\tclass: $class\\n\\tstyle: $style\\n\\tid: $id\\n\\tfilter: $filter\\n\\talign: $align\\n\\tlang: $lang\\n\\tsticky: $sticky\";\n        $para = $matches[5];\n      } elseif (preg_match('|^<textile#(\\d+)>$|', $para, $matches)) {\n        $buffer = $this->repl[0][$matches[1] - 1];\n      } elseif (preg_match('/^clear([<>]+)?\\.$/', $para, $matches)) {\n        if ($matches[1] == '<') {\n          $clear = 'left';\n        } elseif ($matches[1] == '>') {\n          $clear = 'right';\n        } else {\n          $clear = 'both';\n        }\n        continue;\n      } elseif ($sticky && $stickybuff &&\n                ($block == 'table' || $block == 'dl')) {\n        $stickybuff .= $para;\n        continue;\n      } elseif (preg_match('{^(?:' . $this->halignre . '|' . $this->clstypadre . '*)*\n                              [\\*\\#]\n                              (?:' . $this->halignre . '|' . $this->clstypadre . '*)*\n                              \\ }x', $para)) {\n        // '*', '#' prefix means a list\n        $buffer = $this->format_list(array('text' => $para));\n      } elseif (preg_match('{^(?:table(?:' . $this->tblalignre . '|' . $this->clstypadre . '*)*\n                              (\\.\\.?)\\s+)?\n                              (?:_|' . $this->alignre . '|' . $this->clstypadre . '*)*\\|}x', $para, $matches)) {\n        // handle wiki-style tables\n        if ($matches[1] && ($matches[1] == '..')) {\n          $block = 'table';\n          $stickybuff = $para;\n          $sticky = 1;\n          continue;\n        } else {\n          $buffer = $this->format_table(array('text' => $para));\n        }\n      } elseif (preg_match('{^(?:dl(?:' . $this->clstyre . ')*(\\.\\.?)\\s+)}x', $para, $matches)) {\n        // handle definition lists\n        if ($matches[1] && ($matches[1] == '..')) {\n          $block = 'dl';\n          $stickybuff = $para;\n          $sticky = 1;\n          continue;\n        } else {\n          $buffer = $this->format_deflist(array('text' => $para));\n        }\n      }\n      if ($buffer) {\n        $out .= $buffer;\n        continue;\n      }\n      $lines = preg_split('/\\n/', $para);\n      if ((count($lines) == 1) && ($lines[0] == '')) {\n        continue;\n      }\n\n      $block = ($block ? $block : 'p');\n\n      $buffer = '';\n      $pre = '';\n      $post = '';\n\n      if ($block == 'bc') {\n        if ($sticky <= 1) {\n          $pre .= $this->options['_blockcode_open'];\n          $pre = preg_replace('/>$/s', '', $pre, 1);\n          if ($bqlang) { $pre .= \" language=\\\"$bqlang\\\"\"; }\n          if ($align) {\n            $alignment = $this->_halign($align);\n            if ($this->options['css_mode']) {\n              if (($padleft || $padright) &&\n                  (($alignment == 'left') || ($alignment == 'right'))) {\n                $style .= ';float:' . $alignment;\n              } else {\n                $style .= ';text-align:' . $alignment;\n              }\n              $class .= ' ' . ($this->options['css'][\"class_align_$alignment\"] ? $this->options['css'][\"class_align_$alignment\"] : $alignment);\n            } else {\n              if ($alignment) { $pre .= \" align=\\\"$alignment\\\"\"; }\n            }\n          }\n          if ($padleft) { $style .= \";padding-left:${padleft}em\"; }\n          if ($padright) { $style .= \";padding-right:${padright}em\"; }\n          if ($clear) { $style .= \";clear:${clear}\"; }\n          if ($class) { $class = preg_replace('/^ /', '', $class, 1); }\n          if ($class) { $pre .= \" class=\\\"$class\\\"\"; }\n          if ($id) { $pre .= \" id=\\\"$id\\\"\"; }\n          if ($style) { $style = preg_replace('/^;/', '', $style, 1); }\n          if ($style) { $pre .= \" style=\\\"$style\\\"\"; }\n          if ($lang) { $pre .= \" lang=\\\"$lang\\\"\"; }\n          $pre .= '>';\n          unset($lang);\n          unset($bqlang);\n          unset($clear);\n        }\n        $para = preg_replace_callback('{(?:^|(?<=[\\s>])|([{[]))\n                                        ==(.+?)==\n                                        (?:$|([\\]}])|(?=' . $this->punct . '{1,2}|\\s))}sx',\n                                      $this->_cb('$me->_repl($me->repl[0], $me->format_block(array(\"text\" => $m[2], \"inline\" => 1, \"pre\" => $m[1], \"post\" => $m[3])))'), $para);\n        $buffer .= $this->encode_html_basic($para, 1);\n        $buffer = preg_replace('/&lt;textile#(\\d+)&gt;/', '<textile#$1>', $buffer);\n        if ($sticky == 0) {\n          $post .= $this->options['_blockcode_close'];\n        }\n        $out .= $pre . $buffer . $post;\n        continue;\n      } elseif ($block == 'bq') {\n        if ($sticky <= 1) {\n          $pre .= '<blockquote';\n          if ($align) {\n            $alignment = $this->_halign($align);\n            if ($this->options['css_mode']) {\n              if (($padleft || $padright) &&\n                  (($alignment == 'left') || ($alignment == 'right'))) {\n                $style .= ';float:' . $alignment;\n              } else {\n                $style .= ';text-align:' . $alignment;\n              }\n              $class .= ' ' . ($this->options['css'][\"class_align_$alignment\"] ? $this->options['css'][\"class_align_$alignment\"] : $alignment);\n            } else {\n              if ($alignment) { $pre .= \" align=\\\"$alignment\\\"\"; }\n            }\n          }\n          if ($padleft) { $style .= \";padding-left:${padleft}em\"; }\n          if ($padright) { $style .= \";padding-right:${padright}em\"; }\n          if ($clear) { $style .= \";clear:${clear}\"; }\n          if ($class) { $class = preg_replace('/^ /', '', $class, 1); }\n          if ($class) { $pre .= \" class=\\\"$class\\\"\"; }\n          if ($id) { $pre .= \" id=\\\"$id\\\"\"; }\n          if ($style) { $style = preg_replace('/^;/', '', $style, 1); }\n          if ($style) { $pre .= \" style=\\\"$style\\\"\"; }\n          if ($lang) { $pre .= \" lang=\\\"$lang\\\"\"; }\n          if ($cite) { $pre .= ' cite=\"' . $this->format_url(array('url' => $cite)) . '\"'; }\n          $pre .= '>';\n          unset($clear);\n        }\n        $pre .= '<p>';\n      } elseif (preg_match('/fn(\\d+)/', $block, $matches)) {\n        $fnum = $matches[1];\n        $pre .= '<p';\n        if ($this->options['css']['class_footnote']) { $class .= ' ' . $this->options['css']['class_footnote']; }\n        if ($align) {\n          $alignment = $this->_halign($align);\n          if ($this->options['css_mode']) {\n            if (($padleft || $padright) &&\n                (($alignment == 'left') || ($alignment == 'right'))) {\n              $style .= ';float:' . $alignment;\n            } else {\n              $style .= ';text-align:' . $alignment;\n            }\n            $class .= ($this->options['css'][\"class_align_$alignment\"] ? $this->options['css'][\"class_align_$alignment\"] : $alignment);\n          } else {\n            $pre .= \" align=\\\"$alignment\\\"\";\n          }\n        }\n        if ($padleft) { $style .= \";padding-left:${padleft}em\"; }\n        if ($padright) { $style .= \";padding-right:${padright}em\"; }\n        if ($clear) { $style .= \";clear:${clear}\"; }\n        if ($class) { $class = preg_replace('/^ /', '', $class, 1); }\n        if ($class) { $pre .= \" class=\\\"$class\\\"\"; }\n        $pre .= ' id=\"' . ($this->options['css']['id_footnote_prefix'] ? $this->options['css']['id_footnote_prefix'] : 'fn') . $fnum . '\"';\n        if ($style) { $style = preg_replace('/^;/', '', $style, 1); }\n        if ($style) { $pre .= \" style=\\\"$style\\\"\"; }\n        if ($lang) { $pre .= \" lang=\\\"$lang\\\"\"; }\n        $pre .= '>';\n        $pre .= '<sup>' . $fnum . '</sup> ';\n        // we can close like a regular paragraph tag now\n        $block = 'p';\n        unset($clear);\n      } else {\n        $pre .= '<' . ($macros[$block] ? $macros[$block] : $block);\n        if ($align) {\n          $alignment = $this->_halign($align);\n          if ($this->options['css_mode']) {\n            if (($padleft || $padright) &&\n                (($alignment == 'left') || ($alignment == 'right'))) {\n              $style .= ';float:' . $alignment;\n            } else {\n              $style .= ';text-align:' . $alignment;\n            }\n            $class .= ' ' . ($this->options['css'][\"class_align_$alignment\"] ? $this->options['css'][\"class_align_$alignment\"] : $alignment);\n          } else {\n            $pre .= \" align=\\\"$alignment\\\"\";\n          }\n        }\n        if ($padleft) { $style .= \";padding-left:${padleft}em\"; }\n        if ($padright) { $style .= \";padding-right:${padright}em\"; }\n        if ($clear) { $style .= \";clear:${clear}\"; }\n        if ($class) { $class = preg_replace('/^ /', '', $class, 1); }\n        if ($class) { $pre .= \" class=\\\"$class\\\"\"; }\n        if ($id) { $pre .= \" id=\\\"$id\\\"\"; }\n        if ($style) { $style = preg_replace('/^;/', '', $style, 1); }\n        if ($style) { $pre .= \" style=\\\"$style\\\"\"; }\n        if ($lang) { $pre .= \" lang=\\\"$lang\\\"\"; }\n        if ($cite && ($block == 'bq')) { $pre .= ' cite=\"' . $this->format_url(array('url' => $cite)) . '\"'; }\n        $pre .= '>';\n        unset($clear);\n      }\n\n      $buffer = $this->format_paragraph(array('text' => $para));\n\n      if ($block == 'bq') {\n        if (!preg_match('/<p[ >]/', $buffer)) { $post .= '</p>'; }\n        if ($sticky == 0) {\n          $post .= '</blockquote>';\n        }\n      } else {\n        $post .= '</' . $block . '>';\n      }\n\n      if (preg_match('{' . $this->blocktags . '}x', $buffer)) {\n        $buffer = preg_replace('/^\\n\\n/s', '', $buffer, 1);\n        $out .= $buffer;\n      } else {\n        if ($filter) { $buffer = $this->format_block(array('text' => \"|$filter|\" . $buffer, 'inline' => 1)); }\n        $out .= $pre . $buffer . $post;\n      }\n    }\n\n    if ($sticky) {\n      if ($block == 'bc') {\n        // close our blockcode section\n        $out .= $this->options['_blockcode_close']; // . \"\\n\\n\";\n      } elseif ($block == 'bq') {\n        $out .= '</blockquote>'; // . \"\\n\\n\";\n      } elseif (($block == 'table') && $stickybuff) {\n        $table_out = $this->format_table(array('text' => $stickybuff));\n        if ($table_out) { $out .= $table_out; }\n      } elseif (($block == 'dl') && $stickybuff) {\n        $dl_out = $this->format_deflist(array('text' => $stickybuff));\n        if ($dl_out) { $out .= $dl_out; }\n      }\n    }\n\n    // cleanup-- restore preserved blocks\n    for ($i = count($this->repl[0]); $i > 0; $i--) {\n      $out = preg_replace('!(?:<|&lt;)textile#' . $i . '(?:>|&gt;)!', str_replace('$', '\\\\$', $this->repl[0][$i - 1]), $out, 1);\n    }\n    array_shift($this->repl);\n\n    // scan for br, hr tags that are not closed and close them\n    // only for xhtml! just the common ones -- don't fret over input\n    // and the like.\n    if (preg_match('/^xhtml/i', $this->flavor())) {\n      $out = preg_replace('/(<(?:img|br|hr)[^>]*?(?<!\\/))>/', '$1 />', $out);\n    }\n\n    return $out;\n  } // function process\n\n  /**\n   * Processes a single paragraph. The following attributes are\n   * allowed:\n   *\n   * <ul>\n   *\n   * <li><b>text</b>\n   *\n   * The text to be processed.</li>\n   *\n   * </ul>\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the paragraph.\n   *\n   * @return A @c string containing the formatted paragraph.\n   *\n   * @private\n   */\n  function format_paragraph($args) {\n    $buffer = (isset($args['text']) ? $args['text'] : '');\n\n    array_unshift($this->repl, array());\n    $buffer = preg_replace_callback('{(?:^|(?<=[\\s>])|([{[]))\n                                      ==(.+?)==\n                                      (?:$|([\\]}])|(?=' . $this->punct . '{1,2}|\\s))}sx',\n                                    $this->_cb('$me->_repl($me->repl[0], $me->format_block(array(\"text\" => $m[2], \"inline\" => 1, \"pre\" => $m[1], \"post\" => $m[3])))'), $buffer);\n\n    unset($tokens);\n    if (preg_match('/</', $buffer) && (!$this->disable_html())) {  // optimization -- no point in tokenizing if we\n                                       // have no tags to tokenize\n      $tokens = $this->_tokenize($buffer);\n    } else {\n      $tokens = array(array('text', $buffer));\n    }\n    $result = '';\n    foreach ($tokens as $token) {\n      $text = $token[1];\n      if ($token[0] == 'tag') {\n        $text = preg_replace('/&(?!amp;)/', '&amp;', $text);\n        $result .= $text;\n      } else {\n        $text = $this->format_inline(array('text' => $text));\n        $result .= $text;\n      }\n    }\n\n    // now, add line breaks for lines that contain plaintext\n    $lines = preg_split('/\\n/', $result);\n    $result = '';\n    $needs_closing = 0;\n    foreach ($lines as $line) {\n      if (!preg_match('{(' . $this->blocktags . ')}x', $line)\n          && ((preg_match('/^[^<]/', $line) || preg_match('/>[^<]/', $line))\n              || !preg_match('/<img /', $line))) {\n        if ($this->options['_line_open']) {\n          if ($result != '') { $result .= \"\\n\"; }\n          $result .= $this->options['_line_open'] . $line . $this->options['_line_close'];\n        } else {\n          if ($needs_closing) {\n            $result .= $this->options['_line_close'] . \"\\n\";\n          } else {\n            $needs_closing = 1;\n            if ($result != '') { $result .= \"\\n\"; }\n          }\n          $result .= $line;\n        }\n      } else {\n        if ($needs_closing) {\n          $result .= $this->options['_line_close'] . \"\\n\";\n        } else {\n          if ($result != '') { $result .= \"\\n\"; }\n        }\n        $result .= $line;\n        $needs_closing = 0;\n      }\n    }\n\n    // at this point, we will restore the \\001's to \\n's (reversing\n    // the step taken in _tokenize).\n    //$result = preg_replace('/\\r/', \"\\n\", $result);\n    $result = preg_replace('/\\001/', \"\\n\", $result);\n\n    for ($i = count($this->repl[0]); $i > 0; $i--) {\n      $result = preg_replace(\"|<textile#$i>|\", str_replace('$', '\\\\$', $this->repl[0][$i - 1]), $result, 1);\n    }\n    array_shift($this->repl);\n\n    // quotalize\n    if ($this->options['do_quotes']) {\n      $result = $this->process_quotes($result);\n    }\n\n    return $result;\n  } // function format_paragraph\n\n  /**\n   * Processes an inline string (plaintext) for Textile syntax.\n   * The following attributes are allowed:\n   *\n   * <ul>\n   *\n   * <li><b>text</b>\n   *\n   * The text to be processed.</li>\n   *\n   * </ul>\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the inline string.\n   *\n   * @return A @c string containing the formatted inline string.\n   *\n   * @private\n   */\n  function format_inline($args) {\n    $qtags = array(array('**', 'b',      '(?<!\\*)\\*\\*(?!\\*)', '\\*'),\n                   array('__', 'i',      '(?<!_)__(?!_)', '_'),\n                   array('??', 'cite',   '\\?\\?(?!\\?)', '\\?'),\n                   array('*',  'strong', '(?<!\\*)\\*(?!\\*)', '\\*'),\n                   array('_',  'em',     '(?<!_)_(?!_)', '_'),\n                   array('-',  'del',    '(?<!\\-)\\-(?!\\-)', '-'),\n                   array('+',  'ins',    '(?<!\\+)\\+(?!\\+)', '\\+'),\n                   array('++', 'big',    '(?<!\\+)\\+\\+(?!\\+)', '\\+\\+'),\n                   array('--', 'small',  '(?<!\\-)\\-\\-(?!\\-)', '\\-\\-'),\n                   array('~',  'sub',    '(?<!\\~)\\~(?![\\\\\\\\/~])', '\\~'));\n    $text = (isset($args['text']) ? $args['text'] : '');\n\n    array_unshift($this->repl, array());\n\n    $text = preg_replace_callback('{' . $this->codere . '}mx', $this->_cb('$me->_repl($me->repl[0], $me->format_code(array(\"text\" => $m[2] . $m[4], \"lang\" => $m[1] . $m[3])))'), $text);\n\n    // images must be processed before encoding the text since they might\n    // have the <, > alignment specifiers...\n\n    // !blah (alt)! -> image\n    $text = preg_replace_callback('{(?:^|(?<=[\\s>])|([{[]))      # $1: open brace/bracket\n                                    !                            # opening\n                                    (' . $this->imgalignre . '?) # $2: optional alignment\n                                    (' . $this->clstypadre . '*) # $3: optional CSS class/id\n                                    (' . $this->imgalignre . '?) # $4: optional alignment\n                                    (?:\\s*)                      # space between alignment/css stuff\n                                    ([^\\s\\(!]+)                  # $5: filename\n                                    (\\s*[^\\(!]*(?:\\([^\\)]+\\))?[^!]*) # $6: extras (alt text)\n                                    !                            # closing\n                                    (?::(\\d+|' . $this->urlre . '))? # $7: optional URL\n                                    (?:$|([\\]}])|(?=' . $this->punct . '{1,2}|\\s)) # $8: closing brace/bracket\n                                   }mx', $this->_cb('$me->_repl($me->repl[0], $me->format_image(array(\"pre\" => $m[1], \"src\" => $m[5], \"align\" => ($m[2] ? $m[2] : $m[4]), \"extra\" => $m[6], \"url\" => $m[7], \"clsty\" => $m[3], \"post\" => $m[8])))'), $text);\n\n    $text = preg_replace_callback('{(?:^|(?<=[\\s>])|([{[]))     # $1: open brace/bracket\n                                    %                           # opening\n                                    (' . $this->halignre . '?)  # $2: optional alignment\n                                    (' . $this->clstyre . '*)   # $3: optional CSS class/id\n                                    (' . $this->halignre . '?)  # $4: optional alignment\n                                    (?:\\s*)                     # spacing\n                                    ([^%]+?)                    # $5: text\n                                    %                           # closing\n                                    (?::(\\d+|' . $this->urlre . '))? # $6: optional URL\n                                    (?:$|([]}])|(?=' . $this->punct . '{1,2}|\\s)) # $7: closing brace/bracket\n                                   }mx', $this->_cb('$me->_repl($me->repl[0], $me->format_span(array(\"pre\" => $m[1], \"text\" => $m[5], \"align\" => ($m[2] ? $m[2] : $m[4]), \"cite\" => $m[6], \"clsty\" => $m[3], \"post\" => $m[7])))'), $text);\n\n    $text = $this->encode_html($text);\n    $text = preg_replace('!&lt;textile#(\\d+)&gt;!', '<textile#$1>', $text);\n    $text = preg_replace('!&amp;quot;!', '&#34;', $text);\n    $text = preg_replace('!&amp;(([a-z]+|#\\d+);)!', '&$1', $text);\n    $text = preg_replace('!&quot;!', '\"', $text);\n\n    // These create markup with entities. Do first and 'save' result for later:\n    // \"text\":url -> hyperlink\n    // links with brackets surrounding\n    $parenre = '\\( (?: [^()] )* \\)';\n    $text = preg_replace_callback('{(\n                                    [{[]\n                                    (?:\n                                        (?:\"                                         # quote character\n                                           (' . $this->clstyre . '*)?                # $2: optional CSS class/id\n                                           ([^\"]+?)                                  # $3: link text\n                                           (?:\\( ( (?:[^()]|' . $parenre . ')*) \\))? # $4: optional link title\n                                           \"                                         # closing quote\n                                        )\n                                        |\n                                        (?:\\'                                        # open single quote\n                                           (' . $this->clstyre . '*)?                # $5: optional CSS class/id\n                                           ([^\\']+?)                                 # $6: link text\n                                           (?:\\( ( (?:[^()]|' . $parenre . ')*) \\))? # $7: optional link title\n                                           \\'                                        # closing quote\n                                        )\n                                    )\n                                    :(.+?)                                           # $8: URL suffix\n                                    [\\]}]\n                                   )\n                                   }mx', $this->_cb('$me->_repl($me->repl[0], $me->format_link(array(\"text\" => $m[1], \"linktext\" => $m[3] . $m[6], \"title\" => $me->encode_html_basic($m[4] . $m[7]), \"url\" => $m[8], \"clsty\" => $m[2] . $m[5])))'), $text);\n\n    $text = preg_replace_callback('{((?:^|(?<=[\\s>\\(]))                              # $1: open brace/bracket\n                                    (?: (?:\"                                         # quote character \"\n                                           (' . $this->clstyre . '*)?                # $2: optional CSS class/id\n                                           ([^\"]+?)                                  # $3: link text \"\n                                           (?:\\( ( (?:[^()]|' . $parenre . ')*) \\))? # $4: optional link title\n                                           \"                                         # closing quote # \"\n                                        )\n                                        |\n                                        (?:\\'                                        # open single quote \\'\n                                           (' . $this->clstyre . '*)?                # $5: optional CSS class/id\n                                           ([^\\']+?)                                 # $6: link text \\'\n                                           (?:\\( ( (?:[^()]|' . $parenre . ')*) \\))? # $7: optional link title\n                                           \\'                                        # closing quote \\'\n                                        )\n                                    )\n                                    :(\\d+|' . $this->urlre . ')                      # $8: URL suffix\n                                    (?:$|(?=' . $this->punct . '{1,2}|\\s)))          # $9: closing brace/bracket\n                                   }mx', $this->_cb('$me->_repl($me->repl[0], $me->format_link(array(\"text\" => $m[1], \"linktext\" => $m[3] . $m[6], \"title\" => $me->encode_html_basic($m[4] . $m[7]), \"url\" => $m[8], \"clsty\" => $m[2] . $m[5])))'), $text);\n\n    if (preg_match('/^xhtml2/', $this->flavor())) {\n      // citation with cite link\n      $text = preg_replace_callback('{(?:^|(?<=[\\s>\\'\"\\(])|([{[]))                   # $1: open brace/bracket \\'\n                                      \\?\\?                                           # opening \\'??\\'\n                                      ([^\\?]+?)                                      # $2: characters (can\\'t contain \\'?\\')\n                                      \\?\\?                                           # closing \\'??\\'\n                                      :(\\d+|' . $this->urlre . ')                    # $3: optional citation URL\n                                      (?:$|([\\]}])|(?=' . $this->punct . '{1,2}|\\s)) # $4: closing brace/bracket\n                                     }mx', $this->_cb('$me->_repl($me->repl[0], $me->format_cite(array(\"pre\" => $m[1], \"text\" => $m[2], \"cite\" => $m[3], \"post\" => $m[4])))'), $text);\n    }\n\n    // footnotes\n    if (preg_match('/[^ ]\\[\\d+\\]/', $text)) {\n      $fntag = '<sup';\n      if ($this->options['css']['class_footnote']) { $fntag .= ' class=\"' . $this->options['css']['class_footnote'] . '\"'; }\n      $fntag .= '><a href=\"#' . ($this->options['css']['id_footnote_prefix'] ? $this->options['css']['id_footnote_prefix'] : 'fn');\n      $text = preg_replace('|([^ ])\\[(\\d+)\\]|', '$1' . $fntag . '$2\">$2</a></sup>', $text);\n    }\n\n    // translate macros:\n    $text = preg_replace_callback('{(\\{)(.+?)(\\})}x',\n                                  $this->_cb('$me->format_macro(array(\"pre\" => $m[1], \"post\" => $m[3], \"macro\" => $m[2]))'), $text);\n\n    // these were present with textile 1 and are common enough\n    // to not require macro braces...\n    // (tm) -> &trade;\n    $text = preg_replace('|[\\(\\[]TM[\\)\\]]|i', '&#8482;', $text);\n    // (c) -> &copy;\n    $text = preg_replace('|[\\(\\[]C[\\)\\]]|i', '&#169;', $text);\n    // (r) -> &reg;\n    $text = preg_replace('|[\\(\\[]R[\\)\\]]|i', '&#174;', $text);\n\n    if ($this->preserve_spaces()) {\n      // replace two spaces with an em space\n      $text = preg_replace('/(?<!\\s)\\ \\ (?!=\\s)/', '&#8195;', $text);\n    }\n\n    $redo = preg_match('/[\\*_\\?\\-\\+\\^\\~]/', $text);\n    $last = $text;\n    while ($redo) {\n      // simple replacements...\n      $redo = 0;\n      foreach ($qtags as $tag) {\n        list ($this->tmp['f'][], $this->tmp['r'][], $qf, $cls) = $tag;\n        if ($last != ($text = preg_replace_callback('{(?:^|(?<=[\\s>\\'\"])|([{[]))                     # \"\\' $1 - pre\n                                                      ' . $qf . '                                    #\n                                                      (?:(' . $this->clstyre . '*))?                 # $2 - attributes\n                                                      ([^' . $cls . '\\s].*?)                         # $3 - content\n                                                      (?<=\\S)' . $qf . '                             #\n                                                      (?:$|([\\]}])|(?=' . $this->punct . '{1,2}|\\s)) # $4 - post\n                                                     }mx', $this->_cb('$me->format_tag(array(\"tag\" => end($me->tmp[\"r\"]), \"marker\" => end($me->tmp[\"f\"]), \"pre\" => $m[1], \"text\" => $m[3], \"clsty\" => $m[2], \"post\" => $m[4]))'), $text))) {\n          $redo = ($redo || ($last != $text));\n          $last = $text;\n        }\n        array_pop($this->tmp['f']); array_pop($this->tmp['r']);\n      }\n    }\n\n    // superscript is an even simpler replacement...\n    $text = preg_replace('/(?<!\\^)\\^(?!\\^)(.+?)(?<!\\^)\\^(?!\\^)/', '<sup>$1</sup>', $text);\n\n    // ABC(Aye Bee Cee) -> acronym\n    $text = preg_replace_callback('{\\b([A-Z][A-Za-z0-9]*?[A-Z0-9]+?)\\b(?:[(]([^)]*)[)])}',\n                                  $this->_cb('$me->_repl($me->repl[0],\"<acronym title=\\\"\" . $me->encode_html_basic($m[2]) . \"\\\">$m[1]</acronym>\")'), $text);\n\n    // ABC -> 'capped' span\n    if ($this->tmp['caps'][] = $this->options['css']['class_caps']) {\n      $text = preg_replace_callback('/(^|[^\"][>\\s])  # \"\n                                      ((?:[A-Z](?:[A-Z0-9\\.,\\']|\\&amp;){2,}\\ *)+?) # \\'\n                                      (?=[^A-Z\\.0-9]|$)\n                                     /mx', $this->_cb('$m[1] . $me->_repl($me->repl[0], \"<span class=\\\"\" . end($me->tmp[\"caps\"]) . \"\\\">$m[2]</span>\")'), $text);\n    }\n    array_pop($this->tmp['caps']);\n\n    // nxn -> n&times;n\n    $text = preg_replace('!((?:[0-9\\.]0|[1-9]|\\d[\\'\"])\\ ?)x(\\ ?\\d)!', '$1&#215;$2', $text);\n\n    // translate these entities to the Unicode equivalents:\n    $text = preg_replace('/&#133;/', '&#8230;', $text);\n    $text = preg_replace('/&#145;/', '&#8216;', $text);\n    $text = preg_replace('/&#146;/', '&#8217;', $text);\n    $text = preg_replace('/&#147;/', '&#8220;', $text);\n    $text = preg_replace('/&#148;/', '&#8221;', $text);\n    $text = preg_replace('/&#150;/', '&#8211;', $text);\n    $text = preg_replace('/&#151;/', '&#8212;', $text);\n\n    // Restore replacements done earlier:\n    for ($i = count($this->repl[0]); $i > 0; $i--) {\n      $text = preg_replace(\"|<textile#$i>|\", str_replace('$', '\\\\$', $this->repl[0][$i - 1]), $text);\n    }\n    array_shift($this->repl);\n\n    // translate entities to characters for highbit stuff since\n    // we're using utf8\n    // removed for backward compatability with older versions of Perl\n    //if (preg_match('/^utf-?8$/i', $this->options['charset'])) {\n    //    // translate any unicode entities to native UTF-8\n    //    $text = preg_replace('/\\&\\#(\\d+);/e', '($1 > 127) ? pack('U', $1) : chr($1)', $text);\n    //}\n\n    return $text;\n  } // function format_inline\n\n  /**\n   * Responsible for processing a particular macro. Arguments passed\n   * include:\n   *\n   * <ul>\n   *\n   * <li><b>pre</b>\n   *\n   * open brace character</li>\n   *\n   * <li><b>post</b>\n   *\n   * close brace character</li>\n   *\n   * <li><b>macro</b>\n   *\n   * the macro to be executed</li>\n   *\n   * </ul>\n   *\n   * The return value from this method would be the replacement\n   * text for the macro given. If the macro is not defined, it will\n   * return pre + macro + post, thereby preserving the original\n   * macro string.\n   *\n   * @param $attrs An @c array containing the attributes for\n   *        formatting the macro.\n   *\n   * @return A @c string containing the formatted macro.\n   *\n   * @private\n   */\n  function format_macro($attrs) {\n    $macro = $attrs['macro'];\n    if ($this->options['macros'][$macro]) {\n      return $this->options['macros'][$macro];\n    }\n\n    return $attrs['pre'] . $macro . $attrs['post'];\n  } // function format_macro\n\n  /**\n   * Processes text for a citation tag. The following attributes\n   * are allowed:\n   *\n   * <ul>\n   *\n   * <li><b>pre</b>\n   *\n   * Any text that comes before the citation.</li>\n   *\n   * <li><b>text</b>\n   *\n   * The text that is being cited.</li>\n   *\n   * <li><b>cite</b>\n   *\n   * The URL of the citation.</li>\n   *\n   * <li><b>post</b>\n   *\n   * Any text that follows the citation.</li>\n   *\n   * </ul>\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the citation.\n   *\n   * @return A @c string containing the formatted citation.\n   *\n   * @private\n   */\n  function format_cite($args) {\n    $pre = (isset($args['pre']) ? $args['pre'] : '');\n    $text = (isset($args['text']) ? $args['text'] : '');\n    $cite = $args['cite'];\n    $post = (isset($args['post']) ? $args['post'] : '');\n    $this->_strip_borders($pre, $post);\n    $tag = $pre . '<cite';\n    if (preg_match('/^xhtml2/', $this->flavor()) && $cite) {\n      $cite = $this->format_url(array('url' => $cite));\n      $tag .= \" cite=\\\"$cite\\\"\";\n    } else {\n      $post .= ':';\n    }\n    $tag .= '>';\n    return $tag . $this->format_inline(array('text' => $text)) . '</cite>' . $post;\n  } // function format_cite\n\n  /**\n   * Processes '@...@' type blocks (code snippets). The following\n   * attributes are allowed:\n   *\n   * <ul>\n   *\n   * <li><b>text</b>\n   *\n   * The text of the code itself.</li>\n   *\n   * <li><b>lang</b>\n   *\n   * The language (programming language) for the code.</li>\n   *\n   * </ul>\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the code.\n   *\n   * @return A @c string containing the formatted code.\n   *\n   * @private\n   */\n  function format_code($args) {\n    $code = (isset($args['text']) ? $args['text'] : '');\n    $lang = $args['lang'];\n    $code = $this->encode_html($code, 1);\n    $code = preg_replace('/&lt;textile#(\\d+)&gt;/', '<textile#$1>', $code);\n    $tag = '<code';\n    if ($lang) { $tag .= \" language=\\\"$lang\\\"\"; }\n    return $tag . '>' . $code . '</code>';\n  } // function format_code\n\n  /**\n   * Returns a string of tag attributes to accomodate the class,\n   * style and symbols present in @c $clsty.\n   *\n   * @c $clsty is checked for:\n   *\n   * <ul>\n   *\n   * <li><b><code>{...}</code></b>\n   *\n   * style rules. If present, they are appended to <code>$style</code>.</li>\n   *\n   * <li><b><code>(...#...)</code></b>\n   *\n   * class and/or ID name declaration</li>\n   *\n   * <li><b><code>(</code> (one or more)</b>\n   *\n   * pad left characters</li>\n   *\n   * <li><b><code>)</code> (one or more)</b>\n   *\n   * pad right characters</li>\n   *\n   * <li><b><code>[ll]</code></b>\n   *\n   * language declaration</li>\n   *\n   * </ul>\n   *\n   * The attribute string returned will contain any combination\n   * of class, id, style and/or lang attributes.\n   *\n   * @param $clsty A @c string specifying the class/style to process.\n   * @param $class A @c string specifying the predetermined class.\n   * @param $style A @c string specifying the predetermined style.\n   *\n   * @return A @c string containing the formatted class, ID, style,\n   *         and/or language.\n   *\n   * @private\n   */\n  function format_classstyle($clsty = NULL, $class = NULL, $style = NULL) {\n    $class = preg_replace('/^ /', '', $class, 1);\n\n    unset($lang, $padleft, $padright, $id);\n    if ($clsty && preg_match('/{([^}]+)}/', $clsty, $matches)) {\n      $_style = $matches[1];\n      $_style = preg_replace('/\\n/', ' ', $_style);\n      $style .= ';' . $_style;\n      $clsty = preg_replace('/{[^}]+}/', '', $clsty);\n    }\n    if ($clsty && (preg_match('/\\(([A-Za-z0-9_\\- ]+?)(?:#(.+?))?\\)/', $clsty, $matches) ||\n                   preg_match('/\\(([A-Za-z0-9_\\- ]+?)?(?:#(.+?))\\)/', $clsty, $matches))) {\n      if ($matches[1] || $matches[2]) {\n        if ($class) {\n          $class = $matches[1] . ' ' . $class;\n        } else {\n          $class = $matches[1];\n        }\n        $id = $matches[2];\n        if ($class) {\n          $clsty = preg_replace('/\\([A-Za-z0-9_\\- ]+?(#.*?)?\\)/', '', $clsty);\n        }\n        if ($id) {\n          $clsty = preg_replace('/\\(#.+?\\)/', '', $clsty);\n        }\n      }\n    }\n    if ($clsty && preg_match('/(\\(+)/', $clsty, $matches)) {\n      $padleft = strlen($matches[1]);\n      $clsty = preg_replace('/\\(+/', '', $clsty, 1);\n    }\n    if ($clsty && preg_match('/(\\)+)/', $clsty, $matches)) {\n      $padright = strlen($matches[1]);\n      $clsty = preg_replace('/\\)+/', '', $clsty, 1);\n    }\n    if ($clsty && preg_match('/\\[(.+?)\\]/', $clsty, $matches)) {\n      $lang = $matches[1];\n      $clsty = preg_replace('/\\[.+?\\]/', '', $clsty);\n    }\n    $attrs = '';\n    if ($padleft) { $style .= \";padding-left:${padleft}em\"; }\n    if ($padright) { $style .= \";padding-right:${padright}em\"; }\n    $style = preg_replace('/^;/', '', $style, 1);\n    $class = preg_replace('/^ /', '', $class, 1);\n    $class = preg_replace('/ $/', '', $class, 1);\n    if ($class) { $attrs .= \" class=\\\"$class\\\"\"; }\n    if ($id) { $attrs .= \" id=\\\"$id\\\"\"; }\n    if ($style) { $attrs .= \" style=\\\"$style\\\"\"; }\n    if ($lang) { $attrs .= \" lang=\\\"$lang\\\"\"; }\n    $attrs = preg_replace('/^ /', '', $attrs, 1);\n    return $attrs;\n  } // function format_classstyle\n\n  /**\n   * Constructs an HTML tag. Accepted arguments:\n   *\n   * <ul>\n   *\n   * <li><b>tag</b>\n   *\n   * the tag to produce</li>\n   *\n   * <li><b>text</b>\n   *\n   * the text to output inside the tag</li>\n   *\n   * <li><b>pre</b>\n   *\n   * text to produce before the tag</li>\n   *\n   * <li><b>post</b>\n   *\n   * text to produce following the tag</li>\n   *\n   * <li><b>clsty</b>\n   *\n   * class and/or style attributes that should be assigned to the tag.</li>\n   *\n   * </ul>\n   *\n   * @param $args @c array specifying the attributes for formatting\n   *        the tag.\n   *\n   * @return A @c string containing the formatted tag.\n   *\n   * @private\n   */\n  function format_tag($args) {\n    $tagname = $args['tag'];\n    $text = (isset($args['text']) ? $args['text'] : '');\n    $pre = (isset($args['pre']) ? $args['pre'] : '');\n    $post = (isset($args['post']) ? $args['post'] : '');\n    $clsty = (isset($args['clsty']) ? $args['clsty'] : '');\n    $this->_strip_borders($pre, $post);\n    $tag = \"<$tagname\";\n    $attr = $this->format_classstyle($clsty);\n    if ($attr) { $tag .= \" $attr\"; }\n    $tag .= \">$text</$tagname>\";\n    return $pre . $tag . $post;\n  } // function format_tag\n\n  /**\n   * Takes a Textile formatted definition list and\n   * returns the markup for it. Arguments accepted:\n   *\n   * <ul>\n   *\n   * <li><b>text</b>\n   *\n   * The text to be processed.</li>\n   *\n   * </ul>\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the definition list.\n   *\n   * @return A @c string containing the formatted definition list.\n   *\n   * @private\n   */\n  function format_deflist($args) {\n    $str = (isset($args['text']) ? $args['text'] : '');\n    unset($clsty);\n    $lines = preg_split('/\\n/', $str);\n    if (preg_match('{^(dl(' . $this->clstyre . '*?)\\.\\.?(?:\\ +|$))}x', $lines[0], $matches)) {\n      $clsty = $matches[2];\n      $lines[0] = substr($lines[0], strlen($matches[1]));\n    }\n\n    unset($dt, $dd);\n    $out = '';\n    foreach ($lines as $line) {\n      if (preg_match('{^((?:' . $this->clstyre . '*)(?:[^\\ ].*?)(?<![\"\\'\\ ])):([^\\ \\/].*)$}x', $line, $matches)) {\n        if ($dt && $dd) { $out .= $this->add_term($dt, $dd); }\n        $dt = $matches[1];\n        $dd = $matches[2];\n      } else {\n        $dd .= \"\\n\" . $line;\n      }\n    }\n    if ($dt && $dd) { $out .= $this->add_term($dt, $dd); }\n\n    $tag = '<dl';\n    if ($clsty) { $attr = $this->format_classstyle($clsty); }\n    if ($attr) { $tag .= \" $attr\"; }\n    $tag .= '>' . \"\\n\";\n\n    return $tag . $out . \"</dl>\\n\";\n  } // function format_deflist\n\n  /**\n   * Processes a single definition list item from the provided term\n   * and definition.\n   *\n   * @param $dt A @c string specifying the term to be defined.\n   * @param $dd A @c string specifying the definition for the term.\n   *\n   * @return A @c string containing the formatted definition list\n   *         item.\n   *\n   * @private\n   */\n  function add_term($dt, $dd) {\n    unset($dtattr, $ddattr);\n    unset($dtlang);\n    if (preg_match('{^(' . $this->clstyre . '*)}x', $dt, $matches)) {\n      $param = $matches[1];\n      $dtattr = $this->format_classstyle($param);\n      if (preg_match('/\\[([A-Za-z]+?)\\]/', $param, $matches)) {\n        $dtlang = $matches[1];\n      }\n      $dt = substr($dt, strlen($param));\n    }\n    if (preg_match('{^(' . $this->clstyre . '*)}x', $dd, $matches)) {\n      $param = $matches[1];\n      // if the language was specified for the term,\n      // then apply it to the definition as well (unless\n      // already specified of course)\n      if ($dtlang && preg_match('/\\[([A-Za-z]+?)\\]/', $param)) {\n        unset($dtlang);\n      }\n      $ddattr = $this->format_classstyle(($dtlang ? \"[$dtlang]\" : '') . $param);\n      $dd = substr($dd, strlen($param));\n    }\n    $out = '<dt';\n    if ($dtattr) { $out .= \" $dtattr\"; }\n    $out .= '>' . $this->format_inline(array('text' => $dt)) . '</dt>' . \"\\n\";\n    if (preg_match('/\\n\\n/', $dd)) {\n      if (preg_match('/\\n\\n/', $dd)) { $dd = $this->process($dd); }\n    } else {\n      $dd = $this->format_paragraph(array('text' => $dd));\n    }\n    $out .= '<dd';\n    if ($ddattr) { $out .= \" $ddattr\"; }\n    $out .= '>' . $dd . '</dd>' . \"\\n\";\n    return $out;\n  } // function add_term\n\n  /**\n   * Takes a Textile formatted list (numeric or bulleted) and\n   * returns the markup for it. Text that is passed in requires\n   * substantial parsing, so the @c format_list method is a little\n   * involved. But it should always produce a proper ordered\n   * or unordered list. If it cannot (due to misbalanced input),\n   * it will return the original text. Arguments accepted:\n   *\n   * <ul>\n   *\n   * <li><b>text</b>\n   *\n   * The text to be processed.</li>\n   *\n   * </ul>\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the list.\n   *\n   * @return A @c string containing the formatted list.\n   *\n   * @private\n   */\n  function format_list($args) {\n    $str = (isset($args['text']) ? $args['text'] : '');\n\n    $list_tags = array('*' => 'ul', '#' => 'ol');\n\n    $lines = preg_split('/\\n/', $str);\n\n    unset($stack);\n    $last_depth = 0;\n    $item = '';\n    $out = '';\n    foreach ($lines as $line) {\n      if (preg_match('{^((?:' . $this->clstypadre . '*|' . $this->halignre . ')*)\n                       ([\\#\\*]+)\n                       ((?:' . $this->halignre . '|' . $this->clstypadre . '*)*)\n                       \\ (.+)$}x', $line, $matches)) {\n        if ($item != '') {\n          if (preg_match('/\\n/', $item)) {\n            if ($this->options['_line_open']) {\n              $item = preg_replace('/(<li[^>]*>|^)/m', '$1' . $this->options['_line_open'], $item);\n              $item = preg_replace('/(\\n|$)/s', $this->options['_line_close'] . '$1', $item);\n            } else {\n              $item = preg_replace('/(\\n)/s', $this->options['_line_close'] . '$1', $item);\n            }\n          }\n          $out .= $item;\n          $item = '';\n        }\n        $type = substr($matches[2], 0, 1);\n        $depth = strlen($matches[2]);\n        $blockparam = $matches[1];\n        $itemparam = $matches[3];\n        $line = $matches[4];\n        unset ($blockclsty, $blockalign, $blockattr, $itemattr, $itemclsty,\n               $itemalign);\n        if (preg_match('{(' . $this->clstypadre . '+)}x', $blockparam, $matches)) {\n          $blockclsty = $matches[1];\n        }\n        if (preg_match('{(' . $this->halignre . '+)}', $blockparam, $matches)) {\n          $blockalign = $matches[1];\n        }\n        if (preg_match('{(' . $this->clstypadre . '+)}x', $itemparam, $matches)) {\n          $itemclsty = $matches[1];\n        }\n        if (preg_match('{(' . $this->halignre . '+)}', $itemparam, $matches)) {\n          $itemalign = $matches[1];\n        }\n        if ($itemclsty) { $itemattr = $this->format_classstyle($itemclsty); }\n        if ($depth > $last_depth) {\n          for ($j = $last_depth; $j < $depth; $j++) {\n            $out .= \"\\n<$list_tags[$type]\";\n            $stack[] = $type;\n            if ($blockclsty) {\n              $blockattr = $this->format_classstyle($blockclsty);\n              if ($blockattr) { $out .= ' ' . $blockattr; }\n            }\n            $out .= \">\\n<li\";\n            if ($itemattr) { $out .= \" $itemattr\"; }\n            $out .= \">\";\n          }\n        } elseif ($depth < $last_depth) {\n          for ($j = $depth; $j < $last_depth; $j++) {\n            if ($j == $depth) { $out .= \"</li>\\n\"; }\n            $type = array_pop($stack);\n            $out .= \"</$list_tags[$type]>\\n</li>\\n\";\n          }\n          if ($depth) {\n            $out .= '<li';\n            if ($itemattr) { $out .= \" $itemattr\"; }\n            $out .= '>';\n          }\n        } else {\n          $out .= \"</li>\\n<li\";\n          if ($itemattr) { $out .= \" $itemattr\"; }\n          $out .= '>';\n        }\n        $last_depth = $depth;\n      }\n      if ($item != '') { $item .= \"\\n\"; }\n      $item .= $this->format_paragraph(array('text' => $line));\n    }\n\n    if (preg_match('/\\n/', $item, $matches)) {\n      if ($this->options['_line_open']) {\n        $item = preg_replace('/(<li[^>]*>|^)/m', '$1' . $this->options['_line_open'], $item);\n        $item = preg_replace('/(\\n|$)/s', $this->options['_line_close'] . '$1', $item);\n      } else {\n        $item = preg_replace('/(\\n)/s', $this->options['_line_close'] . '$1', $item);\n      }\n    }\n    $out .= $item;\n\n    for ($j = 1; $j <= $last_depth; $j++) {\n      if ($j == 1) { $out .= '</li>'; }\n      $type = array_pop($stack);\n      $out .= \"\\n\" . '</' . $list_tags[$type] . '>' . \"\\n\";\n      if ($j != $last_depth) { $out .= '</li>'; }\n    }\n\n    return $out . \"\\n\";\n  } // function format_list\n\n  /**\n   * Processes '==xxxxx==' type blocks for filters. A filter\n   * would follow the open '==' sequence and is specified within\n   * pipe characters, like so:\n   * <pre>\n   *     ==|filter|text to be filtered==\n   * </pre>\n   * You may specify multiple filters in the filter portion of\n   * the string. Simply comma delimit the filters you desire\n   * to execute. Filters are defined using the filters method.\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the block.\n   *\n   * @return A @c string containing the formatted block.\n   *\n   * @private\n   */\n  function format_block($args) {\n    $str = (isset($args['text']) ? $args['text'] : '');\n    $inline = $args['inline'];\n    $pre = (isset($args['pre']) ? $args['pre'] : '');\n    $post = (isset($args['post']) ? $args['post'] : '');\n    $this->_strip_borders($pre, $post);\n    $filters = (preg_match('/^(\\|(?:(?:[a-z0-9_\\-]+)\\|)+)/', $str, $matches) ? $matches[1] : '');\n    if ($filters) {\n      $filtreg = preg_replace('/[^A-Za-z0-9]/', '\\\\\\\\$1', $filters);\n      $str = preg_replace('/^' . $filtreg . '/', '', $str, 1);\n      $filters = preg_replace('/^\\|/', '', $filters, 1);\n      $filters = preg_replace('/\\|$/', '', $filter, 1);\n      $filters = preg_split('/\\|/', $filters);\n      $str = $this->apply_filters(array('text' => $str, 'filters' => $filters));\n      $count = count($filters);\n      if ($str = preg_replace('!(<p>){' . $count . '}!se', '(++$i ? \"$1\" : \"$1\")', $str) && $i) {\n        $str = preg_replace('!(</p>){' . $count . '}!s', '$1', $str);\n        $str = preg_replace('!(<br( /)?>){' . $count . '}!s', '$1', $str);\n      }\n    }\n    if ($inline) {\n      // strip off opening para, closing para, since we're\n      // operating within an inline block\n      $str = preg_replace('/^\\s*<p[^>]*>/', '', $str, 1);\n      $str = preg_replace('/<\\/p>\\s*$/', '', $str, 1);\n    }\n    return $pre . $str . $post;\n  } // function format_block\n\n  /**\n   * Takes the Textile link attributes and transforms them into\n   * a hyperlink.\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the link.\n   *\n   * @return A @c string containing the formatted link.\n   *\n   * @private\n   */\n  function format_link($args) {\n    $text = (isset($args['text']) ? $args['text'] : '');\n    $linktext = (isset($args['linktext']) ? $args['linktext'] : '');\n    $title = $args['title'];\n    $url = $args['url'];\n    $clsty = $args['clsty'];\n\n    if (!$url || ($url == '')) {\n      return $text;\n    }\n    if (isset($this->links) && isset($this->links[$url])) {\n      $title = ($title ? $title : $this->links[$url]['title']);\n      $url = $this->links[$url]['url'];\n    }\n    $linktext = preg_replace('/ +$/', '', $linktext, 1);\n    $linktext = $this->format_paragraph(array('text' => $linktext));\n    $url = $this->format_url(array('linktext' => $linktext, 'url' => $url));\n    $tag = \"<a href=\\\"$url\\\"\";\n    $attr = $this->format_classstyle($clsty);\n    if ($attr) { $tag .= \" $attr\"; }\n    if ($title) {\n      $title = preg_replace('/^\\s+/', '', $title, 1);\n      if (strlen($title)) { $tag .= \" title=\\\"$title\\\"\"; }\n    }\n    $tag .= \">$linktext</a>\";\n    return $tag;\n  } // function format_link\n\n  /**\n   * Takes the given @c $url and transforms it appropriately.\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the url.\n   *\n   * @return A @c string containing the formatted url.\n   *\n   * @private\n   */\n  function format_url($args) {\n    $url = ($args['url'] ? $args['url'] : '');\n    if (preg_match('/^(mailto:)?([-\\+\\w]+@[-\\w]+(\\.\\w[-\\w]*)+)$/', $url, $matches)) {\n      $url = 'mailto:' . $this->mail_encode($matches[2]);\n    }\n    if (!preg_match('!^(/|\\./|\\.\\./|#)!', $url)) {\n      if (!preg_match('!^(https?|ftp|mailto|nntp|telnet)!', $url)) { $url = \"http://$url\"; }\n    }\n    $url = preg_replace('/&(?!amp;)/', '&amp;', $url);\n    $url = preg_replace('/\\ /', '+', $url);\n    $url = preg_replace_callback('/^((?:.+?)\\?)(.+)$/', $this->_cb('$m[1] . $me->encode_url($m[2])'), $url);\n    return $url;\n  } // function format_url\n\n  /**\n   * Takes a Textile formatted span and returns the markup for it.\n   *\n   * @return A @c string containing the formatted span.\n   *\n   * @private\n   */\n  function format_span($args) {\n    $text = (isset($args['text']) ? $args['text'] : '');\n    $pre = (isset($args['pre']) ? $args['pre'] : '');\n    $post = (isset($args['post']) ? $args['post'] : '');\n    $align = $args['align'];\n    $cite = (isset($args['cite']) ? $args['cite'] : '');\n    $clsty = $args['clsty'];\n    $this->_strip_borders($pre, $post);\n    unset($class, $style);\n    $tag  = \"<span\";\n    $style = '';\n    if ($align) {\n      if ($self->options['css_mode']) {\n        $alignment = $this->_halign($align);\n        if ($alignment) { $style .= \";float:$alignment\"; }\n        if ($alignment) { $class .= ' ' . $this->options['css'][\"class_align_$alignment\"]; }\n      } else {\n        $alignment = ($this->_halign($align) ? $this->_halign($align) : $this->_valign($align));\n        if ($alignment) { $tag .= \" align=\\\"$alignment\\\"\"; }\n      }\n    }\n    $attr = $this->format_classstyle($clsty, $class, $style);\n    if ($attr) { $tag .= \" $attr\"; }\n    if ($cite) {\n      $cite = preg_replace('/^:/', '', $cite, 1);\n      $cite = $this->format_url(array('url' => $cite));\n      $tag .= \" cite=\\\"$cite\\\"\";\n    }\n    return $pre . $tag . '>' . $this->format_paragraph(array('text' => $text)) . '</span>' . $post;\n  } // function format_span\n\n  /**\n   * Returns markup for the given image. @c $src is the location of\n   * the image, @c $extra contains the optional height/width and/or\n   * alt text. @c $url is an optional hyperlink for the image. @c $class\n   * holds the optional CSS class attribute.\n   *\n   * Arguments you may pass:\n   *\n   * <ul>\n   *\n   * <li><b>src</b>\n   *\n   * The 'src' (URL) for the image. This may be a local path,\n   * ideally starting with a '/'. Images can be located within\n   * the file system if the docroot method is used to specify\n   * where the docroot resides. If the image can be found, the\n   * image_size method is used to determine the dimensions of\n   * the image.</li>\n   *\n   * <li><b>extra</b>\n   *\n   * Additional parameters for the image. This would include\n   * alt text, height/width specification or scaling instructions.</li>\n   *\n   * <li><b>align</b>\n   *\n   * Alignment attribute.</li>\n   *\n   * <li><b>pre</b>\n   *\n   * Text to produce prior to the tag.</li>\n   *\n   * <li><b>post</b>\n   *\n   * Text to produce following the tag.</li>\n   *\n   * <li><b>link</b>\n   *\n   * Optional URL to connect with the image tag.</li>\n   *\n   * <li><b>clsty</b>\n   *\n   * Class and/or style attributes.</li>\n   *\n   * </ul>\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the image.\n   *\n   * @return A @c string containing the formatted image.\n   *\n   * @private\n   */\n  function format_image($args) {\n    $src = (isset($args['src']) ? $args['src'] : '');\n    $extra = $args['extra'];\n    $align = $args['align'];\n    $pre = (isset($args['pre']) ? $args['pre'] : '');\n    $post = (isset($args['post']) ? $args['post'] : '');\n    $link = $args['url'];\n    $clsty = $args['clsty'];\n    $this->_strip_borders($pre, $post);\n    if (strlen($src) == 0) { return $pre . '!!' . $post; }\n    unset($tag);\n    if (preg_match('/^xhtml2/', $this->options['flavor'])) {\n      unset($type); // poor man's mime typing. need to extend this externally\n      if (preg_match('/(?:\\.jpeg|\\.jpg)$/i', $src)) {\n        $type = 'image/jpeg';\n      } elseif (preg_match('/\\.gif$/i', $src)) {\n        $type = 'image/gif';\n      } elseif (preg_match('/\\.png$/i', $src)) {\n        $type = 'image/png';\n      } elseif (preg_match('/\\.tiff$/i', $src)) {\n        $type = 'image/tiff';\n      }\n      $tag = \"<object\";\n      if ($type) { $tag .= \" type=\\\"$type\\\"\"; }\n      $tag .= \" data=\\\"$src\\\"\";\n    } else {\n      $tag = \"<img src=\\\"$src\\\"\";\n    }\n    unset($class, $style);\n    if ($align) {\n      if ($this->options['css_mode']) {\n        $alignment = $this->_halign($align);\n        if ($alignment) { $style .= \";float:$alignment\"; }\n        if ($alignment) { $class .= ' ' . $alignment; }\n        $alignment = $this->_valign($align);\n        if ($alignment) {\n          $imgvalign = (preg_match('/(top|bottom)/', $alignment) ? 'text-' . $alignment : $alignment);\n          if ($imgvalign) { $style .= \";vertical-align:$imgvalign\"; }\n          if ($alignment) { $class .= ' ' . $this->options['css'][\"class_align_$alignment\"]; }\n        }\n      } else {\n        $alignment = ($this->_halign($align) ? $this->_halign($align) : $this->_valign($align));\n        if ($alignment) { $tag .= \" align=\\\"$alignment\\\"\"; }\n      }\n    }\n    unset($pctw, $pcth, $w, $h, $alt);\n    if ($extra) {\n      $alt = (preg_match('/\\(([^\\)]+)\\)/', $extra, $matches) ? $matches[1] : '');\n      $extra = preg_replace('/\\([^\\)]+\\)/', '', $extra, 1);\n      $pct = (preg_match('/(^|\\s)(\\d+)%(\\s|$)/', $extra, $matches) ? $matches[2] : '');\n      if (!$pct) {\n        list($pctw, $pcth) = (preg_match('/(^|\\s)(\\d+)%x(\\d+)%(\\s|$)/', $extra, $matches) ? array($matches[2], $matches[3]) : NULL);\n      } else {\n        $pctw = $pcth = $pct;\n      }\n      if (!$pctw && !$pcth) {\n        list($w,$h) = (preg_match('/(^|\\s)(\\d+|\\*)x(\\d+|\\*)(\\s|$)/', $extra, $matches) ? array($matches[2], $matches[3]) : NULL);\n        if ($w == '*') { $w = ''; }\n        if ($h == '*') { $h = ''; }\n        if (!$w) {\n          $w = (preg_match('/(^|[,\\s])(\\d+)w([\\s,]|$)/', $extra, $matches) ? $matches[2] : '');\n        }\n        if (!$h) {\n          $h = (preg_match('/(^|[,\\s])(\\d+)h([\\s,]|$)/', $extra, $matches) ? $matches[2] : '');\n        }\n      }\n    }\n    $alt = ($alt ? $alt : '');\n    if (!preg_match('/^xhtml2/', $this->options['flavor'])) {\n      $tag .= ' alt=\"' . $this->encode_html_basic($alt) . '\"';\n    }\n    if ($w && $h) {\n      if (!preg_match('/^xhtml2/', $this->options['flavor'])) {\n        $tag .= \" height=\\\"$h\\\" width=\\\"$w\\\"\";\n      } else {\n        $style .= \";height:${h}px;width:${w}px\";\n      }\n    } else {\n      list($image_w, $image_h) = $this->image_size($src);\n      if (($image_w && $image_h) && ($w || $h)) {\n        // image size determined, but only width or height specified\n        if ($w && !$h) {\n          // width defined, scale down height proportionately\n          $h = intval($image_h * ($w / $image_w));\n        } elseif ($h && !$w) {\n          $w = intval($image_w * ($h / $image_h));\n        }\n      } else {\n        $w = $image_w;\n        $h = $image_h;\n      }\n      if ($w && $h) {\n        if ($pctw || $pcth) {\n          $w = intval($w * $pctw / 100);\n          $h = intval($h * $pcth / 100);\n        }\n        if (!preg_match('/^xhtml2/', $this->options['flavor'])) {\n          $tag .= \" height=\\\"$h\\\" width=\\\"$w\\\"\";\n        } else {\n          $style .= \";height:{$h}px;width:{$w}px\";\n        }\n      }\n    }\n    $attr = $this->format_classstyle($clsty, $class, $style);\n    if ($attr) { $tag .= \" $attr\"; }\n    if (preg_match('/^xhtml2/', $this->options['flavor'])) {\n      $tag .= '><p>' . $this->encode_html_basic($alt) . '</p></object>';\n    } elseif (preg_match('/^xhtml/', $this->options['flavor'])) {\n      $tag .= ' />';\n    } else {\n      $tag .= '>';\n    }\n    if ($link) {\n      $link = preg_replace('/^:/', '', $link, 1);\n      $link = $this->format_url(array('url' => $link));\n      $tag = '<a href=\"' . $link . '\">' . $tag . '</a>';\n    }\n    return $pre . $tag . $post;\n  } // function format_image\n\n  /**\n   * Takes a Wiki-ish string of data and transforms it into a full\n   * table.\n   *\n   * @param $args An @c array specifying the attributes for formatting\n   *        the table.\n   *\n   * @return A @c string containing the formatted table.\n   *\n   * @private\n   */\n  function format_table($args) {\n    $str = (isset($args['text']) ? $args['text'] : '');\n\n    $lines = preg_split('/\\n/', $str);\n    unset($rows);\n    $line_count = count($lines);\n    for ($i = 0; $i < $line_count; $i++) {\n      if (!preg_match('/\\|\\s*$/', $lines[$i])) {\n        if ($i + 1 < $line_count) {\n          if ($i + 1 <= count($lines) - 1) { $lines[$i + 1] = $lines[$i] . \"\\n\" . $lines[$i + 1]; }\n        } else {\n          $rows[] = $lines[$i];\n        }\n      } else {\n        $rows[] = $lines[$i];\n      }\n    }\n    unset($tid, $tpadl, $tpadr, $tlang);\n    $tclass = '';\n    $tstyle = '';\n    $talign = '';\n    if (preg_match('/^table[^\\.]/', $rows[0])) {\n      $row = $rows[0];\n      $row = preg_replace('/^table/', '', $row, 1);\n      $params = 1;\n      // process row parameters until none are left\n      while ($params) {\n        if (preg_match('{^(' . $this->tblalignre . ')}', $row, $matches)) {\n          // found row alignment\n          $talign .= $matches[1];\n          if ($matches[1]) { $row = substr($row, strlen($matches[1])); }\n          if ($matches[1]) { continue; }\n        }\n        if (preg_match('{^(' . $this->clstypadre . ')}x', $row, $matches)) {\n          // found a class/id/style/padding indicator\n          $clsty = $matches[1];\n          if ($clsty) { $row = substr($row, strlen($clsty)); }\n          if (preg_match('/{([^}]+)}/', $clsty, $matches)) {\n            $tstyle = $matches[1];\n            $clsty = preg_replace('/{([^}]+)}/', '', $clsty, 1);\n            if ($tstyle) { continue; }\n          }\n          if (preg_match('/\\(([A-Za-z0-9_\\- ]+?)(?:#(.+?))?\\)/', $clsty, $matches) ||\n              preg_match('/\\(([A-Za-z0-9_\\- ]+?)?(?:#(.+?))\\)/', $clsty, $matches)) {\n            if ($matches[1] || $matches[2]) {\n              $tclass = $matches[1];\n              $tid = $matches[2];\n              continue;\n            }\n          }\n          if (preg_match('/(\\(+)/', $clsty, $matches)) { $tpadl = strlen($matches[1]); }\n          if (preg_match('/(\\)+)/', $clsty, $matches)) { $tpadr = strlen($matches[1]); }\n          if (preg_match('/\\[(.+?)\\]/', $clsty, $matches)) { $tlang = $matches[1]; }\n          if ($clsty) { continue; }\n        }\n        $params = 0;\n      }\n      $row = preg_replace('/\\.\\s+/', '', $row, 1);\n      $rows[0] = $row;\n    }\n    $out = '';\n    $cols = preg_split('/\\|/', $rows[0] . ' ');\n    unset($colaligns, $rowspans);\n    foreach ($rows as $row) {\n      $cols = preg_split('/\\|/', $row . ' ');\n      $colcount = count($cols) - 1;\n      array_pop($cols);\n      $colspan = 0;\n      $row_out = '';\n      unset($rowclass, $rowid, $rowalign, $rowstyle, $rowheader);\n      if (!$cols[0]) { $cols[0] = ''; }\n      if (preg_match('/_/', $cols[0])) {\n        $cols[0] = preg_replace('/_/', '', $cols[0]);\n        $rowheader = 1;\n      }\n      if (preg_match('/{([^}]+)}/', $cols[0], $matches)) {\n        $rowstyle = $matches[1];\n        $cols[0] = preg_replace('/{[^}]+}/', '', $cols[0]);\n      }\n      if (preg_match('/\\(([^\\#]+?)?(#(.+))?\\)/', $cols[0], $matches)) {\n        $rowclass = $matches[1];\n        $rowid = $matches[3];\n        $cols[0] = preg_replace('/\\([^\\)]+\\)/', '', $cols[0]);\n      }\n      if (preg_match('{(' . $this->alignre . ')}', $cols[0], $matches)) { $rowalign = $matches[1]; }\n      for ($c = $colcount - 1; $c > 0; $c--) {\n        if ($rowspans[$c]) {\n          $rowspans[$c]--;\n          if ($rowspans[$c] > 1) { continue; }\n        }\n        unset($colclass, $colid, $header, $colparams, $colpadl, $colpadr, $collang);\n        $colstyle = '';\n        $colalign = $colaligns[$c];\n        $col = array_pop($cols);\n        $col = ($col ? $col : '');\n        $attrs = '';\n        if (preg_match('{^(((_|[/\\\\\\\\]\\d+|' . $this->alignre . '|' . $this->clstypadre . ')+)\\.\\ )}x', $col, $matches)) {\n          $colparams = $matches[2];\n          $col = substr($col, strlen($matches[1]));\n          $params = 1;\n          // keep processing column parameters until there\n          // are none left...\n          while ($params) {\n            if (preg_match('{^(_|' . $this->alignre . ')(.*)$}', $colparams, $matches)) {\n              // found alignment or heading indicator\n              $attrs .= $matches[1];\n              if ($matches[1]) { $colparams = $matches[2]; }\n              if ($matches[1]) { continue; }\n            }\n            if (preg_match('{^(' . $this->clstypadre . ')(.*)$}x', $colparams, $matches)) {\n              // found a class/id/style/padding marker\n              $clsty = $matches[1];\n              if ($clsty) { $colparams = $matches[2]; }\n              if (preg_match('/{([^}]+)}/', $clsty, $matches)) {\n                $colstyle = $matches[1];\n                $clsty = preg_replace('/{([^}]+)}/', '', $clsty, 1);\n              }\n              if (preg_match('/\\(([A-Za-z0-9_\\- ]+?)(?:#(.+?))?\\)/', $clsty, $matches) ||\n                  preg_match('/\\(([A-Za-z0-9_\\- ]+?)?(?:#(.+?))\\)/', $clsty, $matches)) {\n                if ($matches[1] || $matches[2]) {\n                  $colclass = $matches[1];\n                  $colid = $matches[2];\n                  if ($colclass) {\n                    $clsty = preg_replace('/\\([A-Za-z0-9_\\- ]+?(#.*?)?\\)/', '', $clsty);\n                  } elseif ($colid) {\n                    $clsty = preg_replace('/\\(#.+?\\)/', '', $clsty);\n                  }\n                }\n              }\n              if (preg_match('/(\\(+)/', $clsty, $matches)) {\n                $colpadl = strlen($matches[1]);\n                $clsty = preg_replace('/\\(+/', '', $clsty, 1);\n              }\n              if (preg_match('/(\\)+)/', $clsty, $matches)) {\n                $colpadr = strlen($matches[1]);\n                $clsty = preg_replace('/\\)+/', '', $clsty, 1);\n              }\n              if (preg_match('/\\[(.+?)\\]/', $clsty, $matches)) {\n                $collang = $matches[1];\n                $clsty = preg_replace('/\\[.+?\\]/', '', $clsty, 1);\n              }\n              if ($clsty) { continue; }\n            }\n            if (preg_match('/^\\\\\\\\(\\d+)/', $colparams, $matches)) {\n              $colspan = $matches[1];\n              $colparams = substr($colparams, strlen($matches[1]) + 1);\n              if ($matches[1]) { continue; }\n            }\n            if (preg_match('/\\/(\\d+)/', $colparams, $matches)) {\n              if ($matches[1]) { $rowspans[$c] = $matches[1]; }\n              $colparams = substr($colparams, strlen($matches[1]) + 1);\n              if ($matches[1]) { continue; }\n            }\n            $params = 0;\n          }\n        }\n        if (strlen($attrs)) {\n          if (preg_match('/_/', $attrs)) { $header = 1; }\n          if (preg_match('{(' . $this->alignre . ')}', $attrs, $matches) && strlen($matches[1])) { $colalign = ''; }\n          // determine column alignment\n          if (preg_match('/<>/', $attrs)) {\n            $colalign .= '<>';\n          } elseif (preg_match('/</', $attrs)) {\n            $colalign .= '<';\n          } elseif (preg_match('/=/', $attrs)) {\n            $colalign = '=';\n          } elseif (preg_match('/>/', $attrs)) {\n            $colalign = '>';\n          }\n          if (preg_match('/\\^/', $attrs)) {\n            $colalign .= '^';\n          } elseif (preg_match('/~/', $attrs)) {\n            $colalign .= '~';\n          } elseif (preg_match('/-/', $attrs)) {\n            $colalign .= '-';\n          }\n        }\n        if ($rowheader) { $header = 1; }\n        if ($header) { $colaligns[$c] = $colalign; }\n        $col = preg_replace('/^ +/', '', $col, 1); $col = preg_replace('/ +$/', '', $col, 1);\n        if (strlen($col)) {\n          // create one cell tag\n          $rowspan = ($rowspans[$c] ? $rowspans[$c] : 0);\n          $col_out = '<' . ($header ? 'th' : 'td');\n          if ($colalign) {\n            // horizontal, vertical alignment\n            $halign = $this->_halign($colalign);\n            if ($halign) { $col_out .= \" align=\\\"$halign\\\"\"; }\n            $valign = $this->_valign($colalign);\n            if ($valign) { $col_out .= \" valign=\\\"$valign\\\"\"; }\n          }\n          // apply css attributes, row, column spans\n          if ($colpadl) { $colstyle .= \";padding-left:${colpadl}em\"; }\n          if ($colpadr) { $colstyle .= \";padding-right:${colpadr}em\"; }\n          if ($colclass) { $col_out .= \" class=\\\"$colclass\\\"\"; }\n          if ($colid) { $col_out .= \" id=\\\"$colid\\\"\"; }\n          if ($colstyle) { $colstyle = preg_replace('/^;/', '', $colstyle, 1); }\n          if ($colstyle) { $col_out .= \" style=\\\"$colstyle\\\"\"; }\n          if ($collang) { $col_out .= \" lang=\\\"$collang\\\"\"; }\n          if ($colspan > 1) { $col_out .= \" colspan=\\\"$colspan\\\"\"; }\n          if ($rowspan > 1) { $col_out .= \" rowspan=\\\"$rowspan\\\"\"; }\n          $col_out .= '>';\n          // if the content of this cell has newlines OR matches\n          // our paragraph block signature, process it as a full-blown\n          // textile document\n          if (preg_match('/\\n\\n/', $col) ||\n              preg_match('{^(?:' . $this->halignre . '|' . $this->clstypadre . '*)*\n                            [\\*\\#]\n                            (?:' . $this->clstypadre . '*|' . $this->halignre . ')*\\ }x', $col)) {\n            $col_out .= $this->process($col);\n          } else {\n            $col_out .= $this->format_paragraph(array('text' => $col));\n          }\n          $col_out .= '</' . ($header ? 'th' : 'td') . '>';\n          $row_out = $col_out . $row_out;\n          if ($colspan) { $colspan = 0; }\n        } else {\n          if ($colspan == 0) { $colspan = 1; }\n          $colspan++;\n        }\n      }\n      if ($colspan > 1) {\n        // handle the spanned column if we came up short\n        $colspan--;\n        $row_out = \"<td\"\n                 . ($colspan > 1 ? \" colspan=\\\"$colspan\\\"\" : '')\n                 . \"></td>$row_out\";\n      }\n\n      // build one table row\n      $out .= \"<tr\";\n      if ($rowalign) {\n        $valign = $this->_valign($rowalign);\n        if ($valign) { $out .= \" valign=\\\"$valign\\\"\"; }\n      }\n      if ($rowclass) { $out .= \" class=\\\"$rowclass\\\"\"; }\n      if ($rowid) { $out .= \" id=\\\"$rowid\\\"\"; }\n      if ($rowstyle) { $out .= \" style=\\\"$rowstyle\\\"\"; }\n      $out .= \">$row_out</tr>\";\n    }\n\n    // now, form the table tag itself\n    $table = '';\n    $table .= \"<table\";\n    if ($talign) {\n      if ($this->options['css_mode']) {\n        // horizontal alignment\n        $alignment = $this->_halign($talign);\n        if ($talign == '=') {\n          $tstyle .= ';margin-left:auto;margin-right:auto';\n        } else {\n          if ($alignment) { $tstyle .= ';float:' . $alignment; }\n        }\n        if ($alignment) { $tclass .= ' ' . $alignment; }\n      } else {\n        $alignment = $this->_halign($talign);\n        if ($alignment) { $table .= \" align=\\\"$alignment\\\"\"; }\n      }\n    }\n    if ($tpadl) { $tstyle .= \";padding-left:${tpadl}em\"; }\n    if ($tpadr) { $tstyle .= \";padding-right:${tpadr}em\"; }\n    if ($tclass) { $tclass = preg_replace('/^ /', '', $tclass, 1); }\n    if ($tclass) { $table .= \" class=\\\"$tclass\\\"\"; }\n    if ($tid) { $table .= \" id=\\\"$tid\\\"\"; }\n    if ($tstyle) { $tstyle = preg_replace('/^;/', '', $tstyle, 1); }\n    if ($tstyle) { $table .= \" style=\\\"$tstyle\\\"\"; }\n    if ($tlang) { $table .= \" lang=\\\"$tlang\\\"\"; }\n    if ($tclass || $tid || $tstyle) { $table .= \" cellspacing=\\\"0\\\"\"; }\n    $table .= \">$out</table>\";\n\n    if (preg_match('|<tr></tr>|', $table)) {\n      // exception -- something isn't right so return fail case\n      return NULL;\n    }\n\n    return $table;\n  } // function format_table\n\n  /**\n   * The following attributes are allowed:\n   *\n   * <ul>\n   *\n   * <li><b>text</b>\n   *\n   * The text to be processed.</li>\n   *\n   * <li><b>filters</b>\n   *\n   * An array reference of filter names to run for the given text.</li>\n   *\n   * </ul>\n   *\n   * @param $args An @c array specifying the text and filters to\n   *        apply.\n   *\n   * @return A @c string containing the filtered text.\n   *\n   * @private\n   */\n  function apply_filters($args) {\n    $text = $args['text'];\n    if (!$text) { return ''; }\n    $list = $args['filters'];\n    $filters = $this->options['filters'];\n    if (!is_array($filters)) { return $text; }\n\n    $param = $this->filter_param();\n    foreach ($list as $filter) {\n      if (!isset($filters[$filter])) { continue; }\n      if (is_string($filters[$filter])) {\n        $text = (($f = create_function('$text, $param', $filters[$filter])) ? $f($text, $param) : $text);\n      }\n    }\n    return $text;\n  } // function apply_filters\n\n  // minor utility / formatting routines\n\n  var $Have_Entities = 1;\n\n  /**\n   * Encodes input @c $html string, escaping characters as needed\n   * to HTML entities. This relies on the @c htmlentities function\n   * for full effect. If unavailable, @c encode_html_basic is used\n   * as a fallback technique. If the \"char_encoding\" flag is\n   * set to false, @c encode_html_basic is used exclusively.\n   *\n   * @param $html A @c string specifying the HTML to be encoded.\n   * @param $can_double_encode If provided, a @c bool indicating\n   *        whether or not ampersand characters should be\n   *        unconditionally encoded.\n   *\n   * @return A @c string containing the encoded HTML.\n   *\n   * @private\n   */\n  function encode_html($html, $can_double_encode = FALSE) {\n    if (!$html) { return ''; }\n    if ($this->Have_Entities && $this->options['char_encoding']) {\n      $html = htmlentities($html, ENT_QUOTES, $this->options['char_encoding']);\n    } else {\n      $html = $this->encode_html_basic($html, $can_double_encode);\n    }\n    return $html;\n  } // function encode_html\n\n  /**\n   * Decodes HTML entities in @c $html to their natural character\n   * equivalents.\n   *\n   * @param $html A @c string specifying the HTML to be decoded.\n   *\n   * @return A @c string containing the decode HTML\n   *\n   * @private\n   */\n  function decode_html($html) {\n    $html = preg_replace('!&quot;!', '\"', $html);\n    $html = preg_replace('!&amp;!', '&', $html);\n    $html = preg_replace('!&lt;!', '<', $html);\n    $html = preg_replace('!&gt;!', '>', $html);\n    return $html;\n  } // function decode_html\n\n  /**\n   * Encodes the input @c $html string for the following characters:\n   * \\<, \\>, & and \". If @c $can_double_encode is true, all\n   * ampersand characters are escaped even if they already were.\n   * If @c $can_double_encode is false, ampersands are only escaped\n   * when they aren't part of a HTML entity already.\n   *\n   * @param $html A @c string specifying the HTML to be encoded.\n   * @param $can_double_encode If provided, a @c bool indicating\n   *        whether or not ampersand characters should be\n   * unconditionally encoded.\n   *\n   * @return A @c string containing the encoded HTML.\n   *\n   * @private\n   */\n  function encode_html_basic($html, $can_double_encode = FALSE) {\n    if (!$html) { return ''; }\n    if (!preg_match('/[^\\w\\s]/', $html)) { return $html; }\n    if ($can_double_encode) {\n      $html = preg_replace('!&!', '&amp;', $html);\n    } else {\n      // Encode any & not followed by something that looks like\n      // an entity, numeric or otherwise.\n      $html = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\\w{1,8});)/', '&amp;', $html);\n    }\n    $html = preg_replace('!\"!', '&quot;', $html);\n    $html = preg_replace('!<!', '&lt;', $html);\n    $html = preg_replace('!>!', '&gt;', $html);\n    return $html;\n  } // function encode_html_basic\n\n  /**\n   * Returns the size for the image identified in @c $file. This\n   * method relies upon the @c getimagesize function. If unavailable,\n   * @c image_size will return @c NULL. Otherwise, the expected return\n   * value is an array of the width and height (in that order), in\n   * pixels.\n   *\n   * @param $file A @c string specifying the path or URL for the image\n   *        file.\n   *\n   * @return An @c array containing the width and height\n   *         (respectively) of the image.\n   *\n   * @private\n   */\n  function image_size($file) {\n    $Have_ImageSize = function_exists('getimagesize');\n\n    if ($Have_ImageSize) {\n      if (file_exists($file)) {\n        return @getimagesize($file);\n      } else {\n        if ($docroot = ($this->docroot() ? $this->docroot() : $_SERVER['DOCUMENT_ROOT'])) {\n          $fullpath = $docroot . preg_replace('|^/*(.*)$|', '/$1', $file);\n          if (file_exists($fullpath)) {\n            return @getimagesize($fullpath);\n          }\n        }\n      }\n    }\n    return @getimagesize($file);\n  } // function image_size\n\n  /**\n   * Encodes the query portion of a URL, escaping characters\n   * as necessary.\n   *\n   * @param $str A @c string specifying the URL to be encoded.\n   *\n   * @return A @c string containing the encoded URL.\n   *\n   * @private\n   */\n  function encode_url($str) {\n    $str = preg_replace_callback('!([^A-Za-z0-9_\\.\\-\\+\\&=%;])!x',\n                            $this->_cb('ord($m[1]) > 255 ? \\'%u\\' . sprintf(\"%04X\", ord($m[1]))\n                                                       : \\'%\\'  . sprintf(\"%02X\", ord($m[1]))'), $str);\n    return $str;\n  } // function encode_url\n\n  /**\n   * Encodes the email address in @c $addr for 'mailto:' links.\n   *\n   * @param $addr A @c string specifying the email address to encode.\n   *\n   * @return A @c string containing the encoded email address.\n   *\n   * @private\n   */\n  function mail_encode($addr) {\n    // granted, this is simple, but it gives off warm fuzzies\n    $addr = preg_replace_callback('!([^\\$])!x',\n                             $this->_cb('ord($m[1]) > 255 ? \\'%u\\' . sprintf(\"%04X\", ord($m[1]))\n                                                        : \\'%\\'  . sprintf(\"%02X\", ord($m[1]))'), $addr);\n    return $addr;\n  } // function mail_encode\n\n  /**\n   * Processes string, formatting plain quotes into curly quotes.\n   *\n   * @param $str A @c string specifying the text to process.\n   *\n   * @return A @c string containing the processed text.\n   *\n   * @private\n   */\n  function process_quotes($str) {\n    // stub routine for now. subclass and implement.\n    return $str;\n  } // function process_quotes\n\n  // a default set of macros for the {...} macro syntax\n  // just a handy way to write a lot of the international characters\n  // and some commonly used symbols\n\n  /**\n   * Returns an associative @c array of macros that are assigned to be processed by\n   * default within the @c format_inline method.\n   *\n   * @return An @c array containing the default macros.\n   *\n   * @private\n   */\n  function default_macros() {\n    // <, >, \" must be html entities in the macro text since\n    // those values are escaped by the time they are processed\n    // for macros.\n    return array(\n      'c|' => '&#162;', // CENT SIGN\n      '|c' => '&#162;', // CENT SIGN\n      'L-' => '&#163;', // POUND SIGN\n      '-L' => '&#163;', // POUND SIGN\n      'Y=' => '&#165;', // YEN SIGN\n      '=Y' => '&#165;', // YEN SIGN\n      '(c)' => '&#169;', // COPYRIGHT SIGN\n      '&lt;&lt;' => '&#171;', // LEFT-POINTING DOUBLE ANGLE QUOTATION\n      '(r)' => '&#174;', // REGISTERED SIGN\n      '+_' => '&#177;', // PLUS-MINUS SIGN\n      '_+' => '&#177;', // PLUS-MINUS SIGN\n      '&gt;&gt;' => '&#187;', // RIGHT-POINTING DOUBLE ANGLE QUOTATION\n      '1/4' => '&#188;', // VULGAR FRACTION ONE QUARTER\n      '1/2' => '&#189;', // VULGAR FRACTION ONE HALF\n      '3/4' => '&#190;', // VULGAR FRACTION THREE QUARTERS\n      'A`' => '&#192;', // LATIN CAPITAL LETTER A WITH GRAVE\n      '`A' => '&#192;', // LATIN CAPITAL LETTER A WITH GRAVE\n      'A\\'' => '&#193;', // LATIN CAPITAL LETTER A WITH ACUTE\n      '\\'A' => '&#193;', // LATIN CAPITAL LETTER A WITH ACUTE\n      'A^' => '&#194;', // LATIN CAPITAL LETTER A WITH CIRCUMFLEX\n      '^A' => '&#194;', // LATIN CAPITAL LETTER A WITH CIRCUMFLEX\n      'A~' => '&#195;', // LATIN CAPITAL LETTER A WITH TILDE\n      '~A' => '&#195;', // LATIN CAPITAL LETTER A WITH TILDE\n      'A\"' => '&#196;', // LATIN CAPITAL LETTER A WITH DIAERESIS\n      '\"A' => '&#196;', // LATIN CAPITAL LETTER A WITH DIAERESIS\n      'Ao' => '&#197;', // LATIN CAPITAL LETTER A WITH RING ABOVE\n      'oA' => '&#197;', // LATIN CAPITAL LETTER A WITH RING ABOVE\n      'AE' => '&#198;', // LATIN CAPITAL LETTER AE\n      'C,' => '&#199;', // LATIN CAPITAL LETTER C WITH CEDILLA\n      ',C' => '&#199;', // LATIN CAPITAL LETTER C WITH CEDILLA\n      'E`' => '&#200;', // LATIN CAPITAL LETTER E WITH GRAVE\n      '`E' => '&#200;', // LATIN CAPITAL LETTER E WITH GRAVE\n      'E\\'' => '&#201;', // LATIN CAPITAL LETTER E WITH ACUTE\n      '\\'E' => '&#201;', // LATIN CAPITAL LETTER E WITH ACUTE\n      'E^' => '&#202;', // LATIN CAPITAL LETTER E WITH CIRCUMFLEX\n      '^E' => '&#202;', // LATIN CAPITAL LETTER E WITH CIRCUMFLEX\n      'E\"' => '&#203;', // LATIN CAPITAL LETTER E WITH DIAERESIS\n      '\"E' => '&#203;', // LATIN CAPITAL LETTER E WITH DIAERESIS\n      'I`' => '&#204;', // LATIN CAPITAL LETTER I WITH GRAVE\n      '`I' => '&#204;', // LATIN CAPITAL LETTER I WITH GRAVE\n      'I\\'' => '&#205;', // LATIN CAPITAL LETTER I WITH ACUTE\n      '\\'I' => '&#205;', // LATIN CAPITAL LETTER I WITH ACUTE\n      'I^' => '&#206;', // LATIN CAPITAL LETTER I WITH CIRCUMFLEX\n      '^I' => '&#206;', // LATIN CAPITAL LETTER I WITH CIRCUMFLEX\n      'I\"' => '&#207;', // LATIN CAPITAL LETTER I WITH DIAERESIS\n      '\"I' => '&#207;', // LATIN CAPITAL LETTER I WITH DIAERESIS\n      'D-' => '&#208;', // LATIN CAPITAL LETTER ETH\n      '-D' => '&#208;', // LATIN CAPITAL LETTER ETH\n      'N~' => '&#209;', // LATIN CAPITAL LETTER N WITH TILDE\n      '~N' => '&#209;', // LATIN CAPITAL LETTER N WITH TILDE\n      'O`' => '&#210;', // LATIN CAPITAL LETTER O WITH GRAVE\n      '`O' => '&#210;', // LATIN CAPITAL LETTER O WITH GRAVE\n      'O\\'' => '&#211;', // LATIN CAPITAL LETTER O WITH ACUTE\n      '\\'O' => '&#211;', // LATIN CAPITAL LETTER O WITH ACUTE\n      'O^' => '&#212;', // LATIN CAPITAL LETTER O WITH CIRCUMFLEX\n      '^O' => '&#212;', // LATIN CAPITAL LETTER O WITH CIRCUMFLEX\n      'O~' => '&#213;', // LATIN CAPITAL LETTER O WITH TILDE\n      '~O' => '&#213;', // LATIN CAPITAL LETTER O WITH TILDE\n      'O\"' => '&#214;', // LATIN CAPITAL LETTER O WITH DIAERESIS\n      '\"O' => '&#214;', // LATIN CAPITAL LETTER O WITH DIAERESIS\n      'O/' => '&#216;', // LATIN CAPITAL LETTER O WITH STROKE\n      '/O' => '&#216;', // LATIN CAPITAL LETTER O WITH STROKE\n      'U`' =>  '&#217;', // LATIN CAPITAL LETTER U WITH GRAVE\n      '`U' =>  '&#217;', // LATIN CAPITAL LETTER U WITH GRAVE\n      'U\\'' => '&#218;', // LATIN CAPITAL LETTER U WITH ACUTE\n      '\\'U' => '&#218;', // LATIN CAPITAL LETTER U WITH ACUTE\n      'U^' => '&#219;', // LATIN CAPITAL LETTER U WITH CIRCUMFLEX\n      '^U' => '&#219;', // LATIN CAPITAL LETTER U WITH CIRCUMFLEX\n      'U\"' => '&#220;', // LATIN CAPITAL LETTER U WITH DIAERESIS\n      '\"U' => '&#220;', // LATIN CAPITAL LETTER U WITH DIAERESIS\n      'Y\\'' => '&#221;', // LATIN CAPITAL LETTER Y WITH ACUTE\n      '\\'Y' => '&#221;', // LATIN CAPITAL LETTER Y WITH ACUTE\n      'a`' => '&#224;', // LATIN SMALL LETTER A WITH GRAVE\n      '`a' => '&#224;', // LATIN SMALL LETTER A WITH GRAVE\n      'a\\'' => '&#225;', // LATIN SMALL LETTER A WITH ACUTE\n      '\\'a' => '&#225;', // LATIN SMALL LETTER A WITH ACUTE\n      'a^' => '&#226;', // LATIN SMALL LETTER A WITH CIRCUMFLEX\n      '^a' => '&#226;', // LATIN SMALL LETTER A WITH CIRCUMFLEX\n      'a~' => '&#227;', // LATIN SMALL LETTER A WITH TILDE\n      '~a' => '&#227;', // LATIN SMALL LETTER A WITH TILDE\n      'a\"' => '&#228;', // LATIN SMALL LETTER A WITH DIAERESIS\n      '\"a' => '&#228;', // LATIN SMALL LETTER A WITH DIAERESIS\n      'ao' => '&#229;', // LATIN SMALL LETTER A WITH RING ABOVE\n      'oa' => '&#229;', // LATIN SMALL LETTER A WITH RING ABOVE\n      'ae' => '&#230;', // LATIN SMALL LETTER AE\n      'c,' => '&#231;', // LATIN SMALL LETTER C WITH CEDILLA\n      ',c' => '&#231;', // LATIN SMALL LETTER C WITH CEDILLA\n      'e`' => '&#232;', // LATIN SMALL LETTER E WITH GRAVE\n      '`e' => '&#232;', // LATIN SMALL LETTER E WITH GRAVE\n      'e\\'' => '&#233;', // LATIN SMALL LETTER E WITH ACUTE\n      '\\'e' => '&#233;', // LATIN SMALL LETTER E WITH ACUTE\n      'e^' => '&#234;', // LATIN SMALL LETTER E WITH CIRCUMFLEX\n      '^e' => '&#234;', // LATIN SMALL LETTER E WITH CIRCUMFLEX\n      'e\"' => '&#235;', // LATIN SMALL LETTER E WITH DIAERESIS\n      '\"e' => '&#235;', // LATIN SMALL LETTER E WITH DIAERESIS\n      'i`' => '&#236;', // LATIN SMALL LETTER I WITH GRAVE\n      '`i' => '&#236;', // LATIN SMALL LETTER I WITH GRAVE\n      'i\\'' => '&#237;', // LATIN SMALL LETTER I WITH ACUTE\n      '\\'i' => '&#237;', // LATIN SMALL LETTER I WITH ACUTE\n      'i^' => '&#238;', // LATIN SMALL LETTER I WITH CIRCUMFLEX\n      '^i' => '&#238;', // LATIN SMALL LETTER I WITH CIRCUMFLEX\n      'i\"' => '&#239;', // LATIN SMALL LETTER I WITH DIAERESIS\n      '\"i' => '&#239;', // LATIN SMALL LETTER I WITH DIAERESIS\n      'n~' => '&#241;', // LATIN SMALL LETTER N WITH TILDE\n      '~n' => '&#241;', // LATIN SMALL LETTER N WITH TILDE\n      'o`' => '&#242;', // LATIN SMALL LETTER O WITH GRAVE\n      '`o' => '&#242;', // LATIN SMALL LETTER O WITH GRAVE\n      'o\\'' => '&#243;', // LATIN SMALL LETTER O WITH ACUTE\n      '\\'o' => '&#243;', // LATIN SMALL LETTER O WITH ACUTE\n      'o^' => '&#244;', // LATIN SMALL LETTER O WITH CIRCUMFLEX\n      '^o' => '&#244;', // LATIN SMALL LETTER O WITH CIRCUMFLEX\n      'o~' => '&#245;', // LATIN SMALL LETTER O WITH TILDE\n      '~o' => '&#245;', // LATIN SMALL LETTER O WITH TILDE\n      'o\"' => '&#246;', // LATIN SMALL LETTER O WITH DIAERESIS\n      '\"o' => '&#246;', // LATIN SMALL LETTER O WITH DIAERESIS\n      ':-' => '&#247;', // DIVISION SIGN\n      '-:' => '&#247;', // DIVISION SIGN\n      'o/' => '&#248;', // LATIN SMALL LETTER O WITH STROKE\n      '/o' => '&#248;', // LATIN SMALL LETTER O WITH STROKE\n      'u`' => '&#249;', // LATIN SMALL LETTER U WITH GRAVE\n      '`u' => '&#249;', // LATIN SMALL LETTER U WITH GRAVE\n      'u\\'' => '&#250;', // LATIN SMALL LETTER U WITH ACUTE\n      '\\'u' => '&#250;', // LATIN SMALL LETTER U WITH ACUTE\n      'u^' => '&#251;', // LATIN SMALL LETTER U WITH CIRCUMFLEX\n      '^u' => '&#251;', // LATIN SMALL LETTER U WITH CIRCUMFLEX\n      'u\"' => '&#252;', // LATIN SMALL LETTER U WITH DIAERESIS\n      '\"u' => '&#252;', // LATIN SMALL LETTER U WITH DIAERESIS\n      'y\\'' => '&#253;', // LATIN SMALL LETTER Y WITH ACUTE\n      '\\'y' => '&#253;', // LATIN SMALL LETTER Y WITH ACUTE\n      'y\"' => '&#255;', // LATIN SMALL LETTER Y WITH DIAERESIS\n      '\"y' => '&#255;', // LATIN SMALL LETTER Y WITH DIAERESIS\n      'OE' => '&#338;', // LATIN CAPITAL LIGATURE OE\n      'oe' => '&#339;', // LATIN SMALL LIGATURE OE\n      '*' => '&#8226;', // BULLET\n      'Fr' => '&#8355;', // FRENCH FRANC SIGN\n      'L=' => '&#8356;', // LIRA SIGN\n      '=L' => '&#8356;', // LIRA SIGN\n      'Rs' => '&#8360;', // RUPEE SIGN\n      'C=' => '&#8364;', // EURO SIGN\n      '=C' => '&#8364;', // EURO SIGN\n      'tm' => '&#8482;', // TRADE MARK SIGN\n      '&lt;-' => '&#8592;', // LEFTWARDS ARROW\n      '-&gt;' => '&#8594;', // RIGHTWARDS ARROW\n      '&lt;=' => '&#8656;', // LEFTWARDS DOUBLE ARROW\n      '=&gt;' => '&#8658;', // RIGHTWARDS DOUBLE ARROW\n      '=/' => '&#8800;', // NOT EQUAL TO\n      '/=' => '&#8800;', // NOT EQUAL TO\n      '&lt;_' => '&#8804;', // LESS-THAN OR EQUAL TO\n      '_&lt;' => '&#8804;', // LESS-THAN OR EQUAL TO\n      '&gt;_' => '&#8805;', // GREATER-THAN OR EQUAL TO\n      '_&gt;' => '&#8805;', // GREATER-THAN OR EQUAL TO\n      ':(' => '&#9785;', // WHITE FROWNING FACE\n      ':)' => '&#9786;', // WHITE SMILING FACE\n      'spade' => '&#9824;', // BLACK SPADE SUIT\n      'club' => '&#9827;', // BLACK CLUB SUIT\n      'heart' => '&#9829;', // BLACK HEART SUIT\n      'diamond' => '&#9830;', // BLACK DIAMOND SUIT\n    );\n  } // function default_macros\n\n  // \"private\", internal routines\n\n  /**\n   * Sets the default CSS names for CSS controlled markup. This\n   * is an internal function that should not be called directly.\n   *\n   * @private\n   */\n  function _css_defaults() {\n    $css_defaults = array(\n      'class_align_right' => 'right',\n      'class_align_left' => 'left',\n      'class_align_center' => 'center',\n      'class_align_top' => 'top',\n      'class_align_bottom' => 'bottom',\n      'class_align_middle' => 'middle',\n      'class_align_justify' => 'justify',\n      'class_caps' => 'caps',\n      'class_footnote' => 'footnote',\n      'id_footnote_prefix' => 'fn',\n    );\n    $this->css($css_defaults);\n  } // function _css_defaults\n\n  /**\n   * Returns the alignment keyword depending on the symbol passed.\n   *\n   * <ul>\n   *\n   * <li><b><code>\\<\\></code></b>\n   *\n   * becomes 'justify'</li>\n   *\n   * <li><b><code>\\<</code></b>\n   *\n   * becomes 'left'</li>\n   *\n   * <li><b><code>\\></code></b>\n   *\n   * becomes 'right'</li>\n   *\n   * <li><b><code>=</code></b>\n   *\n   * becomes 'center'</li>\n   *\n   * </ul>\n   *\n   * @param $align A @c string specifying the alignment code.\n   *\n   * @return A @c string containing the alignment text.\n   *\n   * @private\n   */\n  function _halign($align) {\n    if (preg_match('/<>/', $align)) {\n      return 'justify';\n    } elseif (preg_match('/</', $align)) {\n      return 'left';\n    } elseif (preg_match('/>/', $align)) {\n      return 'right';\n    } elseif (preg_match('/=/', $align)) {\n      return 'center';\n    }\n    return '';\n  } // function _halign\n\n  /**\n   * Returns the alignment keyword depending on the symbol passed.\n   *\n   * <ul>\n   *\n   * <li><b><code>^</code></b>\n   *\n   * becomes 'top'</li>\n   *\n   * <li><b><code>~</code></b>\n   *\n   * becomes 'bottom'</li>\n   *\n   * <li><b><code>-</code></b>\n   *\n   * becomes 'middle'</li>\n   *\n   * </ul>\n   *\n   * @param $align A @c string specifying the alignment code.\n   *\n   * @return A @c string containing the alignment text.\n   *\n   * @private\n   */\n  function _valign($align) {\n    if (preg_match('/\\^/', $align)) {\n      return 'top';\n    } elseif (preg_match('/~/', $align)) {\n      return 'bottom';\n    } elseif (preg_match('/-/', $align)) {\n      return 'middle';\n    }\n    return '';\n  } // function _valign\n\n  /**\n   * Returns the alignment keyword depending on the symbol passed.\n   * The following alignment symbols are recognized, and given\n   * preference in the order listed:\n   *\n   * <ul>\n   *\n   * <li><b><code>^</code></b>\n   *\n   * becomes 'top'</li>\n   *\n   * <li><b><code>~</code></b>\n   *\n   * becomes 'bottom'</li>\n   *\n   * <li><b><code>-</code></b>\n   *\n   * becomes 'middle'</li>\n   *\n   * <li><b><code>\\<</code></b>\n   *\n   * becomes 'left'</li>\n   *\n   * <li><b><code>\\></code></b>\n   *\n   * becomes 'right'</li>\n   *\n   * </ul>\n   *\n   * @param $align A @c string containing the alignment code.\n   *\n   * @return A @c string containing the alignment text.\n   *\n   * @private\n   */\n  function _imgalign($align) {\n    $align = preg_replace('/(<>|=)/', '', $align);\n    return ($this->_valign($align) ? $this->_valign($align) : $this->_halign($align));\n  } // function _imgalign\n\n  /**\n   * This utility routine will take 'border' characters off of\n   * the given @c $pre and @c $post strings if they match one of these\n   * conditions:\n   * <pre>\n   *     $pre starts with '[', $post ends with ']'\n   *     $pre starts with '{', $post ends with '}'\n   * </pre>\n   * If neither condition is met, then the @c $pre and @c $post\n   * values are left untouched.\n   *\n   * @param $pre A @c string specifying the prefix.\n   * @param $post A @c string specifying the postfix.\n   *\n   * @private\n   */\n  function _strip_borders(&$pre, &$post) {\n    if ($post && $pre && preg_match('/[{[]/', ($open = substr($pre, 0, 1)))) {\n      $close = substr($post, 0, 1);\n      if ((($open == '{') && ($close == '}')) ||\n          (($open == '[') && ($close == ']'))) {\n        $pre = substr($pre, 1);\n        $post = substr($post, 1);\n      } else {\n        if (!preg_match('/[}\\]]/', $close)) { $close = substr($post, -1, 1); }\n        if ((($open == '{') && ($close == '}')) ||\n            (($open == '[') && ($close == ']'))) {\n          $pre = substr($pre, 1);\n          $post = substr($post, 0, strlen($post) - 1);\n        }\n      }\n    }\n  } // function _strip_borders\n\n  /**\n   * An internal routine that takes a string and appends it to an array.\n   * It returns a marker that is used later to restore the preserved\n   * string.\n   *\n   * @param $array The @c array in which to store the replacement\n   *        text.\n   * @param $str A @c string specifying the replacement text.\n   *\n   * @return A @c string containing a temporary marker for the\n   *         replacement.\n   *\n   * @private\n   */\n  function _repl(&$array, $str) {\n    $array[] = $str;\n    return '<textile#' . count($array) . '>';\n  } // function _repl\n\n  /**\n   * An internal routine responsible for breaking up a string into\n   * individual tag and plaintext elements.\n   *\n   * @param $str A @c string specifying the text to tokenize.\n   *\n   * @return An @c array containing the tag and text tokens.\n   *\n   * @private\n   */\n  function _tokenize($str) {\n    $pos = 0;\n    $len = strlen($str);\n    unset($tokens);\n\n    $depth = 6;\n    $nested_tags = substr(str_repeat('(?:</?[A-Za-z0-9:]+ \\s? (?:[^<>]|', $depth), 0, -1)\n      . str_repeat(')*>)', $depth);\n    $match = '(?s: <! ( -- .*? -- \\s* )+ > )|  # comment\n              (?s: <\\? .*? \\?> )|              # processing instruction\n              (?s: <% .*? %> )|                # ASP-like\n              (?:' . $nested_tags . ')|\n              (?:' . $this->codere . ')';     // nested tags\n\n    while (preg_match('{(' . $match . ')}x', substr($str, $pos), $matches, PREG_OFFSET_CAPTURE)) {\n      $whole_tag = $matches[1][0];\n      $sec_start = $pos + $matches[1][1] + strlen($whole_tag);\n      $tag_start = $sec_start - strlen($whole_tag);\n      if ($pos < $tag_start) {\n        $tokens[] = array('text', substr($str, $pos, $tag_start - $pos));\n      }\n      if (preg_match('/^[[{]?@/', $whole_tag)) {\n        $tokens[] = array('text', $whole_tag);\n      } else {\n        // this clever hack allows us to preserve \\n within tags.\n        // this is restored at the end of the format_paragraph method\n        //$whole_tag = preg_replace('/\\n/', \"\\r\", $whole_tag);\n        $whole_tag = preg_replace('/\\n/', \"\\001\", $whole_tag);\n        $tokens[] = array('tag', $whole_tag);\n      }\n      $pos = $sec_start;\n    }\n    if ($pos < $len) { $tokens[] = array('text', substr($str, $pos, $len - $pos)); }\n    return $tokens;\n  } // function _tokenize\n\n  /**\n   * Returns the version of this release of Textile.php. *JHR*\n   *\n   * @return An @c array with keys 'text' and 'build' containing the\n   *         text version and build ID of this release, respectively.\n   *\n   * @static\n   */\n  function version() {\n    /* Why text and an ID?  Well, the text is easier for the user to\n     * read and understand while the build ID, being a number (a date\n     * with a serial, specifically), is easier for the developer to\n     * use to determine newer/older versions for upgrade and\n     * installation purposes.\n     */\n    return array(\"text\" => \"2.0.8\", \"build\" => 2005032100);\n  } // function version\n\n/**\n   * Creates a custom callback function from the provided PHP\n   * code. The result is used as the callback in\n   * @c preg_replace_callback calls. *JHR*\n   *\n   * @param $function A @c string specifying the PHP code for the\n   *        function body.\n   *\n   * @return A @c function to be used for the callback.\n   *\n   * @private\n   */\n  function _cb($function) {\n    $current =& Textile::_current_store($this);\n    return create_function('$m', '$me =& Textile::_current(); return ' . $function . ';');\n  } // function _cb\n\n  /**\n   * Stores a static variable for the Textile class. This helper\n   * function is used by @c _current to simulate a static\n   * class variable in PHP. *JHR*\n   *\n   * @param $new If a non-@c NULL object reference, the Textile object\n   *        to be set as the current object.\n   *\n   * @return The @c array containing a reference to the current\n   *         Textile object at index 0. An array is used because PHP\n   *         does not allow static variables to be references.\n   *\n   * @static\n   * @private\n   */\n /* static */ function &_current_store(&$new) {\n   static $current = array();\n\n   if ($new != NULL) {\n     $current = array(&$new);\n   }\n\n   return $current;\n } // function _current_store\n\n  /**\n   * Returns the \"current\" Textile object. This is used within\n   * anonymous callback functions which cannot have the scope of a\n   * specific object. *JHR*\n   *\n   * @return An @c object reference to the current Textile object.\n   *\n   * @static\n   * @private\n   */\n /* static */ function &_current() {\n   $current =& Textile::_current_store($null = NULL);\n   return $current[0];\n } // function _current\n} // class Textile\n\n/**\n * Brad Choate's mttextile Movable Type plugin adds some additional\n * functionality to the Textile.pm Perl module. This includes optional\n * \"SmartyPants\" processing of text to produce smart quotes, dashes,\n * etc., code colorizing using Beautifier, and some special lookup\n * links (imdb, google, dict, and amazon). The @c MTLikeTextile class\n * is a subclass of @c Textile that provides an MT-like implementation\n * of Textile to produce results similar to that of the mttextile\n * plugin. Currently only the SmartyPants and special lookup links are\n * implemented.\n *\n * Using the @c MTLikeTextile class is exactly the same as using @c\n * Textile. Simply use <code>$textile = new MTLikeTextile;</code>\n * instead of <code>$textile = new Textile;</code> to create a Textile\n * object.  This will enable the special lookup links.  To enable\n * SmartyPants processing, you must install the SmartyPants-PHP\n * implementation available at\n * <a\n * href=\"http://monauraljerk.org/smartypants-php/\">http://monauraljerk.org/smartypants-php/</a>\n * and include the\n * SmartyPants-PHP.inc file.\n *\n * <pre><code>\n * include_once(\"Textile.php\");\n * include_once(\"SmartyPants-PHP.inc\");\n * $text = \\<\\<\\<EOT\n * h1. Heading\n *\n * A _simple_ demonstration of Textile markup.\n *\n * * One\n * * Two\n * * Three\n *\n * \"More information\":http://www.textism.com/tools/textile is available.\n * EOT;\n *\n * $textile = new MTLikeTextile;\n * $html = $textile->process($text);\n * print $html;\n * </code></pre>\n *\n * @brief A Textile implementation providing additional\n *        Movable-Type-like formatting to produce results similar to\n *        the mttextile plugin.\n *\n * @author Jim Riggs \\<textile at jimandlisa dot com\\>\n */\nclass MTLikeTextile extends Textile {\n  /**\n   * Instantiates a new MTLikeTextile object. Optional options\n   * can be passed to initialize the object. Attributes for the\n   * options key are the same as the get/set method names\n   * documented here.\n   *\n   * @param $options The @c array specifying the options to use for\n   *        this object.\n   *\n   * @public\n   */\n  function MTLikeTextile($options = array()) {\n    parent::Textile($options);\n  } // function MTLikeTextile\n\n  /**\n   * @private\n   */\n  function process_quotes($str) {\n    if (!$this->options['do_quotes'] || !function_exists('SmartyPants')) {\n      return $str;\n    }\n\n    return SmartyPants($str, $this->options['smarty_mode']);\n  } // function process_quotes\n\n  /**\n   * @private\n   */\n  function format_url($args) {\n    $url = ($args['url'] ? $args['url'] : '');\n\n    if (preg_match('/^(imdb|google|dict|amazon)(:(.+))?$/x', $url, $matches)) {\n      $term = $matches[3];\n      $term = ($term ? $term : strip_tags($args['linktext']));\n\n      switch ($matches[1]) {\n        case 'imdb':\n          $args['url'] = 'http://www.imdb.com/Find?for=' . $term;\n          break;\n\n        case 'google':\n          $args['url'] = 'http://www.google.com/search?q=' . $term;\n          break;\n\n        case 'dict':\n          $args['url'] = 'http://www.dictionary.com/search?q=' . $term;\n          break;\n\n        case 'amazon':\n          $args['url'] = 'http://www.amazon.com/exec/obidos/external-search?index=blended&keyword=' . $term;\n          break;\n      }\n    }\n\n    return parent::format_url($args);\n  } // function format_url\n} // class MTLikeTextile\n\n/**\n * @mainpage\n * Textile - A Humane Web Text Generator.\n *\n * @section synopsis SYNOPSIS\n *\n * <pre><code>\n * include_once(\"Textile.php\");\n * $text = \\<\\<\\<EOT\n * h1. Heading\n *\n * A _simple_ demonstration of Textile markup.\n *\n * * One\n * * Two\n * * Three\n *\n * \"More information\":http://www.textism.com/tools/textile is available.\n * EOT;\n *\n * $textile = new Textile;\n * $html = $textile->process($text);\n * print $html;\n * </code></pre>\n *\n * @section abstract ABSTRACT\n *\n * Textile.php is a PHP-based implementation of Dean Allen's Textile\n * syntax. Textile is shorthand for doing common formatting tasks.\n *\n * @section syntax SYNTAX\n *\n * Textile processes text in units of blocks and lines.\n * A block might also be considered a paragraph, since blocks\n * are separated from one another by a blank line. Blocks\n * can begin with a signature that helps identify the rest\n * of the block content. Block signatures include:\n *\n * <ul>\n *\n * <li><b>p</b>\n *\n * A paragraph block. This is the default signature if no\n * signature is explicitly given. Paragraphs are formatted\n * with all the inline rules (see inline formatting) and\n * each line receives the appropriate markup rules for\n * the flavor of HTML in use. For example, newlines for XHTML\n * content receive a \\<br /\\> tag at the end of the line\n * (with the exception of the last line in the paragraph).\n * Paragraph blocks are enclosed in a \\<p\\> tag.</li>\n *\n * <li><b>pre</b>\n *\n * A pre-formatted block of text. Textile will not add any\n * HTML tags for individual lines. Whitespace is also preserved.\n * \n * Note that within a \"pre\" block, \\< and \\> are\n * translated into HTML entities automatically.</li>\n *\n * <li><b>bc</b>\n *\n * A \"bc\" signature is short for \"block code\", which implies\n * a preformatted section like the 'pre' block, but it also\n * gets a \\<code\\> tag (or for XHTML 2, a \\<blockcode\\>\n * tag is used instead).\n * \n * Note that within a \"bc\" block, \\< and \\> are\n * translated into HTML entities automatically.</li>\n *\n * <li><b>table</b>\n *\n * For composing HTML tables. See the \"TABLES\" section for more\n * information.</li>\n *\n * <li><b>bq</b>\n *\n * A \"bq\" signature is short for \"block quote\". Paragraph text\n * formatting is applied to these blocks and they are enclosed\n * in a \\<blockquote\\> tag as well as \\<p\\> tags\n * within.</li>\n *\n * <li><b>h1, h2, h3, h4, h5, h6</b>\n *\n * Headline signatures that produce \\<h1\\>, etc. tags.\n * You can adjust the relative output of these using the\n * head_offset attribute.</li>\n *\n * <li><b>clear</b>\n *\n * A 'clear' signature is simply used to indicate that the next\n * block should emit a CSS style attribute that clears any\n * floating elements. The default behavior is to clear \"both\",\n * but you can use the left (\\< or right \\>) alignment\n * characters to indicate which side to clear.</li>\n *\n * <li><b>dl</b>\n *\n * A \"dl\" signature is short for \"definition list\". See the\n * \"LISTS\" section for more information.</li>\n *\n * <li><b>fn</b>\n *\n * A \"fn\" signature is short for \"footnote\". You add a number\n * following the \"fn\" keyword to number the footnote. Footnotes\n * are output as paragraph tags but are given a special CSS\n * class name which can be used to style them as you see fit.</li>\n *\n * </ul>\n *\n * All signatures should end with a period and be followed\n * with a space. Inbetween the signature and the period, you\n * may use several parameters to further customize the block.\n * These include:\n *\n * <ul>\n *\n * <li><b><code>{style rule}</code></b>\n *\n * A CSS style rule. Style rules can span multiple lines.</li>\n *\n * <li><b><code>[ll]</code></b>\n *\n * A language identifier (for a \"lang\" attribute).</li>\n *\n * <li><b><code>(class)</code> or <code>(#id)</code> or <code>(class#id)</code></b>\n *\n * For CSS class and id attributes.</li>\n *\n * <li><b><code>\\></code>, <code>\\<</code>, <code>=</code>, <code>\\<\\></code></b>\n *\n * Modifier characters for alignment. Right-justification, left-justification,\n * centered, and full-justification.</li>\n *\n * <li><b><code>(</code> (one or more)</b>\n *\n * Adds padding on the left. 1em per \"(\" character is applied.\n * When combined with the align-left or align-right modifier,\n * it makes the block float.</li>\n *\n * <li><b><code>)</code> (one or more)</b>\n *\n * Adds padding on the right. 1em per \")\" character is applied.\n * When combined with the align-left or align-right modifier,\n * it makes the block float.</li>\n *\n * <li><b><code>|filter|</code> or <code>|filter|filter|filter|</code></b>\n *\n * A filter may be invoked to further format the text for this\n * signature. If one or more filters are identified, the text\n * will be processed first using the filters and then by\n * Textile's own block formatting rules.</li>\n *\n * </ul>\n *\n * @subsection extendedblocks Extended Blocks\n *\n * Normally, a block ends with the first blank line encountered.\n * However, there are situations where you may want a block to continue\n * for multiple paragraphs of text. To cause a given block signature\n * to stay active, use two periods in your signature instead of one.\n * This will tell Textile to keep processing using that signature\n * until it hits the next signature is found.\n *\n * For example:\n * <pre>\n *     bq.. This is paragraph one of a block quote.\n *\n *     This is paragraph two of a block quote.\n *\n *     p. Now we're back to a regular paragraph.\n * </pre>\n * You can apply this technique to any signature (although for\n * some it doesn't make sense, like \"h1\" for example). This is\n * especially useful for \"bc\" blocks where your code may\n * have many blank lines scattered through it.\n *\n * @subsection escaping Escaping\n *\n * Sometimes you want Textile to just get out of the way and\n * let you put some regular HTML markup in your document. You\n * can disable Textile formatting for a given block using the '=='\n * escape mechanism:\n * <pre>\n *     p. Regular paragraph\n *\n *     ==\n *     Escaped portion -- will not be formatted\n *     by Textile at all\n *     ==\n *\n *     p. Back to normal.\n * </pre>\n * You can also use this technique within a Textile block,\n * temporarily disabling the inline formatting functions:\n * <pre>\n *     p. This is ==*a test*== of escaping.\n * </pre>\n * @subsection inlineformatting Inline Formatting\n *\n * Formatting within a block of text is covered by the \"inline\"\n * formatting rules. These operators must be placed up against\n * text/punctuation to be recognized. These include:\n *\n * <ul>\n *\n * <li><b><code>*strong*</code></b>\n *\n * Translates into \\<strong\\>strong\\</strong\\>.</li>\n *\n * <li><b>_emphasis_</b>\n *\n * Translates into \\<em\\>emphasis\\</em\\>.</li>\n *\n * <li><b><code>**bold**</code></b>\n *\n * Translates into \\<b\\>bold\\</b\\>.</li>\n *\n * <li><b><code>__italics__</code></b>\n *\n * Translates into \\<i\\>italics\\</i\\>.</li>\n *\n * <li><b><code>++bigger++</code></b>\n *\n * Translates into \\<big\\>bigger\\</big\\>.</li>\n *\n * <li><b><code>--smaller--</code></b>\n *\n * Translates into: \\<small\\>smaller\\</small\\>.</li>\n *\n * <li><b><code>-deleted text-</code></b>\n *\n * Translates into \\<del\\>deleted text\\</del\\>.</li>\n *\n * <li><b><code>+inserted text+</code></b>\n *\n * Translates into \\<ins\\>inserted text\\</ins\\>.</li>\n *\n * <li><b><code>^superscript^</code></b>\n *\n * Translates into \\<sup\\>superscript\\</sup\\>.</li>\n *\n * <li><b><code>~subscript~</code></b>\n *\n * Translates into \\<sub\\>subscript\\</sub\\>.</li>\n *\n * <li><b><code>\\%span\\%</code></b>\n *\n * Translates into \\<span\\>span\\</span\\>.</li>\n *\n * <li><b><code>\\@code\\@</code></b>\n *\n * Translates into \\<code\\>code\\</code\\>. Note\n * that within a '\\@...\\@' section, \\< and \\> are\n * translated into HTML entities automatically.</li>\n *\n * </ul>\n *\n * Inline formatting operators accept the following modifiers:\n *\n * <ul>\n *\n * <li><b><code>{style rule}</code></b>\n *\n * A CSS style rule.</li>\n *\n * <li><b><code>[ll]</code></b>\n *\n * A language identifier (for a \"lang\" attribute).</li>\n *\n * <li><b><code>(class)</code> or <code>(#id)</code> or <code>(class#id)</code></b>\n *\n * For CSS class and id attributes.</li>\n *\n * </ul>\n *\n * @subsubsection examples Examples\n * <pre>\n *     Textile is *way* cool.\n *\n *     Textile is *_way_* cool.\n * </pre>\n * Now this won't work, because the formatting\n * characters need whitespace before and after\n * to be properly recognized.\n * <pre>\n *     Textile is way c*oo*l.\n * </pre>\n * However, you can supply braces or brackets to\n * further clarify that you want to format, so\n * this would work:\n * <pre>\n *     Textile is way c[*oo*]l.\n * </pre>\n * @subsection footnotes Footnotes\n *\n * You can create footnotes like this:\n * <pre>\n *     And then he went on a long trip[1].\n * </pre>\n * By specifying the brackets with a number inside, Textile will\n * recognize that as a footnote marker. It will replace that with\n * a construct like this:\n * <pre>\n *     And then he went on a long\n *     trip<sup class=\"footnote\"><a href=\"#fn1\">1</a></sup>\n * </pre>\n * To supply the content of the footnote, place it at the end of your\n * document using a \"fn\" block signature:\n * <pre>\n *     fn1. And there was much rejoicing.\n * </pre>\n * Which creates a paragraph that looks like this:\n * <pre>\n *     <p class=\"footnote\" id=\"fn1\"><sup>1</sup> And there was\n *     much rejoicing.</p>\n * </pre>\n * @subsection links Links\n *\n * Textile defines a shorthand for formatting hyperlinks.\n * The format looks like this:\n * <pre>\n *     \"Text to display\":http://example.com\n * </pre>\n * In addition to this, you can add 'title' text to your link:\n * <pre>\n *     \"Text to display (Title text)\":http://example.com\n * </pre>\n * The URL portion of the link supports relative paths as well\n * as other protocols like ftp, mailto, news, telnet, etc.\n * <pre>\n *     \"E-mail me please\":mailto:someone\\@example.com\n * </pre>\n * You can also use single quotes instead of double-quotes if\n * you prefer. As with the inline formatting rules, a hyperlink\n * must be surrounded by whitespace to be recognized (an\n * exception to this is common punctuation which can reside\n * at the end of the URL). If you have to place a URL next to\n * some other text, use the bracket or brace trick to do that:\n * <pre>\n *     You[\"gotta\":http://example.com]seethis!\n * </pre>\n * Textile supports an alternate way to compose links. You can\n * optionally create a lookup list of links and refer to them\n * separately. To do this, place one or more links in a block\n * of it's own (it can be anywhere within your document):\n * <pre>\n *     [excom]http://example.com\n *     [exorg]http://example.org\n * </pre>\n * For a list like this, the text in the square brackets is\n * used to uniquely identify the link given. To refer to that\n * link, you would specify it like this:\n * <pre>\n *     \"Text to display\":excom\n * </pre>\n * Once you've defined your link lookup table, you can use\n * the identifiers any number of times.\n *\n * @subsection images Images\n *\n * Images are identified by the following pattern:\n * <pre>\n *     !/path/to/image!\n * </pre>\n * Image attributes may also be specified:\n * <pre>\n *     !/path/to/image 10x20!\n * </pre>\n * Which will render an image 10 pixels wide and 20 pixels high.\n * Another way to indicate width and height:\n * <pre>\n *     !/path/to/image 10w 20h!\n * </pre>\n * You may also redimension the image using a percentage.\n * <pre>\n *     !/path/to/image 20%x40%!\n * </pre>\n * Which will render the image at 20% of it's regular width\n * and 40% of it's regular height.\n *\n * Or specify one percentage to resize proprotionately:\n * <pre>\n *     !/path/to/image 20%!\n * </pre>\n * Alt text can be given as well:\n * <pre>\n *     !/path/to/image (Alt text)!\n * </pre>\n * The path of the image may refer to a locally hosted image or\n * can be a full URL.\n *\n * You can also use the following modifiers after the opening '!'\n * character:\n *\n * <ul>\n *\n * <li><b><code>\\<</code></b>\n *\n * Align the image to the left (causes the image to float if\n * CSS options are enabled).</li>\n *\n * <li><b><code>\\></code></b>\n *\n * Align the image to the right (causes the image to float if\n * CSS options are enabled).</li>\n *\n * <li><b><code>-</code> (dash)</b>\n *\n * Aligns the image to the middle.</li>\n *\n * <li><b><code>^</code></b>\n *\n * Aligns the image to the top.</li>\n *\n * <li><b><code>~</code> (tilde)</b>\n *\n * Aligns the image to the bottom.</li>\n *\n * <li><b><code>{style rule}</code></b>\n *\n * Applies a CSS style rule to the image.</li>\n *\n * <li><b><code>(class)</code> or <code>(#id)</code> or <code>(class#id)</code></b>\n *\n * Applies a CSS class and/or id to the image.</li>\n *\n * <li><b><code>(</code> (one or more)</b>\n *\n * Pads 1em on the left for each '(' character.</li>\n *\n * <li><b><code>)</code> (one or more)</b>\n *\n * Pads 1em on the right for each ')' character.</li>\n *\n * </ul>\n *\n * @subsection characterreplacements Character Replacements\n *\n * A few simple, common symbols are automatically replaced:\n * <pre>\n *     (c)\n *     (r)\n *     (tm)\n * </pre>\n * In addition to these, there are a whole set of character\n * macros that are defined by default. All macros are enclosed\n * in curly braces. These include:\n * <pre>\n *     {c|} or {|c} cent sign\n *     {L-} or {-L} pound sign\n *     {Y=} or {=Y} yen sign\n * </pre>\n * Many of these macros can be guessed. For example:\n * <pre>\n *     {A'} or {'A}\n *     {a\"} or {\"a}\n *     {1/4}\n *     {*}\n *     {:)}\n *     {:(}\n * </pre>\n * @subsection lists Lists\n *\n * Textile also supports ordered and unordered lists.\n * You simply place an asterisk or pound sign, followed\n * with a space at the start of your lines.\n *\n * Simple lists:\n * <pre>\n *     * one\n *     * two\n *     * three\n * </pre>\n * Multi-level lists:\n * <pre>\n *     * one\n *     ** one A\n *     ** one B\n *     *** one B1\n *     * two\n *     ** two A\n *     ** two B\n *     * three\n * </pre>\n * Ordered lists:\n * <pre>\n *     # one\n *     # two\n *     # three\n * </pre>\n * Styling lists:\n * <pre>\n *     (class#id)* one\n *     * two\n *     * three\n * </pre>\n * The above sets the class and id attributes for the \\<ul\\>\n * tag.\n * <pre>\n *     *(class#id) one\n *     * two\n *     * three\n * </pre>\n * The above sets the class and id attributes for the first \\<li\\>\n * tag.\n *\n * Definition lists:\n * <pre>\n *     dl. textile:a cloth, especially one manufactured by weaving\n *     or knitting; a fabric\n *     format:the arrangement of data for storage or display.\n * </pre>\n * Note that there is no space between the term and definition. The\n * term must be at the start of the line (or following the \"dl\"\n * signature as shown above).\n *\n * @subsection tables Tables\n *\n * Textile supports tables. Tables must be in their own block and\n * must have pipe characters delimiting the columns. An optional\n * block signature of \"table\" may be used, usually for applying\n * style, class, id or other options to the table element itself.\n *\n * From the simple:\n * <pre>\n *     |a|b|c|\n *     |1|2|3|\n * </pre>\n * To the complex:\n * <pre>\n *     table(fig). {color:red}_|Top|Row|\n *     {color:blue}|/2. Second|Row|\n *     |_{color:green}. Last|\n * </pre>\n * Modifiers can be specified for the table signature itself,\n * for a table row (prior to the first '|' character) and\n * for any cell (following the '|' for that cell). Note that for\n * cells, a period followed with a space must be placed after\n * any modifiers to distinguish the modifier from the cell content.\n *\n * Modifiers allowed are:\n *\n * <ul>\n *\n * <li><b><code>{style rule}</code></b>\n *\n * A CSS style rule.</li>\n *\n * <li><b><code>(class)</code> or <code>(#id)</code> or <code>(class#id)</code></b>\n *\n * A CSS class and/or id attribute.</li>\n *\n * <li><b><code>(</code> (one or more)</b>\n *\n * Adds 1em of padding to the left for each '(' character.</li>\n *\n * <li><b><code>)</code> (one or more)</b>\n *\n * Adds 1em of padding to the right for each ')' character.</li>\n *\n * <li><b><code>\\<</code></b>\n *\n * Aligns to the left (floats to left for tables if combined with the\n * ')' modifier).</li>\n *\n * <li><b><code>\\></code></b>\n *\n * Aligns to the right (floats to right for tables if combined with\n * the '(' modifier).</li>\n *\n * <li><b><code>=</code></b>\n *\n * Aligns to center (sets left, right margins to 'auto' for tables).</li>\n *\n * <li><b><code>\\<\\></code></b>\n *\n * For cells only. Justifies text.</li>\n *\n * <li><b><code>^</code></b>\n *\n * For rows and cells only. Aligns to the top.</li>\n *\n * <li><b><code>~</code> (tilde)</b>\n *\n * For rows and cells only. Aligns to the bottom.</li>\n *\n * <li><b><code>_</code> (underscore)</b>\n *\n * Can be applied to a table row or cell to indicate a header\n * row or cell.</li>\n *\n * <li><b><code>\\\\2</code> or <code>\\\\3</code> or <code>\\\\4</code>, etc.</b>\n *\n * Used within cells to indicate a colspan of 2, 3, 4, etc. columns.\n * When you see \"\\\\\", think \"push forward\".</li>\n *\n * <li><b><code>/2</code> or <code>/3</code> or <code>/4</code>, etc.</b>\n *\n * Used within cells to indicate a rowspan of 2, 3, 4, etc. rows.\n * When you see \"/\", think \"push downward\".</li>\n *\n * </ul>\n *\n * When a cell is identified as a header cell and an alignment\n * is specified, that becomes the default alignment for\n * cells below it. You can always override this behavior by\n * specifying an alignment for one of the lower cells.\n *\n * @subsection cssnotes CSS Notes\n *\n * When CSS is enabled (and it is by default), CSS class names\n * are automatically applied in certain situations.\n *\n * <ul>\n *\n * <li>Aligning a block or span or other element to\n * left, right, etc.\n *\n * \"left\" for left justified, \"right\" for right justified,\n * \"center\" for centered text, \"justify\" for full-justified\n * text.</li>\n *\n * <li>Aligning an image to the top or bottom\n *\n * \"top\" for top alignment, \"bottom\" for bottom alignment,\n * \"middle\" for middle alignment.</li>\n *\n * <li>Footnotes\n *\n * \"footnote\" is applied to the paragraph tag for the\n * footnote text itself. An id of \"fn\" plus the footnote\n * number is placed on the paragraph for the footnote as\n * well. For the footnote superscript tag, a class of\n * \"footnote\" is used.</li>\n *\n * <li>Capped text\n *\n * For a series of characters that are uppercased, a\n * span is placed around them with a class of \"caps\".</li>\n *\n * </ul>\n *\n * @subsection miscellaneous Miscellaneous\n *\n * Textile tries to do it's very best to ensure proper XHTML\n * syntax. It will even attempt to fix errors you may introduce\n * writing in HTML yourself. Unescaped '&' characters within\n * URLs will be properly escaped. Singlet tags such as br, img\n * and hr are checked for the '/' terminator (and it's added\n * if necessary). The best way to make sure you produce valid\n * XHTML with Textile is to not use any HTML markup at all--\n * use the Textile syntax and let it produce the markup for you.\n *\n * @section license LICENSE\n *\n * Text::Textile is licensed under the same terms as Perl\n * itself. Textile.php is licensed under the terms of the GNU General\n * Public License.\n *\n * @section authorandcopyright AUTHOR & COPYRIGHT\n *\n * Text::Textile was written by Brad Choate, \\<brad at bradchoate dot com\\>.\n * It is an adaptation of Textile, developed by Dean Allen of Textism.com.\n *\n * Textile.php is a PHP port of Brad Choate's Text::Textile\n * (Textile.pm) Perl module.\n *\n * Textile.php was ported by Jim Riggs \\<textile at jimandlissa dot\n * com\\>. Great care has been taken to leave the Perl code in much the\n * same form as Textile.pm. While changes were required due to\n * syntactical differences between Perl and PHP, much of the code was\n * left intact (even if alternative syntax or code optimizations could\n * have been made in PHP), even to the point where one can compare\n * functions/subroutines side by side between the two implementations.\n * This has been done to ensure compatibility, reduce the possibility\n * of introducing errors, and simplify maintainance as one version or\n * the other is updated.\n *\n * @author Jim Riggs \\<textile at jimandlissa dot com\\>\n * @author Brad Choate \\<brad at bradchoate dot com\\>\n * @copyright Copyright &copy; 2004 Jim Riggs and Brad Choate\n * @version @(#) $Id: Textile.php,v 1.13 2005/03/21 15:26:55 jhriggs Exp $\n */\n?>\n"
  },
  {
    "path": "TinyMCE/Plugin.php",
    "content": "<?php\n/**\n * 集成tinyMCE编辑器\n * \n * @package tinyMCE Editor \n * @author qining\n * @version 1.0.1\n * @dependence 9.9.2-*\n * @link http://typecho.org\n */\nclass TinyMCE_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('admin/write-post.php')->richEditor = array('TinyMCE_Plugin', 'render');\n        Typecho_Plugin::factory('admin/write-page.php')->richEditor = array('TinyMCE_Plugin', 'render');\n        \n        //去除段落\n        Typecho_Plugin::factory('Widget_Contents_Post_Edit')->write = array('TinyMCE_Plugin', 'filter');\n        Typecho_Plugin::factory('Widget_Contents_Page_Edit')->write = array('TinyMCE_Plugin', 'filter');\n        \n        Helper::addPanel(0, 'TinyMCE/tiny_mce/langs.php','', '', 'contributor');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate()\n    {\n        Helper::removePanel(0, 'TinyMCE/tiny_mce/langs.php');\n    }\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 去除段落\n     * \n     * @access public\n     * @param array $post 数据结构体\n     * @return array\n     */\n    public static function filter($post)\n    {\n        $post['text'] = Typecho_Common::removeParagraph($post['text']);\n        return $post;\n    }\n    \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function render($post)\n    {\n        $options = Helper::options();\n        $js = Typecho_Common::url('TinyMCE/tiny_mce/tiny_mce.js', $options->pluginUrl);\n        $langs = Typecho_Common::url('extending.php?panel=TinyMCE/tiny_mce/langs.php', $options->adminUrl);\n        echo \"<script type=\\\"text/javascript\\\" src=\\\"{$js}\\\"></script>\n<script type=\\\"text/javascript\\\" src=\\\"{$langs}\\\"></script>\n<script type=\\\"text/javascript\\\">\n    var insertImageToEditor = function (title, url, link) {\n        tinyMCE.activeEditor.execCommand('mceInsertContent', false,\n        '<a href=\\\"' + link + '\\\" title=\\\"' + title + '\\\"><img src=\\\"' + url + '\\\" alt=\\\"' + title + '\\\" /></a>');\n        new Fx.Scroll(window).toElement($(document).getElement('.mceEditor'));\n    };\n    \n    var insertLinkToEditor = function (title, url, link) {\n        tinyMCE.activeEditor.execCommand('mceInsertContent', false, '<a href=\\\"' + url + '\\\" title=\\\"' + title + '\\\">' + title + '</a>');\n        new Fx.Scroll(window).toElement($(document).getElement('.mceEditor'));\n    };\n\n    //自动保存\n    var autoSave;\n    \n    tinyMCE.init({\n    // General options\n    mode : 'exact',\n    elements : 'text',\n    theme : 'advanced',\n    skin : 'typecho',\n    plugins : 'safari,morebreak,inlinepopups,media,coder',\n    extended_valid_elements : 'code[*],pre[*],script[*],iframe[*]',\n    \n    init_instance_callback : function(ed) {\n        \n        ed.setContent(\\\"\" . str_replace(array(\"\\n\", \"\\r\"), array(\"\\\\n\", \"\"), addslashes($post->content)) . \"\\\");\n        \"\n        . ($options->autoSave ? \n        \"autoSave = new Typecho.autoSave($('text').getParent('form').getProperty('action'), {\n            time: 60,\n            getContentHandle: tinyMCE.activeEditor.getContent.bind(ed),\n            messageElement: 'auto-save-message',\n            leaveMessage: '\" . _t('您的内容尚未保存, 是否离开此页面?') . \"',\n            form: $('text').getParent('form')\n        });\" : \"\") .\n        \n        \"\n    },\n    \n    onchange_callback: function (inst) {\n        if ('undefined' != typeof(autoSave)) {\n            autoSave.onContentChange();\n        }\n    },\n    \n    save_callback: function (element_id, html, body) {\n        if ('undefined' != typeof(autoSave)) {\n            autoSave.saveRev = autoSave.rev;\n        }\n        \n        return html;\n    },\n    \n    // Theme options\n    theme_advanced_buttons1 : 'bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,blockquote,|,link,unlink,image,media,|,forecolor,backcolor,|,morebreak,code',\n    theme_advanced_buttons2 : '',\n    theme_advanced_buttons3 : '',\n    theme_advanced_toolbar_location : 'top',\n    theme_advanced_toolbar_align : 'left',\n    convert_urls : false,\n    language : 'typecho'\n});\n</script>\";\n    }\n}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/langs/typecho.js",
    "content": "/** nothing to do, just sleep...Zzz... */\n"
  },
  {
    "path": "TinyMCE/tiny_mce/langs.php",
    "content": "<?php\nif (!defined('__TYPECHO_ROOT_DIR__')) {\n    exit;\n}\n\n$response->setContentType('text/javascript');\n?>\n\ntinyMCE.addI18n({typecho:{\ncommon:{\nedit_confirm:\"<?php _e('在这个文本域启用所见即所得模式？'); ?>\",\napply:\"<?php _e('应用'); ?>\",\ninsert:\"<?php _e('插入'); ?>\",\nupdate:\"<?php _e('更新'); ?>\",\ncancel:\"<?php _e('取消'); ?>\",\nclose:\"<?php _e('关闭'); ?>\",\nbrowse:\"<?php _e('浏览'); ?>\",\nclass_name:\"<?php _e('类别'); ?>\",\nnot_set:\"<?php _e('-- 未设定 --'); ?>\",\nclipboard_msg:\"<?php _e('贴上复制、剪下和贴上功能在 Mozilla 和 Firefox 中无法使用。\\n你需要了解更多相关信息吗？'); ?>\",\nclipboard_no_support:\"<?php _e('目前你的浏览器无法支持，请用键盘快捷键。'); ?>\",\npopup_blocked:\"<?php _e('抱歉，快捷功能在你的系统上被封锁，使程序无法正常使用，你需要暂时解除快捷封锁，使工具能正常使用。'); ?>\",\ninvalid_data:\"<?php _e('错误：输入无效的值，以红色字表示。'); ?>\",\nmore_colors:\"<?php _e('其它更多颜色'); ?>\"\n},\ncontextmenu:{\nalign:\"<?php _e('对齐方式'); ?>\",\nleft:\"<?php _e('居左对齐'); ?>\",\ncenter:\"<?php _e('居中对齐'); ?>\",\nright:\"<?php _e('居右对齐'); ?>\",\nfull:\"<?php _e('左右对齐'); ?>\"\n},\ninsertdatetime:{\ndate_fmt:\"<?php _e('%Y-%m-%d'); ?>\",\ntime_fmt:\"<?php _e('%H:%M:%S'); ?>\",\ninsertdate_desc:\"<?php _e('插入今天日期'); ?>\",\ninserttime_desc:\"<?php _e('插入现在时间'); ?>\",\nmonths_long:\"<?php _e('一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月'); ?>\",\nmonths_short:\"<?php _e('1月,2月,3月,4月,5月,6月,7月,8月,9月,10月,11月,12月'); ?>\",\nday_long:\"<?php _e('星期日,星期一,星期二,星期三,星期四,星期五,星期六,星期日'); ?>\",\nday_short:\"<?php _e('周日,周一,周二,周三,周四,周五,周六,周日'); ?>\"\n},\nprint:{\nprint_desc:\"<?php _e('打印'); ?>\"\n},\npreview:{\npreview_desc:\"<?php _e('预览'); ?>\"\n},\ndirectionality:{\nltr_desc:\"<?php _e('文字从左到右'); ?>\",\nrtl_desc:\"<?php _e('文字从右到左'); ?>\"\n},\nlayer:{\ninsertlayer_desc:\"<?php _e('插入层'); ?>\",\nforward_desc:\"<?php _e('前移'); ?>\",\nbackward_desc:\"<?php _e('后移'); ?>\",\nabsolute_desc:\"<?php _e('切换绝对寻址'); ?>\",\ncontent:\"<?php _e('新增层..'); ?>\"\n},\nsave:{\nsave_desc:\"<?php _e('保存'); ?>\",\ncancel_desc:\"<?php _e('取消所有变更'); ?>\"\n},\nnonbreaking:{\nnonbreaking_desc:\"<?php _e('插入非截断的空格符'); ?>\"\n},\niespell:{\niespell_desc:\"<?php _e('执行拼写检查'); ?>\",\ndownload:\"<?php _e('侦测不到ieSpell套件，是否立即安装？'); ?>\"\n},\nadvhr:{\nadvhr_desc:\"<?php _e('水平分隔线'); ?>\"\n},\nemotions:{\nemotions_desc:\"<?php _e('表情'); ?>\"\n},\nsearchreplace:{\nsearch_desc:\"<?php _e('查找'); ?>\",\nreplace_desc:\"<?php _e('查找/替换'); ?>\"\n},\nadvimage:{\nimage_desc:\"<?php _e('插入/编辑 图片'); ?>\"\n},\nadvlink:{\nlink_desc:\"<?php _e('插入/编辑 链接'); ?>\"\n},\nxhtmlxtras:{\ncite_desc:\"<?php _e('引用'); ?>\",\nabbr_desc:\"<?php _e('缩写'); ?>\",\nacronym_desc:\"<?php _e('首字母缩写'); ?>\",\ndel_desc:\"<?php _e('删除'); ?>\",\nins_desc:\"<?php _e('插入'); ?>\",\nattribs_desc:\"<?php _e('插入/编辑 属性'); ?>\"\n},\nstyle:{\ndesc:\"<?php _e('编辑 CSS 样式'); ?>\"\n},\npaste:{\npaste_text_desc:\"<?php _e('以纯文字格式粘贴'); ?>\",\npaste_word_desc:\"<?php _e('从Word粘贴'); ?>\",\nselectall_desc:\"<?php _e('全选'); ?>\"\n},\npaste_dlg:{\ntext_title:\"<?php _e('用 Ctrl+V 组合键将文字贴入窗口中。'); ?>\",\ntext_linebreaks:\"<?php _e('保留换行符号'); ?>\",\nword_title:\"<?php _e('用 Ctrl+V 组合键将文字贴入窗口中。'); ?>\"\n},\ntable:{\ndesc:\"<?php _e('插入新表格'); ?>\",\nrow_before_desc:\"<?php _e('插入列于前'); ?>\",\nrow_after_desc:\"<?php _e('插入列于后'); ?>\",\ndelete_row_desc:\"<?php _e('删除本列'); ?>\",\ncol_before_desc:\"<?php _e('插入栏于前'); ?>\",\ncol_after_desc:\"<?php _e('插入栏于后'); ?>\",\ndelete_col_desc:\"<?php _e('删除本栏'); ?>\",\nsplit_cells_desc:\"<?php _e('分割储存格'); ?>\",\nmerge_cells_desc:\"<?php _e('合并储存格'); ?>\",\nrow_desc:\"<?php _e('表格列 属性'); ?>\",\ncell_desc:\"<?php _e('储存格 属性'); ?>\",\nprops_desc:\"<?php _e('表格 属性'); ?>\",\npaste_row_before_desc:\"<?php _e('贴入列于前'); ?>\",\npaste_row_after_desc:\"<?php _e('贴入列于后'); ?>\",\ncut_row_desc:\"<?php _e('剪切此列'); ?>\",\ncopy_row_desc:\"<?php _e('复制此列'); ?>\",\ndel:\"<?php _e('删除表格'); ?>\",\nrow:\"<?php _e('列'); ?>\",\ncol:\"<?php _e('栏'); ?>\",\ncell:\"<?php _e('储存格'); ?>\"\n},\nautosave:{\nunload_msg:\"<?php _e('如果离开该页，将导致所有修改全部遗失。'); ?>\"\n},\nfullscreen:{\ndesc:\"<?php _e('切换全屏幕模式'); ?>\"\n},\nmedia:{\ndesc:\"<?php _e('插入/编辑 媒体文件'); ?>\",\nedit:\"<?php _e('编辑 媒体文件'); ?>\"\n},\nfullpage:{\ndesc:\"<?php _e('文档属性'); ?>\"\n},\ntemplate:{\ndesc:\"<?php _e('插入预先定义的模板内容'); ?>\"\n},\nvisualchars:{\ndesc:\"<?php _e('可见控制字符 开/关'); ?>\"\n},\nspellchecker:{\ndesc:\"<?php _e('切换拼写检查'); ?>\",\nmenu:\"<?php _e('拼写检查设定'); ?>\",\nignore_word:\"<?php _e('忽略字'); ?>\",\nignore_words:\"<?php _e('忽略全部'); ?>\",\nlangs:\"<?php _e('语言'); ?>\",\nwait:\"<?php _e('请稍后..'); ?>\",\nsug:\"<?php _e('建议'); ?>\",\nno_sug:\"<?php _e('无建议'); ?>\",\nno_mpell:\"<?php _e('无拼写错误'); ?>\"\n},\nmorebreak:{\ndesc:\"<?php _e('插入摘要分割符'); ?>\"\n}}});\n\ntinyMCE.addI18n('typecho.advanced',{\nstyle_select:\"<?php _e('样式'); ?>\",\nfont_size:\"<?php _e('字体样式'); ?>\",\nfontdefault:\"<?php _e('字体'); ?>\",\nblock:\"<?php _e('格式'); ?>\",\nparagraph:\"<?php _e('段落'); ?>\",\ndiv:\"<?php _e('布局'); ?>\",\naddress:\"<?php _e('地址'); ?>\",\npre:\"<?php _e('原始格式'); ?>\",\nh1:\"<?php _e('标题 1 (H1)'); ?>\",\nh2:\"<?php _e('标题 2 (H2)'); ?>\",\nh3:\"<?php _e('标题 3 (H3)'); ?>\",\nh4:\"<?php _e('标题 4 (H4)'); ?>\",\nh5:\"<?php _e('标题 5 (H5)'); ?>\",\nh6:\"<?php _e('标题 6 (H6)'); ?>\",\nblockquote:\"<?php _e('引用'); ?>\",\ncode:\"<?php _e('代码'); ?>\",\nsamp:\"<?php _e('程序范例'); ?>\",\ndt:\"<?php _e('名词定义'); ?>\",\ndd:\"<?php _e('名词解释'); ?>\",\nbold_desc:\"<?php _e('粗体 (Ctrl+B)'); ?>\",\nitalic_desc:\"<?php _e('斜体 (Ctrl+I)'); ?>\",\nunderline_desc:\"<?php _e('下划线 (Ctrl+U)'); ?>\",\nstriketrough_desc:\"<?php _e('删除线'); ?>\",\njustifyleft_desc:\"<?php _e('居左对齐'); ?>\",\njustifycenter_desc:\"<?php _e('居中对齐'); ?>\",\njustifyright_desc:\"<?php _e('居右对齐'); ?>\",\njustifyfull_desc:\"<?php _e('左右对齐'); ?>\",\nbullist_desc:\"<?php _e('无序列表'); ?>\",\nnumlist_desc:\"<?php _e('有序列表'); ?>\",\noutdent_desc:\"<?php _e('减少缩排'); ?>\",\nindent_desc:\"<?php _e('增加缩排'); ?>\",\nundo_desc:\"<?php _e('撤销 (Ctrl+Z)'); ?>\",\nredo_desc:\"<?php _e('重做 (Ctrl+Y)'); ?>\",\nlink_desc:\"<?php _e('插入/编辑 链接'); ?>\",\nunlink_desc:\"<?php _e('取消链接'); ?>\",\nimage_desc:\"<?php _e('插入/编辑 图片'); ?>\",\ncleanup_desc:\"<?php _e('清除冗余代码'); ?>\",\ncode_desc:\"<?php _e('编辑 HTML 源代码'); ?>\",\nsub_desc:\"<?php _e('下标'); ?>\",\nsup_desc:\"<?php _e('上标'); ?>\",\nhr_desc:\"<?php _e('插入水平分割线'); ?>\",\nremoveformat_desc:\"<?php _e('清除样式'); ?>\",\ncustom1_desc:\"<?php _e('在此输入自定义描述'); ?>\",\nforecolor_desc:\"<?php _e('选择文本前景色'); ?>\",\nbackcolor_desc:\"<?php _e('选择文本背景色'); ?>\",\ncharmap_desc:\"<?php _e('插入自定义符号'); ?>\",\nvisualaid_desc:\"<?php _e('切换可见/隐藏元素'); ?>\",\nanchor_desc:\"<?php _e('插入/编辑 锚点'); ?>\",\ncut_desc:\"<?php _e('剪切 (Ctrl+X)'); ?>\",\ncopy_desc:\"<?php _e('复制 (Ctrl+C)'); ?>\",\npaste_desc:\"<?php _e('粘贴 (Ctrl+V)'); ?>\",\nimage_props_desc:\"<?php _e('图片属性'); ?>\",\nnewdocument_desc:\"<?php _e('新文件'); ?>\",\nhelp_desc:\"<?php _e('帮助'); ?>\",\nblockquote_desc:\"<?php _e('引用'); ?>\",\nclipboard_msg:\"<?php _e('复制/剪切/粘贴功能在 Mozilla 和 Firefox 中无法使用。\\r\\n需要获取更多相关信息？'); ?>\",\npath:\"<?php _e('路径'); ?>\",\nnewdocument:\"<?php _e('你确定要清除所有内容吗？'); ?>\",\ntoolbar_focus:\"<?php _e('移至工具栏 - Alt+Q, 移至编辑器 - Alt-Z, 移至元素路径 - Alt-X'); ?>\",\nmore_colors:\"<?php _e('其它更多颜色'); ?>\",\n\ncolorpicker_delta_height: 30,\nimage_delta_height: 30,\nlink_delta_height: -20,\nlink_delta_width: 10\n});\n\ntinyMCE.addI18n('typecho.advanced_dlg',{\nabout_title:\"<?php _e('关于TinyMCE'); ?>\",\nabout_general:\"<?php _e('关于'); ?>\",\nabout_help:\"<?php _e('帮助'); ?>\",\nabout_license:\"<?php _e('授权'); ?>\",\nabout_plugins:\"<?php _e('插件'); ?>\",\nabout_plugin:\"<?php _e('插件'); ?>\",\nabout_author:\"<?php _e('作者'); ?>\",\nabout_version:\"<?php _e('版本'); ?>\",\nabout_loaded:\"<?php _e('已加载的插件'); ?>\",\nanchor_title:\"<?php _e('插入/编辑 锚点'); ?>\",\nanchor_name:\"<?php _e('锚点名'); ?>\",\ncode_title:\"<?php _e('HTML 源代码编辑器'); ?>\",\ncode_wordwrap:\"<?php _e('自动换行'); ?>\",\ncolorpicker_title:\"<?php _e('选择颜色'); ?>\",\ncolorpicker_picker_tab:\"<?php _e('选色器'); ?>\",\ncolorpicker_picker_title:\"<?php _e('选色器'); ?>\",\ncolorpicker_palette_tab:\"<?php _e('色盘'); ?>\",\ncolorpicker_palette_title:\"<?php _e('色盘颜色'); ?>\",\ncolorpicker_named_tab:\"<?php _e('已指定'); ?>\",\ncolorpicker_named_title:\"<?php _e('已指定颜色'); ?>\",\ncolorpicker_color:\"<?php _e('颜色:'); ?>\",\ncolorpicker_name:\"<?php _e('名称:'); ?>\",\ncharmap_title:\"<?php _e('选择自定义符号'); ?>\",\nimage_title:\"<?php _e('插入/编辑图片'); ?>\",\nimage_src:\"<?php _e('图片地址'); ?>\",\nimage_alt:\"<?php _e('图片描述'); ?>\",\nimage_list:\"<?php _e('图片列表'); ?>\",\nimage_border:\"<?php _e('边框'); ?>\",\nimage_dimensions:\"<?php _e('尺寸'); ?>\",\nimage_vspace:\"<?php _e('垂直间距'); ?>\",\nimage_hspace:\"<?php _e('水平间距'); ?>\",\nimage_align:\"<?php _e('对齐'); ?>\",\nimage_align_baseline:\"<?php _e('基线对齐'); ?>\",\nimage_align_top:\"<?php _e('居上'); ?>\",\nimage_align_middle:\"<?php _e('居中'); ?>\",\nimage_align_bottom:\"<?php _e('居下'); ?>\",\nimage_align_texttop:\"<?php _e('文字上方'); ?>\",\nimage_align_textbottom:\"<?php _e('文字下方'); ?>\",\nimage_align_left:\"<?php _e('居左'); ?>\",\nimage_align_right:\"<?php _e('居右'); ?>\",\nlink_title:\"<?php _e('插入/编辑链接'); ?>\",\nlink_url:\"<?php _e('链接地址'); ?>\",\nlink_target:\"<?php _e('目标'); ?>\",\nlink_target_same:\"<?php _e('在当前窗口打开链接'); ?>\",\nlink_target_blank:\"<?php _e('在新窗口打开链接'); ?>\",\nlink_titlefield:\"<?php _e('标题'); ?>\",\nlink_is_email:\"<?php _e('你输入的URL似乎是一个email地址，是否要加上前辍字 mailto: ?'); ?>\",\nlink_is_external:\"<?php _e('你输入的URL似乎是一个外部链接，是否要加上前辍字 http:// ?'); ?>\",\nlink_list:\"<?php _e('链接列表'); ?>\"\n});\n\ntinyMCE.addI18n('typecho.media_dlg',{\ntitle:\"<?php _e('插入/编辑 媒体文件'); ?>\",\ngeneral:\"<?php _e('常规'); ?>\",\nadvanced:\"<?php _e('高级'); ?>\",\nfile:\"<?php _e('文件/URL'); ?>\",\nlist:\"<?php _e('列表'); ?>\",\nsize:\"<?php _e('尺寸'); ?>\",\npreview:\"<?php _e('预览'); ?>\",\nconstrain_proportions:\"<?php _e('保持比例'); ?>\",\ntype:\"<?php _e('类型'); ?>\",\nid:\"<?php _e('ID'); ?>\",\nname:\"<?php _e('名称'); ?>\",\nclass_name:\"<?php _e('类别'); ?>\",\nvspace:\"<?php _e('垂直间距'); ?>\",\nhspace:\"<?php _e('水平间距'); ?>\",\nplay:\"<?php _e('自动播放'); ?>\",\nloop:\"<?php _e('循环'); ?>\",\nmenu:\"<?php _e('显示菜单'); ?>\",\nquality:\"<?php _e('质量'); ?>\",\nscale:\"<?php _e('缩放'); ?>\",\nalign:\"<?php _e('对齐'); ?>\",\nsalign:\"<?php _e('SAlign'); ?>\",\nwmode:\"<?php _e('WMode'); ?>\",\nbgcolor:\"<?php _e('背景色'); ?>\",\nbase:\"<?php _e('基底'); ?>\",\nflashvars:\"<?php _e('Flash变量'); ?>\",\nliveconnect:\"<?php _e('SWLiveConnect'); ?>\",\nautohref:\"<?php _e('AutoHREF'); ?>\",\ncache:\"<?php _e('缓存'); ?>\",\nhidden:\"<?php _e('隐藏'); ?>\",\ncontroller:\"<?php _e('控制台'); ?>\",\nkioskmode:\"<?php _e('Kiosk 模式'); ?>\",\nplayeveryframe:\"<?php _e('逐帧播放'); ?>\",\ntargetcache:\"<?php _e('目标暂存'); ?>\",\ncorrection:\"<?php _e('修正'); ?>\",\nenablejavascript:\"<?php _e('启用 JavaScript'); ?>\",\nstarttime:\"<?php _e('开始时间'); ?>\",\nendtime:\"<?php _e('结束时间'); ?>\",\nhref:\"<?php _e('Href'); ?>\",\nqtsrcchokespeed:\"<?php _e('Choke速度'); ?>\",\ntarget:\"<?php _e('目标'); ?>\",\nvolume:\"<?php _e('音量'); ?>\",\nautostart:\"<?php _e('自动播放'); ?>\",\nenabled:\"<?php _e('启用'); ?>\",\nfullscreen:\"<?php _e('全屏幕'); ?>\",\ninvokeurls:\"<?php _e('挂用的URLs'); ?>\",\nmute:\"<?php _e('静音'); ?>\",\nstretchtofit:\"<?php _e('缩放至适合大小'); ?>\",\nwindowlessvideo:\"<?php _e('无窗口播放'); ?>\",\nbalance:\"<?php _e('平衡'); ?>\",\nbaseurl:\"<?php _e('基底 网址'); ?>\",\ncaptioningid:\"<?php _e('字幕ID'); ?>\",\ncurrentmarker:\"<?php _e('目前标记'); ?>\",\ncurrentposition:\"<?php _e('当前位置'); ?>\",\ndefaultframe:\"<?php _e('预设帧'); ?>\",\nplaycount:\"<?php _e('播放次数'); ?>\",\nrate:\"<?php _e('码率'); ?>\",\nuimode:\"<?php _e('UI 模式'); ?>\",\nflash_options:\"<?php _e('Flash 选项'); ?>\",\nqt_options:\"<?php _e('Quicktime 选项'); ?>\",\nwmp_options:\"<?php _e('Windows Media Player 选项'); ?>\",\nrmp_options:\"<?php _e('Real Media Player 选项'); ?>\",\nshockwave_options:\"<?php _e('Shockwave 选项'); ?>\",\nautogotourl:\"<?php _e('自动转至 URL'); ?>\",\ncenter:\"<?php _e('居中'); ?>\",\nimagestatus:\"<?php _e('图片状态'); ?>\",\nmaintainaspect:\"<?php _e('维持比例'); ?>\",\nnojava:\"<?php _e('No java'); ?>\",\nprefetch:\"<?php _e('预读'); ?>\",\nshuffle:\"<?php _e('随机'); ?>\",\nconsole:\"<?php _e('控制台'); ?>\",\nnumloop:\"<?php _e('循环次数'); ?>\",\ncontrols:\"<?php _e('控制'); ?>\",\nscriptcallbacks:\"<?php _e('Script回传'); ?>\",\nswstretchstyle:\"<?php _e('缩放样式'); ?>\",\nswstretchhalign:\"<?php _e('缩放至水平对齐'); ?>\",\nswstretchvalign:\"<?php _e('缩放至垂直对齐'); ?>\",\nsound:\"<?php _e('声音'); ?>\",\nprogress:\"<?php _e('进度'); ?>\",\nqtsrc:\"<?php _e('QT Src'); ?>\",\nqt_stream_warn:\"<?php _e('RTSP协议的流资源需要在高级选项中增加QT Src域。 \\n您还要补充一个非流的SRC域..'); ?>\",\nalign_top:\"<?php _e('居顶'); ?>\",\nalign_right:\"<?php _e('居右'); ?>\",\nalign_bottom:\"<?php _e('居底'); ?>\",\nalign_left:\"<?php _e('居左'); ?>\",\nalign_center:\"<?php _e('居中'); ?>\",\nalign_top_left:\"<?php _e('居顶左'); ?>\",\nalign_top_right:\"<?php _e('居顶右'); ?>\",\nalign_bottom_left:\"<?php _e('居底左'); ?>\",\nalign_bottom_right:\"<?php _e('居底右'); ?>\",\nflv_options:\"<?php _e('Flash 视频选项'); ?>\",\nflv_scalemode:\"<?php _e('缩放模式'); ?>\",\nflv_buffer:\"<?php _e('缓冲'); ?>\",\nflv_startimage:\"<?php _e('启动图片'); ?>\",\nflv_starttime:\"<?php _e('启动时间'); ?>\",\nflv_defaultvolume:\"<?php _e('预设音量'); ?>\",\nflv_hiddengui:\"<?php _e('隐藏GUI'); ?>\",\nflv_autostart:\"<?php _e('自动启动'); ?>\",\nflv_loop:\"<?php _e('循环'); ?>\",\nflv_showscalemodes:\"<?php _e('显示缩放模式'); ?>\",\nflv_smoothvideo:\"<?php _e('平滑视图'); ?>\",\nflv_jscallback:\"<?php _e('JS 回传'); ?>\"\n});\n\n/** offset */\ntinyMCE.addI18n('typecho.media',{\n    delta_height:40\n});\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/coder/editor_plugin.js",
    "content": "/**\n * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $\n *\n * @author Moxiecode\n * @copyright Copyright  2004-2008, Moxiecode Systems AB, All rights reserved.\n */\n\n(function() {\n\ttinymce.create('tinymce.plugins.CoderPlugin', {\n\t\tinit : function(ed, url) {\n            \n\t\t\ted.onClick.add(function(ed, e) {\n\t\t\t\te = e.target;\n\n\t\t\t\tif (e.nodeName === 'CODE' || e.nodeName === 'PRE' || e.className.indexOf(\"typecho-plugin\") >= 0)\n\t\t\t\t\ted.selection.select(e);\n\t\t\t});\n\n            \n\t\t\ted.onBeforeSetContent.add(function(ed, o) {\n\t\t\t\t\n                var _replace = function (g, a, b, c) {\n                    \n                    c = c.trim().replace(/( |<|>|\\r\\n|\\r|\\n)/g, function (e) {\n                    \n                        switch (e) {\n                        \n                            case \"<\":\n                                return \"&lt;\";\n                                \n                            case \">\":\n                                return \"&gt;\";\n                            \n                            case \"\\r\\n\":\n                            case \"\\r\":\n                            case \"\\n\":\n                                return '<br />';\n                                \n                            case \" \":\n                                return '&nbsp;';\n                                \n                            default:\n                                return;\n                        \n                        }\n                    \n                    });\n                    \n                    return '<' + a + b + '>' + c + '</' + a + '>';\n                };\n                \n                o.content = o.content.replace(/<(code)([^>]*)>([\\s\\S]*?)<\\/(code)>/ig, _replace);\n                o.content = o.content.replace(/<(pre)([^>]*)>([\\s\\S]*?)<\\/(pre)>/ig, _replace);\n\t\t\t});\n            \n            /*\n\t\t\ted.onPostProcess.add(function(ed, o) {\n\t\t\t\tif (o.get) {\n\t\t\t\t\to.content = o.content.replace(/<textarea([^>]*)>/ig, '<code$1>');\n\t\t\t\t\to.content = o.content.replace(/<\\/textarea>/ig, '</code>');\n                }\n\t\t\t});\n            */\n\t\t},\n\n\t\tgetInfo : function() {\n\t\t\treturn {\n\t\t\t\tlongname : 'Coder',\n\t\t\t\tauthor : 'Typecho Team',\n\t\t\t\tauthorurl : 'http://typecho.org',\n\t\t\t\tinfourl : 'http://typecho.org',\n\t\t\t\tversion : tinymce.majorVersion + \".\" + tinymce.minorVersion\n\t\t\t};\n\t\t}\n\t});\n\n\t// Register plugin\n\ttinymce.PluginManager.add('coder', tinymce.plugins.CoderPlugin);\n})();\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/inlinepopups/editor_plugin.js",
    "content": "(function(){var d=tinymce.DOM,b=tinymce.dom.Element,a=tinymce.dom.Event,e=tinymce.each,c=tinymce.is;tinymce.create(\"tinymce.plugins.InlinePopups\",{init:function(f,g){f.onBeforeRenderUI.add(function(){f.windowManager=new tinymce.InlineWindowManager(f);d.loadCSS(g+\"/skins/\"+(f.settings.inlinepopups_skin||\"clearlooks2\")+\"/window.css\")})},getInfo:function(){return{longname:\"InlinePopups\",author:\"Moxiecode Systems AB\",authorurl:\"http://tinymce.moxiecode.com\",infourl:\"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups\",version:tinymce.majorVersion+\".\"+tinymce.minorVersion}}});tinymce.create(\"tinymce.InlineWindowManager:tinymce.WindowManager\",{InlineWindowManager:function(f){var g=this;g.parent(f);g.zIndex=300000;g.count=0;g.windows={}},open:function(r,j){var y=this,i,k=\"\",q=y.editor,g=0,s=0,h,m,n,o,l,v,x;r=r||{};j=j||{};if(!r.inline){return y.parent(r,j)}if(!r.type){y.bookmark=q.selection.getBookmark(1)}i=d.uniqueId();h=d.getViewPort();r.width=parseInt(r.width||320);r.height=parseInt(r.height||240)+(tinymce.isIE?8:0);r.min_width=parseInt(r.min_width||150);r.min_height=parseInt(r.min_height||100);r.max_width=parseInt(r.max_width||2000);r.max_height=parseInt(r.max_height||2000);r.left=r.left||Math.round(Math.max(h.x,h.x+(h.w/2)-(r.width/2)));r.top=r.top||Math.round(Math.max(h.y,h.y+(h.h/2)-(r.height/2)));r.movable=r.resizable=true;j.mce_width=r.width;j.mce_height=r.height;j.mce_inline=true;j.mce_window_id=i;j.mce_auto_focus=r.auto_focus;y.features=r;y.params=j;y.onOpen.dispatch(y,r,j);if(r.type){k+=\" mceModal\";if(r.type){k+=\" mce\"+r.type.substring(0,1).toUpperCase()+r.type.substring(1)}r.resizable=false}if(r.statusbar){k+=\" mceStatusbar\"}if(r.resizable){k+=\" mceResizable\"}if(r.minimizable){k+=\" mceMinimizable\"}if(r.maximizable){k+=\" mceMaximizable\"}if(r.movable){k+=\" mceMovable\"}y._addAll(d.doc.body,[\"div\",{id:i,\"class\":q.settings.inlinepopups_skin||\"clearlooks2\",style:\"width:100px;height:100px\"},[\"div\",{id:i+\"_wrapper\",\"class\":\"mceWrapper\"+k},[\"div\",{id:i+\"_top\",\"class\":\"mceTop\"},[\"div\",{\"class\":\"mceLeft\"}],[\"div\",{\"class\":\"mceCenter\"}],[\"div\",{\"class\":\"mceRight\"}],[\"span\",{id:i+\"_title\"},r.title||\"\"]],[\"div\",{id:i+\"_middle\",\"class\":\"mceMiddle\"},[\"div\",{id:i+\"_left\",\"class\":\"mceLeft\"}],[\"span\",{id:i+\"_content\"}],[\"div\",{id:i+\"_right\",\"class\":\"mceRight\"}]],[\"div\",{id:i+\"_bottom\",\"class\":\"mceBottom\"},[\"div\",{\"class\":\"mceLeft\"}],[\"div\",{\"class\":\"mceCenter\"}],[\"div\",{\"class\":\"mceRight\"}],[\"span\",{id:i+\"_status\"},\"Content\"]],[\"a\",{\"class\":\"mceMove\",tabindex:\"-1\",href:\"javascript:;\"}],[\"a\",{\"class\":\"mceMin\",tabindex:\"-1\",href:\"javascript:;\",onmousedown:\"return false;\"}],[\"a\",{\"class\":\"mceMax\",tabindex:\"-1\",href:\"javascript:;\",onmousedown:\"return false;\"}],[\"a\",{\"class\":\"mceMed\",tabindex:\"-1\",href:\"javascript:;\",onmousedown:\"return false;\"}],[\"a\",{\"class\":\"mceClose\",tabindex:\"-1\",href:\"javascript:;\",onmousedown:\"return false;\"}],[\"a\",{id:i+\"_resize_n\",\"class\":\"mceResize mceResizeN\",tabindex:\"-1\",href:\"javascript:;\"}],[\"a\",{id:i+\"_resize_s\",\"class\":\"mceResize mceResizeS\",tabindex:\"-1\",href:\"javascript:;\"}],[\"a\",{id:i+\"_resize_w\",\"class\":\"mceResize mceResizeW\",tabindex:\"-1\",href:\"javascript:;\"}],[\"a\",{id:i+\"_resize_e\",\"class\":\"mceResize mceResizeE\",tabindex:\"-1\",href:\"javascript:;\"}],[\"a\",{id:i+\"_resize_nw\",\"class\":\"mceResize mceResizeNW\",tabindex:\"-1\",href:\"javascript:;\"}],[\"a\",{id:i+\"_resize_ne\",\"class\":\"mceResize mceResizeNE\",tabindex:\"-1\",href:\"javascript:;\"}],[\"a\",{id:i+\"_resize_sw\",\"class\":\"mceResize mceResizeSW\",tabindex:\"-1\",href:\"javascript:;\"}],[\"a\",{id:i+\"_resize_se\",\"class\":\"mceResize mceResizeSE\",tabindex:\"-1\",href:\"javascript:;\"}]]]);d.setStyles(i,{top:-10000,left:-10000});if(tinymce.isGecko){d.setStyle(i,\"overflow\",\"auto\")}if(!r.type){g+=d.get(i+\"_left\").clientWidth;g+=d.get(i+\"_right\").clientWidth;s+=d.get(i+\"_top\").clientHeight;s+=d.get(i+\"_bottom\").clientHeight}d.setStyles(i,{top:r.top,left:r.left,width:r.width+g,height:r.height+s});x=r.url||r.file;if(x){if(tinymce.relaxedDomain){x+=(x.indexOf(\"?\")==-1?\"?\":\"&\")+\"mce_rdomain=\"+tinymce.relaxedDomain}x=tinymce._addVer(x)}if(!r.type){d.add(i+\"_content\",\"iframe\",{id:i+\"_ifr\",src:'javascript:\"\"',frameBorder:0,style:\"border:0;width:10px;height:10px\"});d.setStyles(i+\"_ifr\",{width:r.width,height:r.height});d.setAttrib(i+\"_ifr\",\"src\",x)}else{d.add(i+\"_wrapper\",\"a\",{id:i+\"_ok\",\"class\":\"mceButton mceOk\",href:\"javascript:;\",onmousedown:\"return false;\"},\"Ok\");if(r.type==\"confirm\"){d.add(i+\"_wrapper\",\"a\",{\"class\":\"mceButton mceCancel\",href:\"javascript:;\",onmousedown:\"return false;\"},\"Cancel\")}d.add(i+\"_middle\",\"div\",{\"class\":\"mceIcon\"});d.setHTML(i+\"_content\",r.content.replace(\"\\n\",\"<br />\"))}n=a.add(i,\"mousedown\",function(t){var u=t.target,f,p;f=y.windows[i];y.focus(i);if(u.nodeName==\"A\"||u.nodeName==\"a\"){if(u.className==\"mceMax\"){f.oldPos=f.element.getXY();f.oldSize=f.element.getSize();p=d.getViewPort();p.w-=2;p.h-=2;f.element.moveTo(p.x,p.y);f.element.resizeTo(p.w,p.h);d.setStyles(i+\"_ifr\",{width:p.w-f.deltaWidth,height:p.h-f.deltaHeight});d.addClass(i+\"_wrapper\",\"mceMaximized\")}else{if(u.className==\"mceMed\"){f.element.moveTo(f.oldPos.x,f.oldPos.y);f.element.resizeTo(f.oldSize.w,f.oldSize.h);f.iframeElement.resizeTo(f.oldSize.w-f.deltaWidth,f.oldSize.h-f.deltaHeight);d.removeClass(i+\"_wrapper\",\"mceMaximized\")}else{if(u.className==\"mceMove\"){return y._startDrag(i,t,u.className)}else{if(d.hasClass(u,\"mceResize\")){return y._startDrag(i,t,u.className.substring(13))}}}}}});o=a.add(i,\"click\",function(f){var p=f.target;y.focus(i);if(p.nodeName==\"A\"||p.nodeName==\"a\"){switch(p.className){case\"mceClose\":y.close(null,i);return a.cancel(f);case\"mceButton mceOk\":case\"mceButton mceCancel\":r.button_func(p.className==\"mceButton mceOk\");return a.cancel(f)}}});v=y.windows[i]={id:i,mousedown_func:n,click_func:o,element:new b(i,{blocker:1,container:q.getContainer()}),iframeElement:new b(i+\"_ifr\"),features:r,deltaWidth:g,deltaHeight:s};v.iframeElement.on(\"focus\",function(){y.focus(i)});if(y.count==0&&y.editor.getParam(\"dialog_type\",\"modal\")==\"modal\"){d.add(d.doc.body,\"div\",{id:\"mceModalBlocker\",\"class\":(y.editor.settings.inlinepopups_skin||\"clearlooks2\")+\"_modalBlocker\",style:{zIndex:y.zIndex-1}});d.show(\"mceModalBlocker\")}else{d.setStyle(\"mceModalBlocker\",\"z-index\",y.zIndex-1)}if(tinymce.isIE6||/Firefox\\/2\\./.test(navigator.userAgent)||(tinymce.isIE&&!d.boxModel)){d.setStyles(\"mceModalBlocker\",{position:\"absolute\",left:h.x,top:h.y,width:h.w-2,height:h.h-2})}y.focus(i);y._fixIELayout(i,1);if(d.get(i+\"_ok\")){d.get(i+\"_ok\").focus()}y.count++;return v},focus:function(h){var g=this,f;if(f=g.windows[h]){f.zIndex=this.zIndex++;f.element.setStyle(\"zIndex\",f.zIndex);f.element.update();h=h+\"_wrapper\";d.removeClass(g.lastId,\"mceFocus\");d.addClass(h,\"mceFocus\");g.lastId=h}},_addAll:function(k,h){var g,l,f=this,j=tinymce.DOM;if(c(h,\"string\")){k.appendChild(j.doc.createTextNode(h))}else{if(h.length){k=k.appendChild(j.create(h[0],h[1]));for(g=2;g<h.length;g++){f._addAll(k,h[g])}}}},_startDrag:function(v,G,E){var o=this,u,z,C=d.doc,f,l=o.windows[v],h=l.element,y=h.getXY(),x,q,F,g,A,s,r,j,i,m,k,n,B;g={x:0,y:0};A=d.getViewPort();A.w-=2;A.h-=2;j=G.screenX;i=G.screenY;m=k=n=B=0;u=a.add(C,\"mouseup\",function(p){a.remove(C,\"mouseup\",u);a.remove(C,\"mousemove\",z);if(f){f.remove()}h.moveBy(m,k);h.resizeBy(n,B);q=h.getSize();d.setStyles(v+\"_ifr\",{width:q.w-l.deltaWidth,height:q.h-l.deltaHeight});o._fixIELayout(v,1);return a.cancel(p)});if(E!=\"Move\"){D()}function D(){if(f){return}o._fixIELayout(v,0);d.add(C.body,\"div\",{id:\"mceEventBlocker\",\"class\":\"mceEventBlocker \"+(o.editor.settings.inlinepopups_skin||\"clearlooks2\"),style:{zIndex:o.zIndex+1}});if(tinymce.isIE6||(tinymce.isIE&&!d.boxModel)){d.setStyles(\"mceEventBlocker\",{position:\"absolute\",left:A.x,top:A.y,width:A.w-2,height:A.h-2})}f=new b(\"mceEventBlocker\");f.update();x=h.getXY();q=h.getSize();s=g.x+x.x-A.x;r=g.y+x.y-A.y;d.add(f.get(),\"div\",{id:\"mcePlaceHolder\",\"class\":\"mcePlaceHolder\",style:{left:s,top:r,width:q.w,height:q.h}});F=new b(\"mcePlaceHolder\")}z=a.add(C,\"mousemove\",function(w){var p,H,t;D();p=w.screenX-j;H=w.screenY-i;switch(E){case\"ResizeW\":m=p;n=0-p;break;case\"ResizeE\":n=p;break;case\"ResizeN\":case\"ResizeNW\":case\"ResizeNE\":if(E==\"ResizeNW\"){m=p;n=0-p}else{if(E==\"ResizeNE\"){n=p}}k=H;B=0-H;break;case\"ResizeS\":case\"ResizeSW\":case\"ResizeSE\":if(E==\"ResizeSW\"){m=p;n=0-p}else{if(E==\"ResizeSE\"){n=p}}B=H;break;case\"mceMove\":m=p;k=H;break}if(n<(t=l.features.min_width-q.w)){if(m!==0){m+=n-t}n=t}if(B<(t=l.features.min_height-q.h)){if(k!==0){k+=B-t}B=t}n=Math.min(n,l.features.max_width-q.w);B=Math.min(B,l.features.max_height-q.h);m=Math.max(m,A.x-(s+A.x));k=Math.max(k,A.y-(r+A.y));m=Math.min(m,(A.w+A.x)-(s+q.w+A.x));k=Math.min(k,(A.h+A.y)-(r+q.h+A.y));if(m+k!==0){if(s+m<0){m=0}if(r+k<0){k=0}F.moveTo(s+m,r+k)}if(n+B!==0){F.resizeTo(q.w+n,q.h+B)}return a.cancel(w)});return a.cancel(G)},resizeBy:function(g,h,i){var f=this.windows[i];if(f){f.element.resizeBy(g,h);f.iframeElement.resizeBy(g,h)}},close:function(j,l){var h=this,g,k=d.doc,f=0,i,l;l=h._findId(l||j);if(!h.windows[l]){h.parent(j);return}h.count--;if(h.count==0){d.remove(\"mceModalBlocker\")}if(g=h.windows[l]){h.onClose.dispatch(h);a.remove(k,\"mousedown\",g.mousedownFunc);a.remove(k,\"click\",g.clickFunc);a.clear(l);a.clear(l+\"_ifr\");d.setAttrib(l+\"_ifr\",\"src\",'javascript:\"\"');g.element.remove();delete h.windows[l];e(h.windows,function(m){if(m.zIndex>f){i=m;f=m.zIndex}});if(i){h.focus(i.id)}}},setTitle:function(f,g){var h;f=this._findId(f);if(h=d.get(f+\"_title\")){h.innerHTML=d.encode(g)}},alert:function(g,f,j){var i=this,h;h=i.open({title:i,type:\"alert\",button_func:function(k){if(f){f.call(k||i,k)}i.close(null,h.id)},content:d.encode(i.editor.getLang(g,g)),inline:1,width:400,height:130})},confirm:function(g,f,j){var i=this,h;h=i.open({title:i,type:\"confirm\",button_func:function(k){if(f){f.call(k||i,k)}i.close(null,h.id)},content:d.encode(i.editor.getLang(g,g)),inline:1,width:400,height:130})},_findId:function(f){var g=this;if(typeof(f)==\"string\"){return f}e(g.windows,function(h){var i=d.get(h.id+\"_ifr\");if(i&&f==i.contentWindow){f=h.id;return false}});return f},_fixIELayout:function(i,h){var f,g;if(!tinymce.isIE6){return}e([\"n\",\"s\",\"w\",\"e\",\"nw\",\"ne\",\"sw\",\"se\"],function(j){var k=d.get(i+\"_resize_\"+j);d.setStyles(k,{width:h?k.clientWidth:\"\",height:h?k.clientHeight:\"\",cursor:d.getStyle(k,\"cursor\",1)});d.setStyle(i+\"_bottom\",\"bottom\",\"-1px\");k=0});if(f=this.windows[i]){f.element.hide();f.element.show();e(d.select(\"div,a\",i),function(k,j){if(k.currentStyle.backgroundImage!=\"none\"){g=new Image();g.src=k.currentStyle.backgroundImage.replace(/url\\(\\\"(.+)\\\"\\)/,\"$1\")}});d.get(i).style.filter=\"\"}}});tinymce.PluginManager.add(\"inlinepopups\",tinymce.plugins.InlinePopups)})();"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css",
    "content": "/* Clearlooks 2 */\n\n/* Reset */\n.clearlooks2, .clearlooks2 div, .clearlooks2 span, .clearlooks2 a {vertical-align:baseline; text-align:left; position:absolute; border:0; padding:0; margin:0; background:transparent; font-family:\"Lucida Grande\",\"Lucida Sans Unicode\",Tahoma,Verdana; font-size:11px; color:#000; text-decoration:none; font-weight:normal; width:auto; height:auto; overflow:hidden; display:block}\n\n/* General */\n.clearlooks2 {position:absolute; direction:ltr}\n.clearlooks2 .mceWrapper {position:static}\n.mceEventBlocker {position:fixed; left:0; top:0; background:url(img/horizontal.gif) no-repeat 0 -75px; width:100%; height:100%}\n.clearlooks2 .mcePlaceHolder {border:1px solid #000; background:#888; top:0; left:0; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50)}\n.clearlooks2_modalBlocker {position:fixed; left:0; top:0; width:100%; height:100%; background:#333; opacity:0.6; -ms-filter:'alpha(opacity=60)'; filter:alpha(opacity=60); display:none}\n\n/* Top */\n.clearlooks2 .mceTop, .clearlooks2 .mceTop div {top:0; width:100%; height:30px}\n.clearlooks2 .mceTop .mceLeft {width:6px; background:#666}\n.clearlooks2 .mceTop .mceCenter {right:6px; width:100%; height:30px; background:#666; clip:rect(auto auto auto 12px)}\n.clearlooks2 .mceTop .mceRight {right:0; width:6px; height:30px; background:#666}\n.clearlooks2 .mceTop span {width:100%; text-align:center; vertical-align:middle; line-height:30px; font-weight:bold; font-size:10pt}\n.clearlooks2 .mceFocus .mceTop .mceLeft {background:#666}\n.clearlooks2 .mceFocus .mceTop .mceCenter {background:#666}\n.clearlooks2 .mceFocus .mceTop .mceRight {background:#666}\n.clearlooks2 .mceFocus .mceTop span {color:#FFF}\n\n/* Middle */\n.clearlooks2 .mceMiddle, .clearlooks2 .mceMiddle div {top:0}\n.clearlooks2 .mceMiddle {width:100%; height:100%; clip:rect(30px auto auto auto)}\n.clearlooks2 .mceMiddle .mceLeft {left:0; width:5px; height:100%; background: #DEE4C5}\n.clearlooks2 .mceMiddle span {top:30px; left:5px; width:100%; height:100%; background:#FFF}\n.clearlooks2 .mceMiddle .mceRight {right:0; width:5px; height:100%; background:#DEE4C5}\n\n/* Bottom */\n.clearlooks2 .mceBottom, .clearlooks2 .mceBottom div {height:6px}\n.clearlooks2 .mceBottom {left:0; bottom:0; width:100%}\n.clearlooks2 .mceBottom div {top:0}\n.clearlooks2 .mceBottom .mceLeft {left:0; width:5px; background:url(img/corners.gif) -34px -6px}\n.clearlooks2 .mceBottom .mceCenter {left:5px; width:100%; background:#DEE4C5}\n.clearlooks2 .mceBottom .mceRight {right:0; width:5px; background: url(img/corners.gif) -34px 0}\n.clearlooks2 .mceBottom span {display:none}\n.clearlooks2 .mceStatusbar .mceBottom, .clearlooks2 .mceStatusbar .mceBottom div {height:30px}\n.clearlooks2 .mceStatusbar .mceBottom .mceLeft {background:url(img/corners.gif) -29px 0}\n.clearlooks2 .mceStatusbar .mceBottom .mceCenter {background:url(img/horizontal.gif) 0 -52px}\n.clearlooks2 .mceStatusbar .mceBottom .mceRight {background:url(img/corners.gif) -24px 0}\n.clearlooks2 .mceStatusbar .mceBottom span {display:block; left:7px; font-family:Arial, Verdana; font-size:11px; line-height:30px}\n\n/* Actions */\n.clearlooks2 a {width:29px; height:16px; top:7px;}\n.clearlooks2 .mceClose {right:6px; background:url(img/buttons.gif) -87px 0}\n.clearlooks2 .mceMin {display:none; right:68px; background:url(img/buttons.gif) 0 0}\n.clearlooks2 .mceMed {display:none; right:37px; background:url(img/buttons.gif) -29px 0}\n.clearlooks2 .mceMax {display:none; right:37px; background:url(img/buttons.gif) -58px 0}\n.clearlooks2 .mceMove {display:none;width:100%;cursor:move;background:url(img/corners.gif) no-repeat -100px -100px}\n.clearlooks2 .mceMovable .mceMove {display:block}\n.clearlooks2 .mceFocus .mceClose {right:6px; background:url(img/buttons.gif) -87px 0}\n.clearlooks2 .mceFocus .mceMin {right:68px; background:url(img/buttons.gif) 0 0}\n.clearlooks2 .mceFocus .mceMed {right:37px; background:url(img/buttons.gif) -29px 0}\n.clearlooks2 .mceFocus .mceMax {right:37px; background:url(img/buttons.gif) -58px 0}\n.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px 0}\n.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px 0}\n.clearlooks2 .mceFocus .mceMin:hover {right:68px; background:url(img/buttons.gif) 0 0}\n.clearlooks2 .mceFocus .mceMed:hover {right:37px; background:url(img/buttons.gif) -29px 0}\n.clearlooks2 .mceFocus .mceMax:hover {right:37px; background:url(img/buttons.gif) -58px 0}\n\n/* Resize */\n.clearlooks2 .mceResize {top:auto; left:auto; display:none; width:1px; height:1px; background:#333}\n.clearlooks2 .mceResizable .mceResize {display:block}\n.clearlooks2 .mceResizable .mceMin, .clearlooks2 .mceMax {display:none}\n.clearlooks2 .mceMinimizable .mceMin {display:block}\n.clearlooks2 .mceMaximizable .mceMax {display:block}\n.clearlooks2 .mceMaximized .mceMed {display:block}\n.clearlooks2 .mceMaximized .mceMax {display:none}\n.clearlooks2 a.mceResizeN {top:0; left:0; width:100%; cursor:n-resize}\n.clearlooks2 a.mceResizeNW {top:0; left:0; cursor:nw-resize}\n.clearlooks2 a.mceResizeNE {top:0; right:0; cursor:ne-resize}\n.clearlooks2 a.mceResizeW {top:0; left:0; height:100%; cursor:w-resize;}\n.clearlooks2 a.mceResizeE {top:0; right:0; height:100%; cursor:e-resize}\n.clearlooks2 a.mceResizeS {bottom:0; left:0; width:100%; cursor:s-resize}\n.clearlooks2 a.mceResizeSW {bottom:0; left:0; cursor:sw-resize}\n.clearlooks2 a.mceResizeSE {bottom:0; right:0; cursor:se-resize}\n\n/* Alert/Confirm */\n.clearlooks2 .mceButton {font-weight:bold; bottom:10px; width:80px; height:30px; background:url(img/button.gif); line-height:30px; vertical-align:middle; text-align:center; outline:0}\n.clearlooks2 .mceMiddle .mceIcon {left:15px; top:35px; width:32px; height:32px}\n.clearlooks2 .mceAlert .mceMiddle span, .clearlooks2 .mceConfirm .mceMiddle span {background:transparent;left:60px; top:35px; width:320px; height:50px; font-weight:bold; overflow:auto; white-space:normal}\n.clearlooks2 a:hover {font-weight:bold;}\n.clearlooks2 .mceAlert .mceMiddle, .clearlooks2 .mceConfirm .mceMiddle {background:#D6D7D5}\n.clearlooks2 .mceAlert .mceOk {left:50%; top:auto; margin-left: -40px}\n.clearlooks2 .mceAlert .mceIcon {background:url(img/alert.gif)}\n.clearlooks2 .mceConfirm .mceOk {left:50%; top:auto; margin-left: -90px}\n.clearlooks2 .mceConfirm .mceCancel {left:50%; top:auto}\n.clearlooks2 .mceConfirm .mceIcon {background:url(img/confirm.gif)} \n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/inlinepopups/template.htm",
    "content": "<!-- <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> -->\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<title>Template for dialogs</title>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"skins/clearlooks2/window.css\" />\n</head>\n<body>\n\n<div class=\"mceEditor\">\n\t<div class=\"clearlooks2\" style=\"width:400px; height:100px; left:10px;\">\n\t\t<div class=\"mceWrapper\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Blured</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>Content</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar text.</span>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceMin\" href=\"#\"></a>\n\t\t\t<a class=\"mceMax\" href=\"#\"></a>\n\t\t\t<a class=\"mceMed\" href=\"#\"></a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeN\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeS\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSE\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:100px; left:420px;\">\n\t\t<div class=\"mceWrapper mceMovable mceFocus\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Focused</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>Content</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar text.</span>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceMin\" href=\"#\"></a>\n\t\t\t<a class=\"mceMax\" href=\"#\"></a>\n\t\t\t<a class=\"mceMed\" href=\"#\"></a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeN\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeS\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSE\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:100px; left:10px; top:120px;\">\n\t\t<div class=\"mceWrapper mceMovable mceFocus mceStatusbar\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>Content</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar text.</span>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceMin\" href=\"#\"></a>\n\t\t\t<a class=\"mceMax\" href=\"#\"></a>\n\t\t\t<a class=\"mceMed\" href=\"#\"></a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeN\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeS\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSE\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:100px; left:420px; top:120px;\">\n\t\t<div class=\"mceWrapper mceMovable mceFocus mceStatusbar mceResizable\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar, Resizable</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>Content</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar text.</span>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceMin\" href=\"#\"></a>\n\t\t\t<a class=\"mceMax\" href=\"#\"></a>\n\t\t\t<a class=\"mceMed\" href=\"#\"></a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeN\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeS\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSE\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:100px; left:10px; top:230px;\">\n\t\t<div class=\"mceWrapper mceMovable mceFocus mceResizable mceMaximizable\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Resizable, Maximizable</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>Content</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar text.</span>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceMin\" href=\"#\"></a>\n\t\t\t<a class=\"mceMax\" href=\"#\"></a>\n\t\t\t<a class=\"mceMed\" href=\"#\"></a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeN\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeS\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSE\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:100px; left:420px; top:230px;\">\n\t\t<div class=\"mceWrapper mceMovable mceStatusbar mceResizable mceMaximizable\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Blurred, Maximizable, Statusbar, Resizable</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>Content</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar text.</span>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceMin\" href=\"#\"></a>\n\t\t\t<a class=\"mceMax\" href=\"#\"></a>\n\t\t\t<a class=\"mceMed\" href=\"#\"></a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeN\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeS\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSE\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:100px; left:10px; top:340px;\">\n\t\t<div class=\"mceWrapper mceMovable mceFocus mceResizable mceMaximized mceMinimizable mceMaximizable\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Maximized, Maximizable, Minimizable</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>Content</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar text.</span>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceMin\" href=\"#\"></a>\n\t\t\t<a class=\"mceMax\" href=\"#\"></a>\n\t\t\t<a class=\"mceMed\" href=\"#\"></a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeN\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeS\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSE\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:100px; left:420px; top:340px;\">\n\t\t<div class=\"mceWrapper mceMovable mceStatusbar mceResizable mceMaximized mceMinimizable mceMaximizable\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Blured</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>Content</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Statusbar text.</span>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceMin\" href=\"#\"></a>\n\t\t\t<a class=\"mceMax\" href=\"#\"></a>\n\t\t\t<a class=\"mceMed\" href=\"#\"></a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeN\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeS\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeNE\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSW\" href=\"#\"></a>\n\t\t\t<a class=\"mceResize mceResizeSE\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:130px; left:10px; top:450px;\">\n\t\t<div class=\"mceWrapper mceMovable mceFocus mceModal mceAlert\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Alert</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<div class=\"mceIcon\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceButton mceOk\" href=\"#\">Ok</a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n\n\t<div class=\"clearlooks2\" style=\"width:400px; height:130px; left:420px; top:450px;\">\n\t\t<div class=\"mceWrapper mceMovable mceFocus mceModal mceConfirm\">\n\t\t\t<div class=\"mceTop\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<span>Confirm</span>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceMiddle\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<span>\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\tThis is a very long error message. This is a very long error message.\n\t\t\t\t\t</span>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t\t<div class=\"mceIcon\"></div>\n\t\t\t</div>\n\n\t\t\t<div class=\"mceBottom\">\n\t\t\t\t<div class=\"mceLeft\"></div>\n\t\t\t\t<div class=\"mceCenter\"></div>\n\t\t\t\t<div class=\"mceRight\"></div>\n\t\t\t</div>\n\n\t\t\t<a class=\"mceMove\" href=\"#\"></a>\n\t\t\t<a class=\"mceButton mceOk\" href=\"#\">Ok</a>\n\t\t\t<a class=\"mceButton mceCancel\" href=\"#\">Cancel</a>\n\t\t\t<a class=\"mceClose\" href=\"#\"></a>\n\t\t</div>\n\t</div>\n</div>\n\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/media/css/content.css",
    "content": ".mceItemFlash, .mceItemShockWave, .mceItemQuickTime, .mceItemWindowsMedia, .mceItemRealMedia {border:1px dotted #cc0000; background-position:center; background-repeat:no-repeat; background-color:#ffffcc;}\n.mceItemShockWave {background-image: url(../img/shockwave.gif);}\n.mceItemFlash {background-image:url(../img/flash.gif);}\n.mceItemQuickTime {background-image:url(../img/quicktime.gif);}\n.mceItemWindowsMedia {background-image:url(../img/windowsmedia.gif);}\n.mceItemRealMedia {background-image:url(../img/realmedia.gif);}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/media/css/media.css",
    "content": "#id, #name, #hspace, #vspace, #class_name, #align {\twidth: 100px }\n#hspace, #vspace { width: 50px }\n#flash_quality, #flash_align, #flash_scale, #flash_salign, #flash_wmode { width: 100px }\n#flash_base, #flash_flashvars { width: 240px }\n#width, #height { width: 40px }\n#src, #media_type { width: 250px }\n#class { width: 120px }\n#prev { margin: 0; border: 1px solid black; width: 360px; height: 230px; overflow: auto }\n.panel_wrapper div.current { height: 420px; overflow: auto }\n#flash_options, #shockwave_options, #qt_options, #wmp_options, #rmp_options { display: none }\n.mceAddSelectValue { background-color: #DDDDDD }\n#qt_starttime, #qt_endtime, #qt_fov, #qt_href, #qt_moveid, #qt_moviename, #qt_node, #qt_pan, #qt_qtsrc, #qt_qtsrcchokespeed, #qt_target, #qt_tilt, #qt_urlsubstituten, #qt_volume { width: 70px }\n#wmp_balance, #wmp_baseurl, #wmp_captioningid, #wmp_currentmarker, #wmp_currentposition, #wmp_defaultframe, #wmp_playcount, #wmp_rate, #wmp_uimode, #wmp_volume { width: 70px }\n#rmp_console, #rmp_numloop, #rmp_controls, #rmp_scriptcallbacks { width: 70px }\n#shockwave_swvolume, #shockwave_swframe, #shockwave_swurl, #shockwave_swstretchvalign, #shockwave_swstretchhalign, #shockwave_swstretchstyle { width: 90px }\n#qt_qtsrc { width: 200px }\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/media/editor_plugin.js",
    "content": "(function(){var a=tinymce.each;tinymce.create(\"tinymce.plugins.MediaPlugin\",{init:function(b,c){var e=this;e.editor=b;e.url=c;function f(g){return/^(mceItemFlash|mceItemShockWave|mceItemWindowsMedia|mceItemQuickTime|mceItemRealMedia)$/.test(g.className)}b.onPreInit.add(function(){b.serializer.addRules(\"param[name|value|_mce_value]\")});b.addCommand(\"mceMedia\",function(){b.windowManager.open({file:c+\"/media.htm\",width:430+parseInt(b.getLang(\"media.delta_width\",0)),height:470+parseInt(b.getLang(\"media.delta_height\",0)),inline:1},{plugin_url:c})});b.addButton(\"media\",{title:\"media.desc\",cmd:\"mceMedia\"});b.onNodeChange.add(function(h,g,i){g.setActive(\"media\",i.nodeName==\"IMG\"&&f(i))});b.onInit.add(function(){var g={mceItemFlash:\"flash\",mceItemShockWave:\"shockwave\",mceItemWindowsMedia:\"windowsmedia\",mceItemQuickTime:\"quicktime\",mceItemRealMedia:\"realmedia\"};b.selection.onSetContent.add(function(){e._spansToImgs(b.getBody())});b.selection.onBeforeSetContent.add(e._objectsToSpans,e);if(b.settings.content_css!==false){b.dom.loadCSS(c+\"/css/content.css\")}if(b.theme&&b.theme.onResolveName){b.theme.onResolveName.add(function(h,i){if(i.name==\"img\"){a(g,function(l,j){if(b.dom.hasClass(i.node,j)){i.name=l;i.title=b.dom.getAttrib(i.node,\"title\");return false}})}})}if(b&&b.plugins.contextmenu){b.plugins.contextmenu.onContextMenu.add(function(i,h,j){if(j.nodeName==\"IMG\"&&/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(j.className)){h.add({title:\"media.edit\",icon:\"media\",cmd:\"mceMedia\"})}})}});b.onBeforeSetContent.add(e._objectsToSpans,e);b.onSetContent.add(function(){e._spansToImgs(b.getBody())});b.onPreProcess.add(function(g,i){var h=g.dom;if(i.set){e._spansToImgs(i.node);a(h.select(\"IMG\",i.node),function(k){var j;if(f(k)){j=e._parse(k.title);h.setAttrib(k,\"width\",h.getAttrib(k,\"width\",j.width||100));h.setAttrib(k,\"height\",h.getAttrib(k,\"height\",j.height||100))}})}if(i.get){a(h.select(\"IMG\",i.node),function(m){var l,j,k;if(g.getParam(\"media_use_script\")){if(f(m)){m.className=m.className.replace(/mceItem/g,\"mceTemp\")}return}switch(m.className){case\"mceItemFlash\":l=\"d27cdb6e-ae6d-11cf-96b8-444553540000\";j=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0\";k=\"application/x-shockwave-flash\";break;case\"mceItemShockWave\":l=\"166b1bca-3f9c-11cf-8075-444553540000\";j=\"http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0\";k=\"application/x-director\";break;case\"mceItemWindowsMedia\":l=g.getParam(\"media_wmp6_compatible\")?\"05589fa1-c356-11ce-bf01-00aa0055595a\":\"6bf52a52-394a-11d3-b153-00c04f79faa6\";j=\"http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701\";k=\"application/x-mplayer2\";break;case\"mceItemQuickTime\":l=\"02bf25d5-8c17-4b23-bc80-d3488abddc6b\";j=\"http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0\";k=\"video/quicktime\";break;case\"mceItemRealMedia\":l=\"cfcdaa03-8be4-11cf-b84b-0020afbbccfa\";j=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0\";k=\"audio/x-pn-realaudio-plugin\";break}if(l){h.replace(e._buildObj({classid:l,codebase:j,type:k},m),m)}})}});b.onPostProcess.add(function(g,h){h.content=h.content.replace(/_mce_value=/g,\"value=\")});function d(g,h){h=new RegExp(h+'=\"([^\"]+)\"',\"g\").exec(g);return h?b.dom.decode(h[1]):\"\"}b.onPostProcess.add(function(g,h){if(g.getParam(\"media_use_script\")){h.content=h.content.replace(/<img[^>]+>/g,function(j){var i=d(j,\"class\");if(/^(mceTempFlash|mceTempShockWave|mceTempWindowsMedia|mceTempQuickTime|mceTempRealMedia)$/.test(i)){at=e._parse(d(j,\"title\"));at.width=d(j,\"width\");at.height=d(j,\"height\");j='<script type=\"text/javascript\">write'+i.substring(7)+\"({\"+e._serialize(at)+\"});<\\/script>\"}return j})}})},getInfo:function(){return{longname:\"Media\",author:\"Moxiecode Systems AB\",authorurl:\"http://tinymce.moxiecode.com\",infourl:\"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media\",version:tinymce.majorVersion+\".\"+tinymce.minorVersion}},_objectsToSpans:function(b,e){var c=this,d=e.content;d=d.replace(/<script[^>]*>\\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\\(\\{([^\\)]*)\\}\\);\\s*<\\/script>/gi,function(g,f,i){var h=c._parse(i);return'<img class=\"mceItem'+f+'\" title=\"'+b.dom.encode(i)+'\" src=\"'+c.url+'/img/trans.gif\" width=\"'+h.width+'\" height=\"'+h.height+'\" />'});d=d.replace(/<object([^>]*)>/gi,'<span class=\"mceItemObject\" $1>');d=d.replace(/<embed([^>]*)\\/?>/gi,'<span class=\"mceItemEmbed\" $1></span>');d=d.replace(/<embed([^>]*)>/gi,'<span class=\"mceItemEmbed\" $1>');d=d.replace(/<\\/(object)([^>]*)>/gi,\"</span>\");d=d.replace(/<\\/embed>/gi,\"\");d=d.replace(/<param([^>]*)>/gi,function(g,f){return\"<span \"+f.replace(/value=/gi,\"_mce_value=\")+' class=\"mceItemParam\"></span>'});d=d.replace(/\\/ class=\\\"mceItemParam\\\"><\\/span>/gi,'class=\"mceItemParam\"></span>');e.content=d},_buildObj:function(g,h){var d,c=this.editor,f=c.dom,e=this._parse(h.title),b;b=c.getParam(\"media_strict\",true)&&g.type==\"application/x-shockwave-flash\";e.width=g.width=f.getAttrib(h,\"width\")||100;e.height=g.height=f.getAttrib(h,\"height\")||100;if(e.src){e.src=c.convertURL(e.src,\"src\",h)}if(b){d=f.create(\"span\",{id:e.id,mce_name:\"object\",type:\"application/x-shockwave-flash\",data:e.src,style:f.getAttrib(h,\"style\"),width:g.width,height:g.height})}else{d=f.create(\"span\",{id:e.id,mce_name:\"object\",classid:\"clsid:\"+g.classid,style:f.getAttrib(h,\"style\"),codebase:g.codebase,width:g.width,height:g.height})}a(e,function(j,i){if(!/^(width|height|codebase|classid|id|_cx|_cy)$/.test(i)){if(g.type==\"application/x-mplayer2\"&&i==\"src\"&&!e.url){i=\"url\"}if(j){f.add(d,\"span\",{mce_name:\"param\",name:i,_mce_value:j})}}});if(!b){f.add(d,\"span\",tinymce.extend({mce_name:\"embed\",type:g.type,style:f.getAttrib(h,\"style\")},e))}return d},_spansToImgs:function(e){var d=this,f=d.editor.dom,b,c;a(f.select(\"span\",e),function(g){if(f.getAttrib(g,\"class\")==\"mceItemObject\"){c=f.getAttrib(g,\"classid\").toLowerCase().replace(/\\s+/g,\"\");switch(c){case\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\":f.replace(d._createImg(\"mceItemFlash\",g),g);break;case\"clsid:166b1bca-3f9c-11cf-8075-444553540000\":f.replace(d._createImg(\"mceItemShockWave\",g),g);break;case\"clsid:6bf52a52-394a-11d3-b153-00c04f79faa6\":case\"clsid:22d6f312-b0f6-11d0-94ab-0080c74c7e95\":case\"clsid:05589fa1-c356-11ce-bf01-00aa0055595a\":f.replace(d._createImg(\"mceItemWindowsMedia\",g),g);break;case\"clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b\":f.replace(d._createImg(\"mceItemQuickTime\",g),g);break;case\"clsid:cfcdaa03-8be4-11cf-b84b-0020afbbccfa\":f.replace(d._createImg(\"mceItemRealMedia\",g),g);break;default:f.replace(d._createImg(\"mceItemFlash\",g),g)}return}if(f.getAttrib(g,\"class\")==\"mceItemEmbed\"){switch(f.getAttrib(g,\"type\")){case\"application/x-shockwave-flash\":f.replace(d._createImg(\"mceItemFlash\",g),g);break;case\"application/x-director\":f.replace(d._createImg(\"mceItemShockWave\",g),g);break;case\"application/x-mplayer2\":f.replace(d._createImg(\"mceItemWindowsMedia\",g),g);break;case\"video/quicktime\":f.replace(d._createImg(\"mceItemQuickTime\",g),g);break;case\"audio/x-pn-realaudio-plugin\":f.replace(d._createImg(\"mceItemRealMedia\",g),g);break;default:f.replace(d._createImg(\"mceItemFlash\",g),g)}}})},_createImg:function(c,h){var b,g=this.editor.dom,f={},e=\"\",d;d=[\"id\",\"name\",\"width\",\"height\",\"bgcolor\",\"align\",\"flashvars\",\"src\",\"wmode\",\"allowfullscreen\",\"quality\",\"data\"];b=g.create(\"img\",{src:this.url+\"/img/trans.gif\",width:g.getAttrib(h,\"width\")||100,height:g.getAttrib(h,\"height\")||100,style:g.getAttrib(h,\"style\"),\"class\":c});a(d,function(i){var j=g.getAttrib(h,i);if(j){f[i]=j}});a(g.select(\"span\",h),function(i){if(g.hasClass(i,\"mceItemParam\")){f[g.getAttrib(i,\"name\")]=g.getAttrib(i,\"_mce_value\")}});if(f.movie){f.src=f.movie;delete f.movie}if(!f.src){f.src=f.data;delete f.data}h=g.select(\".mceItemEmbed\",h)[0];if(h){a(d,function(i){var j=g.getAttrib(h,i);if(j&&!f[i]){f[i]=j}})}delete f.width;delete f.height;b.title=this._serialize(f);return b},_parse:function(b){return tinymce.util.JSON.parse(\"{\"+b+\"}\")},_serialize:function(b){return tinymce.util.JSON.serialize(b).replace(/[{}]/g,\"\")}});tinymce.PluginManager.add(\"media\",tinymce.plugins.MediaPlugin)})();"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/media/js/embed.js",
    "content": "/**\n * This script contains embed functions for common plugins. This scripts are complety free to use for any purpose.\n */\n\nfunction writeFlash(p) {\n\twriteEmbed(\n\t\t'D27CDB6E-AE6D-11cf-96B8-444553540000',\n\t\t'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0',\n\t\t'application/x-shockwave-flash',\n\t\tp\n\t);\n}\n\nfunction writeShockWave(p) {\n\twriteEmbed(\n\t'166B1BCA-3F9C-11CF-8075-444553540000',\n\t'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0',\n\t'application/x-director',\n\t\tp\n\t);\n}\n\nfunction writeQuickTime(p) {\n\twriteEmbed(\n\t\t'02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',\n\t\t'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0',\n\t\t'video/quicktime',\n\t\tp\n\t);\n}\n\nfunction writeRealMedia(p) {\n\twriteEmbed(\n\t\t'CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA',\n\t\t'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0',\n\t\t'audio/x-pn-realaudio-plugin',\n\t\tp\n\t);\n}\n\nfunction writeWindowsMedia(p) {\n\tp.url = p.src;\n\twriteEmbed(\n\t\t'6BF52A52-394A-11D3-B153-00C04F79FAA6',\n\t\t'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701',\n\t\t'application/x-mplayer2',\n\t\tp\n\t);\n}\n\nfunction writeEmbed(cls, cb, mt, p) {\n\tvar h = '', n;\n\n\th += '<object classid=\"clsid:' + cls + '\" codebase=\"' + cb + '\"';\n\th += typeof(p.id) != \"undefined\" ? 'id=\"' + p.id + '\"' : '';\n\th += typeof(p.name) != \"undefined\" ? 'name=\"' + p.name + '\"' : '';\n\th += typeof(p.width) != \"undefined\" ? 'width=\"' + p.width + '\"' : '';\n\th += typeof(p.height) != \"undefined\" ? 'height=\"' + p.height + '\"' : '';\n\th += typeof(p.align) != \"undefined\" ? 'align=\"' + p.align + '\"' : '';\n\th += '>';\n\n\tfor (n in p)\n\t\th += '<param name=\"' + n + '\" value=\"' + p[n] + '\">';\n\n\th += '<embed type=\"' + mt + '\"';\n\n\tfor (n in p)\n\t\th += n + '=\"' + p[n] + '\" ';\n\n\th += '></embed></object>';\n\n\tdocument.write(h);\n}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/media/js/media.js",
    "content": "tinyMCEPopup.requireLangPack();\n\nvar oldWidth, oldHeight, ed, url;\n\nif (url = tinyMCEPopup.getParam(\"media_external_list_url\"))\n\tdocument.write('<script language=\"javascript\" type=\"text/javascript\" src=\"' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '\"></script>');\n\nfunction init() {\n\tvar pl = \"\", f, val;\n\tvar type = \"flash\", fe, i;\n\n\ted = tinyMCEPopup.editor;\n\n\ttinyMCEPopup.resizeToInnerSize();\n\tf = document.forms[0]\n\n\tfe = ed.selection.getNode();\n\tif (/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(ed.dom.getAttrib(fe, 'class'))) {\n\t\tpl = fe.title;\n\n\t\tswitch (ed.dom.getAttrib(fe, 'class')) {\n\t\t\tcase 'mceItemFlash':\n\t\t\t\ttype = 'flash';\n\t\t\t\tbreak;\n\n\t\t\tcase 'mceItemFlashVideo':\n\t\t\t\ttype = 'flv';\n\t\t\t\tbreak;\n\n\t\t\tcase 'mceItemShockWave':\n\t\t\t\ttype = 'shockwave';\n\t\t\t\tbreak;\n\n\t\t\tcase 'mceItemWindowsMedia':\n\t\t\t\ttype = 'wmp';\n\t\t\t\tbreak;\n\n\t\t\tcase 'mceItemQuickTime':\n\t\t\t\ttype = 'qt';\n\t\t\t\tbreak;\n\n\t\t\tcase 'mceItemRealMedia':\n\t\t\t\ttype = 'rmp';\n\t\t\t\tbreak;\n\t\t}\n\n\t\tdocument.forms[0].insert.value = ed.getLang('update', 'Insert', true); \n\t}\n\n\tdocument.getElementById('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media');\n\tdocument.getElementById('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','qt_qtsrc','media','media');\n\tdocument.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor');\n\n\tvar html = getMediaListHTML('medialist','src','media','media');\n\tif (html == \"\")\n\t\tdocument.getElementById(\"linklistrow\").style.display = 'none';\n\telse\n\t\tdocument.getElementById(\"linklistcontainer\").innerHTML = html;\n\n\t// Resize some elements\n\tif (isVisible('filebrowser'))\n\t\tdocument.getElementById('src').style.width = '230px';\n\n\t// Setup form\n\tif (pl != \"\") {\n\t\tpl = tinyMCEPopup.editor.plugins.media._parse(pl);\n\n\t\tswitch (type) {\n\t\t\tcase \"flash\":\n\t\t\t\tsetBool(pl, 'flash', 'play');\n\t\t\t\tsetBool(pl, 'flash', 'loop');\n\t\t\t\tsetBool(pl, 'flash', 'menu');\n\t\t\t\tsetBool(pl, 'flash', 'swliveconnect');\n\t\t\t\tsetStr(pl, 'flash', 'quality');\n\t\t\t\tsetStr(pl, 'flash', 'scale');\n\t\t\t\tsetStr(pl, 'flash', 'salign');\n\t\t\t\tsetStr(pl, 'flash', 'wmode');\n\t\t\t\tsetStr(pl, 'flash', 'base');\n\t\t\t\tsetStr(pl, 'flash', 'flashvars');\n\t\t\tbreak;\n\n\t\t\tcase \"qt\":\n\t\t\t\tsetBool(pl, 'qt', 'loop');\n\t\t\t\tsetBool(pl, 'qt', 'autoplay');\n\t\t\t\tsetBool(pl, 'qt', 'cache');\n\t\t\t\tsetBool(pl, 'qt', 'controller');\n\t\t\t\tsetBool(pl, 'qt', 'correction');\n\t\t\t\tsetBool(pl, 'qt', 'enablejavascript');\n\t\t\t\tsetBool(pl, 'qt', 'kioskmode');\n\t\t\t\tsetBool(pl, 'qt', 'autohref');\n\t\t\t\tsetBool(pl, 'qt', 'playeveryframe');\n\t\t\t\tsetBool(pl, 'qt', 'tarsetcache');\n\t\t\t\tsetStr(pl, 'qt', 'scale');\n\t\t\t\tsetStr(pl, 'qt', 'starttime');\n\t\t\t\tsetStr(pl, 'qt', 'endtime');\n\t\t\t\tsetStr(pl, 'qt', 'tarset');\n\t\t\t\tsetStr(pl, 'qt', 'qtsrcchokespeed');\n\t\t\t\tsetStr(pl, 'qt', 'volume');\n\t\t\t\tsetStr(pl, 'qt', 'qtsrc');\n\t\t\tbreak;\n\n\t\t\tcase \"shockwave\":\n\t\t\t\tsetBool(pl, 'shockwave', 'sound');\n\t\t\t\tsetBool(pl, 'shockwave', 'progress');\n\t\t\t\tsetBool(pl, 'shockwave', 'autostart');\n\t\t\t\tsetBool(pl, 'shockwave', 'swliveconnect');\n\t\t\t\tsetStr(pl, 'shockwave', 'swvolume');\n\t\t\t\tsetStr(pl, 'shockwave', 'swstretchstyle');\n\t\t\t\tsetStr(pl, 'shockwave', 'swstretchhalign');\n\t\t\t\tsetStr(pl, 'shockwave', 'swstretchvalign');\n\t\t\tbreak;\n\n\t\t\tcase \"wmp\":\n\t\t\t\tsetBool(pl, 'wmp', 'autostart');\n\t\t\t\tsetBool(pl, 'wmp', 'enabled');\n\t\t\t\tsetBool(pl, 'wmp', 'enablecontextmenu');\n\t\t\t\tsetBool(pl, 'wmp', 'fullscreen');\n\t\t\t\tsetBool(pl, 'wmp', 'invokeurls');\n\t\t\t\tsetBool(pl, 'wmp', 'mute');\n\t\t\t\tsetBool(pl, 'wmp', 'stretchtofit');\n\t\t\t\tsetBool(pl, 'wmp', 'windowlessvideo');\n\t\t\t\tsetStr(pl, 'wmp', 'balance');\n\t\t\t\tsetStr(pl, 'wmp', 'baseurl');\n\t\t\t\tsetStr(pl, 'wmp', 'captioningid');\n\t\t\t\tsetStr(pl, 'wmp', 'currentmarker');\n\t\t\t\tsetStr(pl, 'wmp', 'currentposition');\n\t\t\t\tsetStr(pl, 'wmp', 'defaultframe');\n\t\t\t\tsetStr(pl, 'wmp', 'playcount');\n\t\t\t\tsetStr(pl, 'wmp', 'rate');\n\t\t\t\tsetStr(pl, 'wmp', 'uimode');\n\t\t\t\tsetStr(pl, 'wmp', 'volume');\n\t\t\tbreak;\n\n\t\t\tcase \"rmp\":\n\t\t\t\tsetBool(pl, 'rmp', 'autostart');\n\t\t\t\tsetBool(pl, 'rmp', 'loop');\n\t\t\t\tsetBool(pl, 'rmp', 'autogotourl');\n\t\t\t\tsetBool(pl, 'rmp', 'center');\n\t\t\t\tsetBool(pl, 'rmp', 'imagestatus');\n\t\t\t\tsetBool(pl, 'rmp', 'maintainaspect');\n\t\t\t\tsetBool(pl, 'rmp', 'nojava');\n\t\t\t\tsetBool(pl, 'rmp', 'prefetch');\n\t\t\t\tsetBool(pl, 'rmp', 'shuffle');\n\t\t\t\tsetStr(pl, 'rmp', 'console');\n\t\t\t\tsetStr(pl, 'rmp', 'controls');\n\t\t\t\tsetStr(pl, 'rmp', 'numloop');\n\t\t\t\tsetStr(pl, 'rmp', 'scriptcallbacks');\n\t\t\tbreak;\n\t\t}\n\n\t\tsetStr(pl, null, 'src');\n\t\tsetStr(pl, null, 'id');\n\t\tsetStr(pl, null, 'name');\n\t\tsetStr(pl, null, 'vspace');\n\t\tsetStr(pl, null, 'hspace');\n\t\tsetStr(pl, null, 'bgcolor');\n\t\tsetStr(pl, null, 'align');\n\t\tsetStr(pl, null, 'width');\n\t\tsetStr(pl, null, 'height');\n\n\t\tif ((val = ed.dom.getAttrib(fe, \"width\")) != \"\")\n\t\t\tpl.width = f.width.value = val;\n\n\t\tif ((val = ed.dom.getAttrib(fe, \"height\")) != \"\")\n\t\t\tpl.height = f.height.value = val;\n\n\t\toldWidth = pl.width ? parseInt(pl.width) : 0;\n\t\toldHeight = pl.height ? parseInt(pl.height) : 0;\n\t} else\n\t\toldWidth = oldHeight = 0;\n\n\tselectByValue(f, 'media_type', type);\n\tchangedType(type);\n\tupdateColor('bgcolor_pick', 'bgcolor');\n\n\tTinyMCE_EditableSelects.init();\n\tgeneratePreview();\n}\n\nfunction insertMedia() {\n\tvar fe, f = document.forms[0], h;\n\n\ttinyMCEPopup.restoreSelection();\n\n\tif (!AutoValidator.validate(f)) {\n\t\ttinyMCEPopup.alert(ed.getLang('invalid_data'));\n\t\treturn false;\n\t}\n\n\tf.width.value = f.width.value == \"\" ? 100 : f.width.value;\n\tf.height.value = f.height.value == \"\" ? 100 : f.height.value;\n\n\tfe = ed.selection.getNode();\n\tif (fe != null && /mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(ed.dom.getAttrib(fe, 'class'))) {\n\t\tswitch (f.media_type.options[f.media_type.selectedIndex].value) {\n\t\t\tcase \"flash\":\n\t\t\t\tfe.className = \"mceItemFlash\";\n\t\t\t\tbreak;\n\n\t\t\tcase \"flv\":\n\t\t\t\tfe.className = \"mceItemFlashVideo\";\n\t\t\t\tbreak;\n\n\t\t\tcase \"shockwave\":\n\t\t\t\tfe.className = \"mceItemShockWave\";\n\t\t\t\tbreak;\n\n\t\t\tcase \"qt\":\n\t\t\t\tfe.className = \"mceItemQuickTime\";\n\t\t\t\tbreak;\n\n\t\t\tcase \"wmp\":\n\t\t\t\tfe.className = \"mceItemWindowsMedia\";\n\t\t\t\tbreak;\n\n\t\t\tcase \"rmp\":\n\t\t\t\tfe.className = \"mceItemRealMedia\";\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (fe.width != f.width.value || fe.height != f.height.value)\n\t\t\ted.execCommand('mceRepaint');\n\n\t\tfe.title = serializeParameters();\n\t\tfe.width = f.width.value;\n\t\tfe.height = f.height.value;\n\t\tfe.style.width = f.width.value + (f.width.value.indexOf('%') == -1 ? 'px' : '');\n\t\tfe.style.height = f.height.value + (f.height.value.indexOf('%') == -1 ? 'px' : '');\n\t\tfe.align = f.align.options[f.align.selectedIndex].value;\n\t} else {\n\t\th = '<img src=\"' + tinyMCEPopup.getWindowArg(\"plugin_url\") + '/img/trans.gif\"' ;\n\n\t\tswitch (f.media_type.options[f.media_type.selectedIndex].value) {\n\t\t\tcase \"flash\":\n\t\t\t\th += ' class=\"mceItemFlash\"';\n\t\t\t\tbreak;\n\n\t\t\tcase \"flv\":\n\t\t\t\th += ' class=\"mceItemFlashVideo\"';\n\t\t\t\tbreak;\n\n\t\t\tcase \"shockwave\":\n\t\t\t\th += ' class=\"mceItemShockWave\"';\n\t\t\t\tbreak;\n\n\t\t\tcase \"qt\":\n\t\t\t\th += ' class=\"mceItemQuickTime\"';\n\t\t\t\tbreak;\n\n\t\t\tcase \"wmp\":\n\t\t\t\th += ' class=\"mceItemWindowsMedia\"';\n\t\t\t\tbreak;\n\n\t\t\tcase \"rmp\":\n\t\t\t\th += ' class=\"mceItemRealMedia\"';\n\t\t\t\tbreak;\n\t\t}\n\n\t\th += ' title=\"' + serializeParameters() + '\"';\n\t\th += ' width=\"' + f.width.value + '\"';\n\t\th += ' height=\"' + f.height.value + '\"';\n\t\th += ' align=\"' + f.align.options[f.align.selectedIndex].value + '\"';\n\n\t\th += ' />';\n\n\t\ted.execCommand('mceInsertContent', false, h);\n\t}\n\n\ttinyMCEPopup.close();\n}\n\nfunction updatePreview() {\n\tvar f = document.forms[0], type;\n\n\tf.width.value = f.width.value || '320';\n\tf.height.value = f.height.value || '240';\n\n\ttype = getType(f.src.value);\n\tselectByValue(f, 'media_type', type);\n\tchangedType(type);\n\tgeneratePreview();\n}\n\nfunction getMediaListHTML() {\n\tif (typeof(tinyMCEMediaList) != \"undefined\" && tinyMCEMediaList.length > 0) {\n\t\tvar html = \"\";\n\n\t\thtml += '<select id=\"linklist\" name=\"linklist\" style=\"width: 250px\" onchange=\"this.form.src.value=this.options[this.selectedIndex].value;updatePreview();\">';\n\t\thtml += '<option value=\"\">---</option>';\n\n\t\tfor (var i=0; i<tinyMCEMediaList.length; i++)\n\t\t\thtml += '<option value=\"' + tinyMCEMediaList[i][1] + '\">' + tinyMCEMediaList[i][0] + '</option>';\n\n\t\thtml += '</select>';\n\n\t\treturn html;\n\t}\n\n\treturn \"\";\n}\n\nfunction getType(v) {\n\tvar fo, i, c, el, x, f = document.forms[0];\n\n\tfo = ed.getParam(\"media_types\", \"flash=swf;flv=flv;shockwave=dcr;qt=mov,qt,mpg,mp3,mp4,mpeg;shockwave=dcr;wmp=avi,wmv,wm,asf,asx,wmx,wvx;rmp=rm,ra,ram\").split(';');\n\n\t// YouTube\n\tif (v.match(/watch\\?v=(.+)(.*)/)) {\n\t\tf.width.value = '425';\n\t\tf.height.value = '350';\n\t\tf.src.value = 'http://www.youtube.com/v/' + v.match(/v=(.*)(.*)/)[0].split('=')[1];\n\t\treturn 'flash';\n\t}\n\n\t// Google video\n\tif (v.indexOf('http://video.google.com/videoplay?docid=') == 0) {\n\t\tf.width.value = '425';\n\t\tf.height.value = '326';\n\t\tf.src.value = 'http://video.google.com/googleplayer.swf?docId=' + v.substring('http://video.google.com/videoplay?docid='.length) + '&hl=en';\n\t\treturn 'flash';\n\t}\n\n\tfor (i=0; i<fo.length; i++) {\n\t\tc = fo[i].split('=');\n\n\t\tel = c[1].split(',');\n\t\tfor (x=0; x<el.length; x++)\n\t\tif (v.indexOf('.' + el[x]) != -1)\n\t\t\treturn c[0];\n\t}\n\n\treturn null;\n}\n\nfunction switchType(v) {\n\tvar t = getType(v), d = document, f = d.forms[0];\n\n\tif (!t)\n\t\treturn;\n\n\tselectByValue(d.forms[0], 'media_type', t);\n\tchangedType(t);\n\n\t// Update qtsrc also\n\tif (t == 'qt' && f.src.value.toLowerCase().indexOf('rtsp://') != -1) {\n\t\talert(ed.getLang(\"media_qt_stream_warn\"));\n\n\t\tif (f.qt_qtsrc.value == '')\n\t\t\tf.qt_qtsrc.value = f.src.value;\n\t}\n}\n\nfunction changedType(t) {\n\tvar d = document;\n\n\td.getElementById('flash_options').style.display = 'none';\n\td.getElementById('flv_options').style.display = 'none';\n\td.getElementById('qt_options').style.display = 'none';\n\td.getElementById('shockwave_options').style.display = 'none';\n\td.getElementById('wmp_options').style.display = 'none';\n\td.getElementById('rmp_options').style.display = 'none';\n\n\tif (t)\n\t\td.getElementById(t + '_options').style.display = 'block';\n}\n\nfunction serializeParameters() {\n\tvar d = document, f = d.forms[0], s = '';\n\n\tswitch (f.media_type.options[f.media_type.selectedIndex].value) {\n\t\tcase \"flash\":\n\t\t\ts += getBool('flash', 'play', true);\n\t\t\ts += getBool('flash', 'loop', true);\n\t\t\ts += getBool('flash', 'menu', true);\n\t\t\ts += getBool('flash', 'swliveconnect', false);\n\t\t\ts += getStr('flash', 'quality');\n\t\t\ts += getStr('flash', 'scale');\n\t\t\ts += getStr('flash', 'salign');\n\t\t\ts += getStr('flash', 'wmode');\n\t\t\ts += getStr('flash', 'base');\n\t\t\ts += getStr('flash', 'flashvars');\n\t\tbreak;\n\n\t\tcase \"qt\":\n\t\t\ts += getBool('qt', 'loop', false);\n\t\t\ts += getBool('qt', 'autoplay', true);\n\t\t\ts += getBool('qt', 'cache', false);\n\t\t\ts += getBool('qt', 'controller', true);\n\t\t\ts += getBool('qt', 'correction', false, 'none', 'full');\n\t\t\ts += getBool('qt', 'enablejavascript', false);\n\t\t\ts += getBool('qt', 'kioskmode', false);\n\t\t\ts += getBool('qt', 'autohref', false);\n\t\t\ts += getBool('qt', 'playeveryframe', false);\n\t\t\ts += getBool('qt', 'targetcache', false);\n\t\t\ts += getStr('qt', 'scale');\n\t\t\ts += getStr('qt', 'starttime');\n\t\t\ts += getStr('qt', 'endtime');\n\t\t\ts += getStr('qt', 'target');\n\t\t\ts += getStr('qt', 'qtsrcchokespeed');\n\t\t\ts += getStr('qt', 'volume');\n\t\t\ts += getStr('qt', 'qtsrc');\n\t\tbreak;\n\n\t\tcase \"shockwave\":\n\t\t\ts += getBool('shockwave', 'sound');\n\t\t\ts += getBool('shockwave', 'progress');\n\t\t\ts += getBool('shockwave', 'autostart');\n\t\t\ts += getBool('shockwave', 'swliveconnect');\n\t\t\ts += getStr('shockwave', 'swvolume');\n\t\t\ts += getStr('shockwave', 'swstretchstyle');\n\t\t\ts += getStr('shockwave', 'swstretchhalign');\n\t\t\ts += getStr('shockwave', 'swstretchvalign');\n\t\tbreak;\n\n\t\tcase \"wmp\":\n\t\t\ts += getBool('wmp', 'autostart', true);\n\t\t\ts += getBool('wmp', 'enabled', false);\n\t\t\ts += getBool('wmp', 'enablecontextmenu', true);\n\t\t\ts += getBool('wmp', 'fullscreen', false);\n\t\t\ts += getBool('wmp', 'invokeurls', true);\n\t\t\ts += getBool('wmp', 'mute', false);\n\t\t\ts += getBool('wmp', 'stretchtofit', false);\n\t\t\ts += getBool('wmp', 'windowlessvideo', false);\n\t\t\ts += getStr('wmp', 'balance');\n\t\t\ts += getStr('wmp', 'baseurl');\n\t\t\ts += getStr('wmp', 'captioningid');\n\t\t\ts += getStr('wmp', 'currentmarker');\n\t\t\ts += getStr('wmp', 'currentposition');\n\t\t\ts += getStr('wmp', 'defaultframe');\n\t\t\ts += getStr('wmp', 'playcount');\n\t\t\ts += getStr('wmp', 'rate');\n\t\t\ts += getStr('wmp', 'uimode');\n\t\t\ts += getStr('wmp', 'volume');\n\t\tbreak;\n\n\t\tcase \"rmp\":\n\t\t\ts += getBool('rmp', 'autostart', false);\n\t\t\ts += getBool('rmp', 'loop', false);\n\t\t\ts += getBool('rmp', 'autogotourl', true);\n\t\t\ts += getBool('rmp', 'center', false);\n\t\t\ts += getBool('rmp', 'imagestatus', true);\n\t\t\ts += getBool('rmp', 'maintainaspect', false);\n\t\t\ts += getBool('rmp', 'nojava', false);\n\t\t\ts += getBool('rmp', 'prefetch', false);\n\t\t\ts += getBool('rmp', 'shuffle', false);\n\t\t\ts += getStr('rmp', 'console');\n\t\t\ts += getStr('rmp', 'controls');\n\t\t\ts += getStr('rmp', 'numloop');\n\t\t\ts += getStr('rmp', 'scriptcallbacks');\n\t\tbreak;\n\t}\n\n\ts += getStr(null, 'id');\n\ts += getStr(null, 'name');\n\ts += getStr(null, 'src');\n\ts += getStr(null, 'align');\n\ts += getStr(null, 'bgcolor');\n\ts += getInt(null, 'vspace');\n\ts += getInt(null, 'hspace');\n\ts += getStr(null, 'width');\n\ts += getStr(null, 'height');\n\n\ts = s.length > 0 ? s.substring(0, s.length - 1) : s;\n\n\treturn s;\n}\n\nfunction setBool(pl, p, n) {\n\tif (typeof(pl[n]) == \"undefined\")\n\t\treturn;\n\n\tdocument.forms[0].elements[p + \"_\" + n].checked = pl[n] != 'false';\n}\n\nfunction setStr(pl, p, n) {\n\tvar f = document.forms[0], e = f.elements[(p != null ? p + \"_\" : '') + n];\n\n\tif (typeof(pl[n]) == \"undefined\")\n\t\treturn;\n\n\tif (e.type == \"text\")\n\t\te.value = pl[n];\n\telse\n\t\tselectByValue(f, (p != null ? p + \"_\" : '') + n, pl[n]);\n}\n\nfunction getBool(p, n, d, tv, fv) {\n\tvar v = document.forms[0].elements[p + \"_\" + n].checked;\n\n\ttv = typeof(tv) == 'undefined' ? 'true' : \"'\" + jsEncode(tv) + \"'\";\n\tfv = typeof(fv) == 'undefined' ? 'false' : \"'\" + jsEncode(fv) + \"'\";\n\n\treturn (v == d) ? '' : n + (v ? ':' + tv + ',' : \":\\'\" + fv + \"\\',\");\n}\n\nfunction getStr(p, n, d) {\n\tvar e = document.forms[0].elements[(p != null ? p + \"_\" : \"\") + n];\n\tvar v = e.type == \"text\" ? e.value : e.options[e.selectedIndex].value;\n\n\tif (n == 'src')\n\t\tv = tinyMCEPopup.editor.convertURL(v, 'src', null);\n\n\treturn ((n == d || v == '') ? '' : n + \":'\" + jsEncode(v) + \"',\");\n}\n\nfunction getInt(p, n, d) {\n\tvar e = document.forms[0].elements[(p != null ? p + \"_\" : \"\") + n];\n\tvar v = e.type == \"text\" ? e.value : e.options[e.selectedIndex].value;\n\n\treturn ((n == d || v == '') ? '' : n + \":\" + v.replace(/[^0-9]+/g, '') + \",\");\n}\n\nfunction jsEncode(s) {\n\ts = s.replace(new RegExp('\\\\\\\\', 'g'), '\\\\\\\\');\n\ts = s.replace(new RegExp('\"', 'g'), '\\\\\"');\n\ts = s.replace(new RegExp(\"'\", 'g'), \"\\\\'\");\n\n\treturn s;\n}\n\nfunction generatePreview(c) {\n\tvar f = document.forms[0], p = document.getElementById('prev'), h = '', cls, pl, n, type, codebase, wp, hp, nw, nh;\n\n\tp.innerHTML = '<!-- x --->';\n\n\tnw = parseInt(f.width.value);\n\tnh = parseInt(f.height.value);\n\n\tif (f.width.value != \"\" && f.height.value != \"\") {\n\t\tif (f.constrain.checked) {\n\t\t\tif (c == 'width' && oldWidth != 0) {\n\t\t\t\twp = nw / oldWidth;\n\t\t\t\tnh = Math.round(wp * nh);\n\t\t\t\tf.height.value = nh;\n\t\t\t} else if (c == 'height' && oldHeight != 0) {\n\t\t\t\thp = nh / oldHeight;\n\t\t\t\tnw = Math.round(hp * nw);\n\t\t\t\tf.width.value = nw;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (f.width.value != \"\")\n\t\toldWidth = nw;\n\n\tif (f.height.value != \"\")\n\t\toldHeight = nh;\n\n\t// After constrain\n\tpl = serializeParameters();\n\n\tswitch (f.media_type.options[f.media_type.selectedIndex].value) {\n\t\tcase \"flash\":\n\t\t\tcls = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';\n\t\t\tcodebase = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0';\n\t\t\ttype = 'application/x-shockwave-flash';\n\t\t\tbreak;\n\n\t\tcase \"shockwave\":\n\t\t\tcls = 'clsid:166B1BCA-3F9C-11CF-8075-444553540000';\n\t\t\tcodebase = 'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0';\n\t\t\ttype = 'application/x-director';\n\t\t\tbreak;\n\n\t\tcase \"qt\":\n\t\t\tcls = 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B';\n\t\t\tcodebase = 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0';\n\t\t\ttype = 'video/quicktime';\n\t\t\tbreak;\n\n\t\tcase \"wmp\":\n\t\t\tcls = ed.getParam('media_wmp6_compatible') ? 'clsid:05589FA1-C356-11CE-BF01-00AA0055595A' : 'clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6';\n\t\t\tcodebase = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701';\n\t\t\ttype = 'application/x-mplayer2';\n\t\t\tbreak;\n\n\t\tcase \"rmp\":\n\t\t\tcls = 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA';\n\t\t\tcodebase = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701';\n\t\t\ttype = 'audio/x-pn-realaudio-plugin';\n\t\t\tbreak;\n\t}\n\n\tif (pl == '') {\n\t\tp.innerHTML = '';\n\t\treturn;\n\t}\n\n\tpl = tinyMCEPopup.editor.plugins.media._parse(pl);\n\n\tif (!pl.src) {\n\t\tp.innerHTML = '';\n\t\treturn;\n\t}\n\n\tpl.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(pl.src);\n\tpl.width = !pl.width ? 100 : pl.width;\n\tpl.height = !pl.height ? 100 : pl.height;\n\tpl.id = !pl.id ? 'obj' : pl.id;\n\tpl.name = !pl.name ? 'eobj' : pl.name;\n\tpl.align = !pl.align ? '' : pl.align;\n\n\t// Avoid annoying warning about insecure items\n\tif (!tinymce.isIE || document.location.protocol != 'https:') {\n\t\th += '<object classid=\"' + cls + '\" codebase=\"' + codebase + '\" width=\"' + pl.width + '\" height=\"' + pl.height + '\" id=\"' + pl.id + '\" name=\"' + pl.name + '\" align=\"' + pl.align + '\">';\n\n\t\tfor (n in pl) {\n\t\t\th += '<param name=\"' + n + '\" value=\"' + pl[n] + '\">';\n\n\t\t\t// Add extra url parameter if it's an absolute URL\n\t\t\tif (n == 'src' && pl[n].indexOf('://') != -1)\n\t\t\t\th += '<param name=\"url\" value=\"' + pl[n] + '\" />';\n\t\t}\n\t}\n\n\th += '<embed type=\"' + type + '\" ';\n\n\tfor (n in pl)\n\t\th += n + '=\"' + pl[n] + '\" ';\n\n\th += '></embed>';\n\n\t// Avoid annoying warning about insecure items\n\tif (!tinymce.isIE || document.location.protocol != 'https:')\n\t\th += '</object>';\n\n\tp.innerHTML = \"<!-- x --->\" + h;\n}\n\ntinyMCEPopup.onInit.add(init);\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/media/langs/typecho_dlg.js",
    "content": "\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/media/media.htm",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n\t<title>{#media_dlg.title}</title>\n\t<script type=\"text/javascript\" src=\"../../tiny_mce_popup.js\"></script>\n\t<script type=\"text/javascript\" src=\"js/media.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/mctabs.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/validate.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/form_utils.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/editable_selects.js\"></script>\n\t<link href=\"css/media.css\" rel=\"stylesheet\" type=\"text/css\" />\n</head>\n<body style=\"display: none\">\n    <form onsubmit=\"insertMedia();return false;\" action=\"#\">\n\t\t<div class=\"tabs\">\n\t\t\t<ul>\n\t\t\t\t<li id=\"general_tab\" class=\"current\"><span><a href=\"javascript:mcTabs.displayTab('general_tab','general_panel');generatePreview();\" onmousedown=\"return false;\">{#media_dlg.general}</a></span></li>\n\t\t\t\t<li id=\"advanced_tab\"><span><a href=\"javascript:mcTabs.displayTab('advanced_tab','advanced_panel');\" onmousedown=\"return false;\">{#media_dlg.advanced}</a></span></li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<div class=\"panel_wrapper\">\n\t\t\t<div id=\"general_panel\" class=\"panel current\">\n\t\t\t\t<fieldset>\n\t\t\t\t\t<legend>{#media_dlg.general}</legend>\n\n\t\t\t\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td><label for=\"media_type\">{#media_dlg.type}</label></td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<select id=\"media_type\" name=\"media_type\" onchange=\"changedType(this.value);generatePreview();\">\n\t\t\t\t\t\t\t\t\t\t<option value=\"flash\">Flash</option>\n\t\t\t\t\t\t\t\t\t\t<!-- <option value=\"flv\">Flash video (FLV)</option> -->\n\t\t\t\t\t\t\t\t\t\t<option value=\"qt\">Quicktime</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"shockwave\">Shockwave</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"wmp\">Windows Media</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"rmp\">Real Media</option>\n\t\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"src\">{#media_dlg.file}</label></td>\n\t\t\t\t\t\t\t  <td>\n\t\t\t\t\t\t\t\t\t<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n\t\t\t\t\t\t\t\t\t  <tr>\n\t\t\t\t\t\t\t\t\t\t<td><input id=\"src\" name=\"src\" type=\"text\" value=\"\" class=\"mceFocus\" onchange=\"switchType(this.value);generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td id=\"filebrowsercontainer\">&nbsp;</td>\n\t\t\t\t\t\t\t\t\t  </tr>\n\t\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t<tr id=\"linklistrow\">\n\t\t\t\t\t\t\t\t<td><label for=\"linklist\">{#media_dlg.list}</label></td>\n\t\t\t\t\t\t\t\t<td id=\"linklistcontainer\"><select id=\"linklist\"><option value=\"\"></option></select></td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td><label for=\"width\">{#media_dlg.size}</label></td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t\t<td><input type=\"text\" id=\"width\" name=\"width\" value=\"\" class=\"size\" onchange=\"generatePreview('width');\" /> x <input type=\"text\" id=\"height\" name=\"height\" value=\"\" class=\"size\"  onchange=\"generatePreview('height');\" /></td>\n\t\t\t\t\t\t\t\t\t\t\t<td>&nbsp;&nbsp;<input id=\"constrain\" type=\"checkbox\" name=\"constrain\" class=\"checkbox\" /></td>\n\t\t\t\t\t\t\t\t\t\t\t<td><label id=\"constrainlabel\" for=\"constrain\">{#media_dlg.constrain_proportions}</label></td>\n\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t</table>\n\t\t\t\t</fieldset>\n\n\t\t\t\t<fieldset>\n\t\t\t\t\t<legend>{#media_dlg.preview}</legend>\n\t\t\t\t\t<div id=\"prev\"></div>\n\t\t\t\t</fieldset>\n\t\t\t</div>\n\n\t\t\t<div id=\"advanced_panel\" class=\"panel\">\n\t\t\t\t<fieldset>\n\t\t\t\t\t<legend>{#media_dlg.advanced}</legend>\n\n\t\t\t\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"id\">{#media_dlg.id}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"id\" name=\"id\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t<td><label for=\"name\">{#media_dlg.name}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"name\" name=\"name\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"align\">{#media_dlg.align}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"align\" name=\"align\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"\">{#not_set}</option> \n\t\t\t\t\t\t\t\t\t<option value=\"top\">{#media_dlg.align_top}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"right\">{#media_dlg.align_right}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"bottom\">{#media_dlg.align_bottom}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"left\">{#media_dlg.align_left}</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td><label for=\"bgcolor\">{#media_dlg.bgcolor}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input id=\"bgcolor\" name=\"bgcolor\" type=\"text\" value=\"\" size=\"9\" onchange=\"updateColor('bgcolor_pick','bgcolor');generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td id=\"bgcolor_pickcontainer\">&nbsp;</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"vspace\">{#media_dlg.vspace}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"vspace\" name=\"vspace\" class=\"number\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t<td><label for=\"hspace\">{#media_dlg.hspace}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"hspace\" name=\"hspace\" class=\"number\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</table>\n\t\t\t\t</fieldset>\n\n\t\t\t\t<fieldset id=\"flash_options\">\n\t\t\t\t\t<legend>{#media_dlg.flash_options}</legend>\n\n\t\t\t\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"flash_quality\">{#media_dlg.quality}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"flash_quality\" name=\"flash_quality\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"\">{#not_set}</option> \n\t\t\t\t\t\t\t\t\t<option value=\"high\">high</option>\n\t\t\t\t\t\t\t\t\t<option value=\"low\">low</option>\n\t\t\t\t\t\t\t\t\t<option value=\"autolow\">autolow</option>\n\t\t\t\t\t\t\t\t\t<option value=\"autohigh\">autohigh</option>\n\t\t\t\t\t\t\t\t\t<option value=\"best\">best</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td><label for=\"flash_scale\">{#media_dlg.scale}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"flash_scale\" name=\"flash_scale\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"\">{#not_set}</option> \n\t\t\t\t\t\t\t\t\t<option value=\"showall\">showall</option>\n\t\t\t\t\t\t\t\t\t<option value=\"noborder\">noborder</option>\n\t\t\t\t\t\t\t\t\t<option value=\"exactfit\">exactfit</option>\n\t\t\t\t\t\t\t\t\t<option value=\"noscale\">noscale</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"flash_wmode\">{#media_dlg.wmode}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"flash_wmode\" name=\"flash_wmode\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"\">{#not_set}</option> \n\t\t\t\t\t\t\t\t\t<option value=\"window\">window</option>\n\t\t\t\t\t\t\t\t\t<option value=\"opaque\">opaque</option>\n\t\t\t\t\t\t\t\t\t<option value=\"transparent\">transparent</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td><label for=\"flash_salign\">{#media_dlg.salign}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"flash_salign\" name=\"flash_salign\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"\">{#not_set}</option> \n\t\t\t\t\t\t\t\t\t<option value=\"l\">{#media_dlg.align_left}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"t\">{#media_dlg.align_top}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"r\">{#media_dlg.align_right}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"b\">{#media_dlg.align_bottom}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"tl\">{#media_dlg.align_top_left}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"tr\">{#media_dlg.align_top_right}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"bl\">{#media_dlg.align_bottom_left}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"br\">{#media_dlg.align_bottom_right}</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flash_play\" name=\"flash_play\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flash_play\">{#media_dlg.play}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flash_loop\" name=\"flash_loop\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flash_loop\">{#media_dlg.loop}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flash_menu\" name=\"flash_menu\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flash_menu\">{#media_dlg.menu}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flash_swliveconnect\" name=\"flash_swliveconnect\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flash_swliveconnect\">{#media_dlg.liveconnect}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</table>\n\n\t\t\t\t\t<table>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"flash_base\">{#media_dlg.base}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"flash_base\" name=\"flash_base\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"flash_flashvars\">{#media_dlg.flashvars}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"flash_flashvars\" name=\"flash_flashvars\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</table>\n\t\t\t\t</fieldset>\n\n\t\t\t\t<fieldset id=\"flv_options\">\n\t\t\t\t\t<legend>{#media_dlg.flv_options}</legend>\n\n\t\t\t\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"flv_scalemode\">{#media_dlg.flv_scalemode}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"flv_scalemode\" name=\"flv_scalemode\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"\">{#not_set}</option> \n\t\t\t\t\t\t\t\t\t<option value=\"none\">none</option>\n\t\t\t\t\t\t\t\t\t<option value=\"double\">double</option>\n\t\t\t\t\t\t\t\t\t<option value=\"full\">full</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td><label for=\"flv_buffer\">{#media_dlg.flv_buffer}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"flv_buffer\" name=\"flv_buffer\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"flv_startimage\">{#media_dlg.flv_startimage}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"flv_startimage\" name=\"flv_startimage\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"flv_starttime\">{#media_dlg.flv_starttime}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"flv_starttime\" name=\"flv_starttime\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"flv_defaultvolume\">{#media_dlg.flv_defaultvolume}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"flv_defaultvolume\" name=\"flv_defaultvolume\" onchange=\"generatePreview();\" /></td>\n\n\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flv_hiddengui\" name=\"flv_hiddengui\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flv_hiddengui\">{#media_dlg.flv_hiddengui}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flv_autostart\" name=\"flv_autostart\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flv_autostart\">{#media_dlg.flv_autostart}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flv_loop\" name=\"flv_loop\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flv_loop\">{#media_dlg.flv_loop}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flv_showscalemodes\" name=\"flv_showscalemodes\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flv_showscalemodes\">{#media_dlg.flv_showscalemodes}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flv_smoothvideo\" name=\"flash_flv_flv_smoothvideosmoothvideo\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flv_smoothvideo\">{#media_dlg.flv_smoothvideo}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"flv_jscallback\" name=\"flv_jscallback\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"flv_jscallback\">{#media_dlg.flv_jscallback}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</table>\n\t\t\t\t</fieldset>\n\n\t\t\t\t<fieldset id=\"qt_options\">\n\t\t\t\t\t<legend>{#media_dlg.qt_options}</legend>\n\n\t\t\t\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_loop\" name=\"qt_loop\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_loop\">{#media_dlg.loop}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_autoplay\" name=\"qt_autoplay\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_autoplay\">{#media_dlg.play}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_cache\" name=\"qt_cache\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_cache\">{#media_dlg.cache}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_controller\" name=\"qt_controller\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_controller\">{#media_dlg.controller}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_correction\" name=\"qt_correction\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_correction\">{#media_dlg.correction}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_enablejavascript\" name=\"qt_enablejavascript\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_enablejavascript\">{#media_dlg.enablejavascript}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_kioskmode\" name=\"qt_kioskmode\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_kioskmode\">{#media_dlg.kioskmode}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_autohref\" name=\"qt_autohref\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_autohref\">{#media_dlg.autohref}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_playeveryframe\" name=\"qt_playeveryframe\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_playeveryframe\">{#media_dlg.playeveryframe}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"qt_targetcache\" name=\"qt_targetcache\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"qt_targetcache\">{#media_dlg.targetcache}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"qt_scale\">{#media_dlg.scale}</label></td>\n\t\t\t\t\t\t\t<td><select id=\"qt_scale\" name=\"qt_scale\" class=\"mceEditableSelect\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"\">{#not_set}</option> \n\t\t\t\t\t\t\t\t\t<option value=\"tofit\">tofit</option>\n\t\t\t\t\t\t\t\t\t<option value=\"aspect\">aspect</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">&nbsp;</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"qt_starttime\">{#media_dlg.starttime}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"qt_starttime\" name=\"qt_starttime\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"qt_endtime\">{#media_dlg.endtime}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"qt_endtime\" name=\"qt_endtime\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"qt_target\">{#media_dlg.target}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"qt_target\" name=\"qt_target\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"qt_href\">{#media_dlg.href}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"qt_href\" name=\"qt_href\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"qt_qtsrcchokespeed\">{#media_dlg.qtsrcchokespeed}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"qt_qtsrcchokespeed\" name=\"qt_qtsrcchokespeed\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"qt_volume\">{#media_dlg.volume}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"qt_volume\" name=\"qt_volume\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"qt_qtsrc\">{#media_dlg.qtsrc}</label></td>\n\t\t\t\t\t\t\t<td colspan=\"4\">\n\t\t\t\t\t\t\t<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n\t\t\t\t\t\t\t\t  <tr>\n\t\t\t\t\t\t\t\t\t<td><input type=\"text\" id=\"qt_qtsrc\" name=\"qt_qtsrc\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t<td id=\"qtsrcfilebrowsercontainer\">&nbsp;</td>\n\t\t\t\t\t\t\t\t  </tr>\n\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</table>\n\t\t\t\t</fieldset>\n\n\t\t\t\t<fieldset id=\"wmp_options\">\n\t\t\t\t\t<legend>{#media_dlg.wmp_options}</legend>\n\n\t\t\t\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"wmp_autostart\" name=\"wmp_autostart\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"wmp_autostart\">{#media_dlg.autostart}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"wmp_enabled\" name=\"wmp_enabled\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"wmp_enabled\">{#media_dlg.enabled}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"wmp_enablecontextmenu\" name=\"wmp_enablecontextmenu\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"wmp_enablecontextmenu\">{#media_dlg.menu}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"wmp_fullscreen\" name=\"wmp_fullscreen\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"wmp_fullscreen\">{#media_dlg.fullscreen}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"wmp_invokeurls\" name=\"wmp_invokeurls\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"wmp_invokeurls\">{#media_dlg.invokeurls}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"wmp_mute\" name=\"wmp_mute\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"wmp_mute\">{#media_dlg.mute}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"wmp_stretchtofit\" name=\"wmp_stretchtofit\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"wmp_stretchtofit\">{#media_dlg.stretchtofit}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"wmp_windowlessvideo\" name=\"wmp_windowlessvideo\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"wmp_windowlessvideo\">{#media_dlg.windowlessvideo}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"wmp_balance\">{#media_dlg.balance}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_balance\" name=\"wmp_balance\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"wmp_baseurl\">{#media_dlg.baseurl}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_baseurl\" name=\"wmp_baseurl\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"wmp_captioningid\">{#media_dlg.captioningid}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_captioningid\" name=\"wmp_captioningid\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"wmp_currentmarker\">{#media_dlg.currentmarker}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_currentmarker\" name=\"wmp_currentmarker\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"wmp_currentposition\">{#media_dlg.currentposition}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_currentposition\" name=\"wmp_currentposition\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"wmp_defaultframe\">{#media_dlg.defaultframe}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_defaultframe\" name=\"wmp_defaultframe\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"wmp_playcount\">{#media_dlg.playcount}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_playcount\" name=\"wmp_playcount\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"wmp_rate\">{#media_dlg.rate}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_rate\" name=\"wmp_rate\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"wmp_uimode\">{#media_dlg.uimode}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_uimode\" name=\"wmp_uimode\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"wmp_volume\">{#media_dlg.volume}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"wmp_volume\" name=\"wmp_volume\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t</table>\n\t\t\t\t</fieldset>\n\n\t\t\t\t<fieldset id=\"rmp_options\">\n\t\t\t\t\t<legend>{#media_dlg.rmp_options}</legend>\n\n\t\t\t\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_autostart\" name=\"rmp_autostart\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_autostart\">{#media_dlg.autostart}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_loop\" name=\"rmp_loop\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_loop\">{#media_dlg.loop}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_autogotourl\" name=\"rmp_autogotourl\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_autogotourl\">{#media_dlg.autogotourl}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_center\" name=\"rmp_center\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_center\">{#media_dlg.center}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_imagestatus\" name=\"rmp_imagestatus\" checked=\"checked\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_imagestatus\">{#media_dlg.imagestatus}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_maintainaspect\" name=\"rmp_maintainaspect\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_maintainaspect\">{#media_dlg.maintainaspect}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_nojava\" name=\"rmp_nojava\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_nojava\">{#media_dlg.nojava}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_prefetch\" name=\"rmp_prefetch\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_prefetch\">{#media_dlg.prefetch}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"rmp_shuffle\" name=\"rmp_shuffle\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"rmp_shuffle\">{#media_dlg.shuffle}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t&nbsp;\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"rmp_console\">{#media_dlg.console}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"rmp_console\" name=\"rmp_console\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"rmp_controls\">{#media_dlg.controls}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"rmp_controls\" name=\"rmp_controls\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"rmp_numloop\">{#media_dlg.numloop}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"rmp_numloop\" name=\"rmp_numloop\" onchange=\"generatePreview();\" /></td>\n\n\t\t\t\t\t\t\t<td><label for=\"rmp_scriptcallbacks\">{#media_dlg.scriptcallbacks}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"rmp_scriptcallbacks\" name=\"rmp_scriptcallbacks\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</table>\n\t\t\t\t</fieldset>\n\n\t\t\t\t<fieldset id=\"shockwave_options\">\n\t\t\t\t\t<legend>{#media_dlg.shockwave_options}</legend>\n\n\t\t\t\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"shockwave_swstretchstyle\">{#media_dlg.swstretchstyle}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"shockwave_swstretchstyle\" name=\"shockwave_swstretchstyle\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"none\">{#not_set}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"meet\">Meet</option>\n\t\t\t\t\t\t\t\t\t<option value=\"fill\">Fill</option>\n\t\t\t\t\t\t\t\t\t<option value=\"stage\">Stage</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td><label for=\"shockwave_swvolume\">{#media_dlg.volume}</label></td>\n\t\t\t\t\t\t\t<td><input type=\"text\" id=\"shockwave_swvolume\" name=\"shockwave_swvolume\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td><label for=\"shockwave_swstretchhalign\">{#media_dlg.swstretchhalign}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"shockwave_swstretchhalign\" name=\"shockwave_swstretchhalign\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"none\">{#not_set}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"left\">{#media_dlg.align_left}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"center\">{#media_dlg.align_center}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"right\">{#media_dlg.align_right}</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td><label for=\"shockwave_swstretchvalign\">{#media_dlg.swstretchvalign}</label></td>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<select id=\"shockwave_swstretchvalign\" name=\"shockwave_swstretchvalign\" onchange=\"generatePreview();\">\n\t\t\t\t\t\t\t\t\t<option value=\"none\">{#not_set}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"meet\">Meet</option>\n\t\t\t\t\t\t\t\t\t<option value=\"fill\">Fill</option>\n\t\t\t\t\t\t\t\t\t<option value=\"stage\">Stage</option>\n\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"shockwave_autostart\" name=\"shockwave_autostart\" onchange=\"generatePreview();\" checked=\"checked\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"shockwave_autostart\">{#media_dlg.autostart}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"shockwave_sound\" name=\"shockwave_sound\" onchange=\"generatePreview();\" checked=\"checked\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"shockwave_sound\">{#media_dlg.sound}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\n\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"shockwave_swliveconnect\" name=\"shockwave_swliveconnect\" onchange=\"generatePreview();\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"shockwave_swliveconnect\">{#media_dlg.liveconnect}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\n\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td><input type=\"checkbox\" class=\"checkbox\" id=\"shockwave_progress\" name=\"shockwave_progress\" onchange=\"generatePreview();\" checked=\"checked\" /></td>\n\t\t\t\t\t\t\t\t\t\t<td><label for=\"shockwave_progress\">{#media_dlg.progress}</label></td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</table>\n\t\t\t\t</fieldset>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"mceActionPanel\">\n\t\t\t<div style=\"float: left\">\n\t\t\t\t<input type=\"submit\" id=\"insert\" name=\"insert\" value=\"{#insert}\" />\n\t\t\t</div>\n\n\t\t\t<div style=\"float: right\">\n\t\t\t\t<input type=\"button\" id=\"cancel\" name=\"cancel\" value=\"{#cancel}\" onclick=\"tinyMCEPopup.close();\" />\n\t\t\t</div>\n\t\t</div>\n\t</form>\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/morebreak/css/content.css",
    "content": ".mceMoreBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../img/morebreak.gif) no-repeat center top;}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/morebreak/editor_plugin.js",
    "content": "/**\n * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $\n *\n * @author Moxiecode\n * @copyright Copyright  2004-2008, Moxiecode Systems AB, All rights reserved.\n */\n\n(function() {\n\ttinymce.create('tinymce.plugins.MoreBreakPlugin', {\n\t\tinit : function(ed, url) {\n\t\t\tvar pb = '<img src=\"' + url + '/img/trans.gif\" class=\"mceMoreBreak mceItemNoResize\" />', cls = 'mceMoreBreak', sep = ed.getParam('morebreak_separator', '<!--more-->'), pbRE;\n\n\t\t\tpbRE = new RegExp(sep.replace(/[\\?\\.\\*\\[\\]\\(\\)\\{\\}\\+\\^\\$\\:]/g, function(a) {return '\\\\' + a;}), 'g');\n\n\t\t\t// Register commands\n\t\t\ted.addCommand('mceMoreBreak', function() {\n\t\t\t\ted.execCommand('mceInsertContent', 0, pb);\n\t\t\t});\n\n\t\t\t// Register buttons\n\t\t\ted.addButton('morebreak', {title : 'morebreak.desc', cmd : cls});\n\n\t\t\ted.onInit.add(function() {\n\t\t\t\tif (ed.settings.content_css !== false)\n\t\t\t\t\ted.dom.loadCSS(url + \"/css/content.css\");\n\n\t\t\t\tif (ed.theme.onResolveName) {\n\t\t\t\t\ted.theme.onResolveName.add(function(th, o) {\n\t\t\t\t\t\tif (o.node.nodeName == 'IMG' && ed.dom.hasClass(o.node, cls))\n\t\t\t\t\t\t\to.name = 'morebreak';\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\ted.onClick.add(function(ed, e) {\n\t\t\t\te = e.target;\n\n\t\t\t\tif (e.nodeName === 'IMG' && ed.dom.hasClass(e, cls))\n\t\t\t\t\ted.selection.select(e);\n\t\t\t});\n\n\t\t\ted.onNodeChange.add(function(ed, cm, n) {\n\t\t\t\tcm.setActive('morebreak', n.nodeName === 'IMG' && ed.dom.hasClass(n, cls));\n\t\t\t});\n\n\t\t\ted.onBeforeSetContent.add(function(ed, o) {\n\t\t\t\to.content = o.content.replace(pbRE, pb);\n\t\t\t});\n\n\t\t\ted.onPostProcess.add(function(ed, o) {\n\t\t\t\tif (o.get)\n\t\t\t\t\to.content = o.content.replace(/<img[^>]+>/g, function(im) {\n\t\t\t\t\t\tif (im.indexOf('class=\"mceMoreBreak') !== -1)\n\t\t\t\t\t\t\tim = sep;\n\n\t\t\t\t\t\treturn im;\n\t\t\t\t\t});\n\t\t\t});\n\t\t},\n\n\t\tgetInfo : function() {\n\t\t\treturn {\n\t\t\t\tlongname : 'MoreBreak',\n\t\t\t\tauthor : 'Moxiecode Systems AB',\n\t\t\t\tauthorurl : 'http://tinymce.moxiecode.com',\n\t\t\t\tinfourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/morebreak',\n\t\t\t\tversion : tinymce.majorVersion + \".\" + tinymce.minorVersion\n\t\t\t};\n\t\t}\n\t});\n\n\t// Register plugin\n\ttinymce.PluginManager.add('morebreak', tinymce.plugins.MoreBreakPlugin);\n})();\n"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/safari/blank.htm",
    "content": "<!-- WebKit -->"
  },
  {
    "path": "TinyMCE/tiny_mce/plugins/safari/editor_plugin.js",
    "content": "(function(){var a=tinymce.dom.Event,c=tinymce.grep,d=tinymce.each,b=tinymce.inArray;function e(j,i,h){var g,k;g=j.createTreeWalker(i,NodeFilter.SHOW_ALL,null,false);while(k=g.nextNode()){if(h){if(!h(k)){return false}}if(k.nodeType==3&&k.nodeValue&&/[^\\s\\u00a0]+/.test(k.nodeValue)){return false}if(k.nodeType==1&&/^(HR|IMG|TABLE)$/.test(k.nodeName)){return false}}return true}tinymce.create(\"tinymce.plugins.Safari\",{init:function(f){var g=this,h;if(!tinymce.isWebKit){return}g.editor=f;g.webKitFontSizes=[\"x-small\",\"small\",\"medium\",\"large\",\"x-large\",\"xx-large\",\"-webkit-xxx-large\"];g.namedFontSizes=[\"xx-small\",\"x-small\",\"small\",\"medium\",\"large\",\"x-large\",\"xx-large\"];f.addCommand(\"CreateLink\",function(k,j){var m=f.selection.getNode(),l=f.dom,i;if(m&&(/^(left|right)$/i.test(l.getStyle(m,\"float\",1))||/^(left|right)$/i.test(l.getAttrib(m,\"align\")))){i=l.create(\"a\",{href:j},m.cloneNode());m.parentNode.replaceChild(i,m);f.selection.select(i)}else{f.getDoc().execCommand(\"CreateLink\",false,j)}});f.onKeyUp.add(function(j,o){var l,i,m,p,k;if(o.keyCode==46||o.keyCode==8){i=j.getBody();l=i.innerHTML;k=j.selection;if(i.childNodes.length==1&&!/<(img|hr)/.test(l)&&tinymce.trim(l.replace(/<[^>]+>/g,\"\")).length==0){j.setContent('<p><br mce_bogus=\"1\" /></p>',{format:\"raw\"});p=i.firstChild;m=k.getRng();m.setStart(p,0);m.setEnd(p,0);k.setRng(m)}}});f.addCommand(\"FormatBlock\",function(j,i){var l=f.dom,k=l.getParent(f.selection.getNode(),l.isBlock);if(k){l.replace(l.create(i),k,1)}else{f.getDoc().execCommand(\"FormatBlock\",false,i)}});f.addCommand(\"mceInsertContent\",function(j,i){f.getDoc().execCommand(\"InsertText\",false,\"mce_marker\");f.getBody().innerHTML=f.getBody().innerHTML.replace(/mce_marker/g,f.dom.processHTML(i)+'<span id=\"_mce_tmp\">XX</span>');f.selection.select(f.dom.get(\"_mce_tmp\"));f.getDoc().execCommand(\"Delete\",false,\" \")});f.onKeyPress.add(function(o,p){var q,v,r,l,j,k,i,u,m,t,s;if(p.keyCode==13){i=o.selection;q=i.getNode();if(p.shiftKey||o.settings.force_br_newlines&&q.nodeName!=\"LI\"){g._insertBR(o);a.cancel(p)}if(v=h.getParent(q,\"LI\")){r=h.getParent(v,\"OL,UL\");u=o.getDoc();s=h.create(\"p\");h.add(s,\"br\",{mce_bogus:\"1\"});if(e(u,v)){if(k=h.getParent(r.parentNode,\"LI,OL,UL\")){return}k=h.getParent(r,\"p,h1,h2,h3,h4,h5,h6,div\")||r;l=u.createRange();l.setStartBefore(k);l.setEndBefore(v);j=u.createRange();j.setStartAfter(v);j.setEndAfter(k);m=l.cloneContents();t=j.cloneContents();if(!e(u,t)){h.insertAfter(t,k)}h.insertAfter(s,k);if(!e(u,m)){h.insertAfter(m,k)}h.remove(k);k=s.firstChild;l=u.createRange();l.setStartBefore(k);l.setEndBefore(k);i.setRng(l);return a.cancel(p)}}}});f.onExecCommand.add(function(i,k){var j,m,n,l;if(k==\"InsertUnorderedList\"||k==\"InsertOrderedList\"){j=i.selection;m=i.dom;if(n=m.getParent(j.getNode(),function(o){return/^(H[1-6]|P|ADDRESS|PRE)$/.test(o.nodeName)})){l=j.getBookmark();m.remove(n,1);j.moveToBookmark(l)}}});f.onClick.add(function(i,j){j=j.target;if(j.nodeName==\"IMG\"){g.selElm=j;i.selection.select(j)}else{g.selElm=null}});f.onInit.add(function(){g._fixWebKitSpans()});f.onSetContent.add(function(){h=f.dom;d([\"strong\",\"b\",\"em\",\"u\",\"strike\",\"sub\",\"sup\",\"a\"],function(i){d(c(h.select(i)).reverse(),function(l){var k=l.nodeName.toLowerCase(),j;if(k==\"a\"){if(l.name){h.replace(h.create(\"img\",{mce_name:\"a\",name:l.name,\"class\":\"mceItemAnchor\"}),l)}return}switch(k){case\"b\":case\"strong\":if(k==\"b\"){k=\"strong\"}j=\"font-weight: bold;\";break;case\"em\":j=\"font-style: italic;\";break;case\"u\":j=\"text-decoration: underline;\";break;case\"sub\":j=\"vertical-align: sub;\";break;case\"sup\":j=\"vertical-align: super;\";break;case\"strike\":j=\"text-decoration: line-through;\";break}h.replace(h.create(\"span\",{mce_name:k,style:j,\"class\":\"Apple-style-span\"}),l,1)})})});f.onPreProcess.add(function(i,j){h=i.dom;d(c(j.node.getElementsByTagName(\"span\")).reverse(),function(m){var k,l;if(j.get){if(h.hasClass(m,\"Apple-style-span\")){l=m.style.backgroundColor;switch(h.getAttrib(m,\"mce_name\")){case\"font\":if(!i.settings.convert_fonts_to_spans){h.setAttrib(m,\"style\",\"\")}break;case\"strong\":case\"em\":case\"sub\":case\"sup\":h.setAttrib(m,\"style\",\"\");break;case\"strike\":case\"u\":if(!i.settings.inline_styles){h.setAttrib(m,\"style\",\"\")}else{h.setAttrib(m,\"mce_name\",\"\")}break;default:if(!i.settings.inline_styles){h.setAttrib(m,\"style\",\"\")}}if(l){m.style.backgroundColor=l}}}if(h.hasClass(m,\"mceItemRemoved\")){h.remove(m,1)}})});f.onPostProcess.add(function(i,j){j.content=j.content.replace(/<br \\/><\\/(h[1-6]|div|p|address|pre)>/g,\"</$1>\");j.content=j.content.replace(/ id=\\\"undefined\\\"/g,\"\")})},getInfo:function(){return{longname:\"Safari compatibility\",author:\"Moxiecode Systems AB\",authorurl:\"http://tinymce.moxiecode.com\",infourl:\"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/safari\",version:tinymce.majorVersion+\".\"+tinymce.minorVersion}},_fixWebKitSpans:function(){var g=this,f=g.editor;a.add(f.getDoc(),\"DOMNodeInserted\",function(h){h=h.target;if(h&&h.nodeType==1){g._fixAppleSpan(h)}})},_fixAppleSpan:function(l){var g=this.editor,m=g.dom,i=this.webKitFontSizes,f=this.namedFontSizes,j=g.settings,h,k;if(m.getAttrib(l,\"mce_fixed\")){return}if(l.nodeName==\"SPAN\"&&l.className==\"Apple-style-span\"){h=l.style;if(!j.convert_fonts_to_spans){if(h.fontSize){m.setAttrib(l,\"mce_name\",\"font\");m.setAttrib(l,\"size\",b(i,h.fontSize)+1)}if(h.fontFamily){m.setAttrib(l,\"mce_name\",\"font\");m.setAttrib(l,\"face\",h.fontFamily)}if(h.color){m.setAttrib(l,\"mce_name\",\"font\");m.setAttrib(l,\"color\",m.toHex(h.color))}if(h.backgroundColor){m.setAttrib(l,\"mce_name\",\"font\");m.setStyle(l,\"background-color\",h.backgroundColor)}}else{if(h.fontSize){m.setStyle(l,\"fontSize\",f[b(i,h.fontSize)])}}if(h.fontWeight==\"bold\"){m.setAttrib(l,\"mce_name\",\"strong\")}if(h.fontStyle==\"italic\"){m.setAttrib(l,\"mce_name\",\"em\")}if(h.textDecoration==\"underline\"){m.setAttrib(l,\"mce_name\",\"u\")}if(h.textDecoration==\"line-through\"){m.setAttrib(l,\"mce_name\",\"strike\")}if(h.verticalAlign==\"super\"){m.setAttrib(l,\"mce_name\",\"sup\")}if(h.verticalAlign==\"sub\"){m.setAttrib(l,\"mce_name\",\"sub\")}m.setAttrib(l,\"mce_fixed\",\"1\")}},_insertBR:function(f){var j=f.dom,h=f.selection,i=h.getRng(),g;i.insertNode(g=j.create(\"br\"));i.setStartAfter(g);i.setEndAfter(g);h.setRng(i);if(h.getSel().focusNode==g.previousSibling){h.select(j.insertAfter(j.doc.createTextNode(\"\\u00a0\"),g));h.collapse(1)}f.getWin().scrollTo(0,j.getPos(h.getRng().startContainer).y)}});tinymce.PluginManager.add(\"safari\",tinymce.plugins.Safari)})();"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/about.htm",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> \n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n\t<title>{#advanced_dlg.about_title}</title>\n\t<script type=\"text/javascript\" src=\"../../tiny_mce_popup.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/mctabs.js\"></script>\n\t<script type=\"text/javascript\" src=\"js/about.js\"></script>\n</head>\n<body id=\"about\" style=\"display: none\">\n\t\t<div class=\"tabs\">\n\t\t\t<ul>\n\t\t\t\t<li id=\"general_tab\" class=\"current\"><span><a href=\"javascript:mcTabs.displayTab('general_tab','general_panel');\" onmousedown=\"return false;\">{#advanced_dlg.about_general}</a></span></li>\n\t\t\t\t<li id=\"help_tab\" style=\"display:none\"><span><a href=\"javascript:mcTabs.displayTab('help_tab','help_panel');\" onmousedown=\"return false;\">{#advanced_dlg.about_help}</a></span></li>\n\t\t\t\t<li id=\"plugins_tab\"><span><a href=\"javascript:mcTabs.displayTab('plugins_tab','plugins_panel');\" onmousedown=\"return false;\">{#advanced_dlg.about_plugins}</a></span></li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<div class=\"panel_wrapper\">\n\t\t\t<div id=\"general_panel\" class=\"panel current\">\n\t\t\t\t<h3>{#advanced_dlg.about_title}</h3>\n\t\t\t\t<p>Version: <span id=\"version\"></span> (<span id=\"date\"></span>)</p>\n\t\t\t\t<p>TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under <a href=\"../../license.txt\" target=\"_blank\">LGPL</a>\n\t\t\t\tby Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.</p>\n\t\t\t\t<p>Copyright &copy; 2003-2008, <a href=\"http://www.moxiecode.com\" target=\"_blank\">Moxiecode Systems AB</a>, All rights reserved.</p>\n\t\t\t\t<p>For more information about this software visit the <a href=\"http://tinymce.moxiecode.com\" target=\"_blank\">TinyMCE website</a>.</p>\n\n\t\t\t\t<div id=\"buttoncontainer\">\n\t\t\t\t\t<a href=\"http://www.moxiecode.com\" target=\"_blank\"><img src=\"http://tinymce.moxiecode.com/images/gotmoxie.png\" alt=\"Got Moxie?\" border=\"0\" /></a>\n\t\t\t\t\t<a href=\"http://sourceforge.net/projects/tinymce/\" target=\"_blank\"><img src=\"http://sourceforge.net/sflogo.php?group_id=103281\" alt=\"Hosted By Sourceforge\" border=\"0\" /></a>\n\t\t\t\t\t<a href=\"http://www.freshmeat.net/projects/tinymce\" target=\"_blank\"><img src=\"http://tinymce.moxiecode.com/images/fm.gif\" alt=\"Also on freshmeat\" border=\"0\" /></a>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div id=\"plugins_panel\" class=\"panel\">\n\t\t\t\t<div id=\"pluginscontainer\">\n\t\t\t\t\t<h3>{#advanced_dlg.about_loaded}</h3>\n\n\t\t\t\t\t<div id=\"plugintablecontainer\">\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>&nbsp;</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div id=\"help_panel\" class=\"panel noscroll\" style=\"overflow: visible;\">\n\t\t\t\t<div id=\"iframecontainer\"></div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"mceActionPanel\">\n\t\t\t<div style=\"float: right\">\n\t\t\t\t<input type=\"button\" id=\"cancel\" name=\"cancel\" value=\"{#close}\" onclick=\"tinyMCEPopup.close();\" />\n\t\t\t</div>\n\t\t</div>\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/anchor.htm",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n\t<title>{#advanced_dlg.anchor_title}</title>\n\t<script type=\"text/javascript\" src=\"../../tiny_mce_popup.js\"></script>\n\t<script type=\"text/javascript\" src=\"js/anchor.js\"></script>\n</head>\n<body style=\"display: none\">\n<form onsubmit=\"AnchorDialog.update();return false;\" action=\"#\">\n\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n\t\t<tr>\n\t\t\t<td colspan=\"2\" class=\"title\">{#advanced_dlg.anchor_title}</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td class=\"nowrap\">{#advanced_dlg.anchor_name}:</td>\n\t\t\t<td><input name=\"anchorName\" type=\"text\" class=\"mceFocus\" id=\"anchorName\" value=\"\" style=\"width: 200px\" /></td>\n\t\t</tr>\n\t</table>\n\n\t<div class=\"mceActionPanel\">\n\t\t<div style=\"float: left\">\n\t\t\t<input type=\"submit\" id=\"insert\" name=\"insert\" value=\"{#update}\" />\n\t\t</div>\n\n\t\t<div style=\"float: right\">\n\t\t\t<input type=\"button\" id=\"cancel\" name=\"cancel\" value=\"{#cancel}\" onclick=\"tinyMCEPopup.close();\" />\n\t\t</div>\n\t</div>\n</form>\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/charmap.htm",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n\t<title>{#advanced_dlg.charmap_title}</title>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\" />\n\t<script type=\"text/javascript\" src=\"../../tiny_mce_popup.js\"></script>\n\t<script type=\"text/javascript\" src=\"js/charmap.js\"></script>\n</head>\n<body id=\"charmap\" style=\"display:none\">\n<table align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">\n    <tr>\n        <td colspan=\"2\" class=\"title\">{#advanced_dlg.charmap_title}</td>\n    </tr>\n    <tr>\n        <td id=\"charmapView\" rowspan=\"2\" align=\"left\" valign=\"top\">\n\t\t\t<!-- Chars will be rendered here -->\n        </td>\n        <td width=\"100\" align=\"center\" valign=\"top\">\n            <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100\" style=\"height:100px\">\n                <tr>\n                    <td id=\"codeV\">&nbsp;</td>\n                </tr>\n                <tr>\n                    <td id=\"codeN\">&nbsp;</td>\n                </tr>\n            </table>\n        </td>\n    </tr>\n    <tr>\n        <td valign=\"bottom\" style=\"padding-bottom: 3px;\">\n            <table width=\"100\" align=\"center\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\">\n                <tr>\n                    <td align=\"center\" style=\"border-left: 1px solid #666699; border-top: 1px solid #666699; border-right: 1px solid #666699;\">HTML-Code</td>\n                </tr>\n                <tr>\n                    <td style=\"font-size: 16px; font-weight: bold; border-left: 1px solid #666699; border-bottom: 1px solid #666699; border-right: 1px solid #666699;\" id=\"codeA\" align=\"center\">&nbsp;</td>\n                </tr>\n                <tr>\n                    <td style=\"font-size: 1px;\">&nbsp;</td>\n                </tr>\n                <tr>\n                    <td align=\"center\" style=\"border-left: 1px solid #666699; border-top: 1px solid #666699; border-right: 1px solid #666699;\">NUM-Code</td>\n                </tr>\n                <tr>\n                    <td style=\"font-size: 16px; font-weight: bold; border-left: 1px solid #666699; border-bottom: 1px solid #666699; border-right: 1px solid #666699;\" id=\"codeB\" align=\"center\">&nbsp;</td>\n                </tr>\n            </table>\n        </td>\n    </tr>\n</table>\n\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/color_picker.htm",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n\t<title>{#advanced_dlg.colorpicker_title}</title>\n\t<script type=\"text/javascript\" src=\"../../tiny_mce_popup.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/mctabs.js\"></script>\n\t<script type=\"text/javascript\" src=\"js/color_picker.js\"></script>\n</head>\n<body id=\"colorpicker\" style=\"display: none\">\n<form onsubmit=\"insertAction();return false\" action=\"#\">\n\t<div class=\"tabs\">\n\t\t<ul>\n\t\t\t<li id=\"picker_tab\" class=\"current\"><span><a href=\"javascript:mcTabs.displayTab('picker_tab','picker_panel');\" onmousedown=\"return false;\">{#advanced_dlg.colorpicker_picker_tab}</a></span></li>\n\t\t\t<li id=\"rgb_tab\"><span><a href=\"javascript:;\" onclick=\"generateWebColors();mcTabs.displayTab('rgb_tab','rgb_panel');\" onmousedown=\"return false;\">{#advanced_dlg.colorpicker_palette_tab}</a></span></li>\n\t\t\t<li id=\"named_tab\"><span><a  href=\"javascript:;\" onclick=\"generateNamedColors();javascript:mcTabs.displayTab('named_tab','named_panel');\" onmousedown=\"return false;\">{#advanced_dlg.colorpicker_named_tab}</a></span></li>\n\t\t</ul>\n\t</div>\n\n\t<div class=\"panel_wrapper\">\n\t\t<div id=\"picker_panel\" class=\"panel current\">\n\t\t\t<fieldset>\n\t\t\t\t<legend>{#advanced_dlg.colorpicker_picker_title}</legend>\n\t\t\t\t<div id=\"picker\">\n\t\t\t\t\t<img id=\"colors\" src=\"img/colorpicker.jpg\" onclick=\"computeColor(event)\" onmousedown=\"isMouseDown = true;return false;\" onmouseup=\"isMouseDown = false;\" onmousemove=\"if (isMouseDown && isMouseOver) computeColor(event); return false;\" onmouseover=\"isMouseOver=true;\" onmouseout=\"isMouseOver=false;\" alt=\"\" />\n\n\t\t\t\t\t<div id=\"light\">\n\t\t\t\t\t\t<!-- Will be filled with divs -->\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<br style=\"clear: both\" />\n\t\t\t\t</div>\n\t\t\t</fieldset>\n\t\t</div>\n\n\t\t<div id=\"rgb_panel\" class=\"panel\">\n\t\t\t<fieldset>\n\t\t\t\t<legend>{#advanced_dlg.colorpicker_palette_title}</legend>\n\t\t\t\t<div id=\"webcolors\">\n\t\t\t\t\t<!-- Gets filled with web safe colors-->\n\t\t\t\t</div>\n\n\t\t\t\t<br style=\"clear: both\" />\n\t\t\t</fieldset>\n\t\t</div>\n\n\t\t<div id=\"named_panel\" class=\"panel\">\n\t\t\t<fieldset>\n\t\t\t\t<legend>{#advanced_dlg.colorpicker_named_title}</legend>\n\t\t\t\t<div id=\"namedcolors\">\n\t\t\t\t\t<!-- Gets filled with named colors-->\n\t\t\t\t</div>\n\n\t\t\t\t<br style=\"clear: both\" />\n\n\t\t\t\t<div id=\"colornamecontainer\">\n\t\t\t\t\t{#advanced_dlg.colorpicker_name} <span id=\"colorname\"></span>\n\t\t\t\t</div>\n\t\t\t</fieldset>\n\t\t</div>\n\t</div>\n\n\t<div class=\"mceActionPanel\">\n\t\t<div style=\"float: left\">\n\t\t\t<input type=\"submit\" id=\"insert\" name=\"insert\" value=\"{#apply}\" />\n\t\t</div>\n\n\t\t<div id=\"preview\"></div>\n\n\t\t<div id=\"previewblock\">\n\t\t\t<label for=\"color\">{#advanced_dlg.colorpicker_color}</label> <input id=\"color\" type=\"text\" size=\"8\" maxlength=\"8\" class=\"text mceFocus\" />\n\t\t</div>\n\t</div>\n</form>\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/editor_template.js",
    "content": "(function(e){var d=e.DOM,b=e.dom.Event,h=e.extend,f=e.each,a=e.util.Cookie,g,c=e.explode;e.ThemeManager.requireLangPack(\"advanced\");e.create(\"tinymce.themes.AdvancedTheme\",{sizes:[8,10,12,14,18,24,36],controls:{bold:[\"bold_desc\",\"Bold\"],italic:[\"italic_desc\",\"Italic\"],underline:[\"underline_desc\",\"Underline\"],strikethrough:[\"striketrough_desc\",\"Strikethrough\"],justifyleft:[\"justifyleft_desc\",\"JustifyLeft\"],justifycenter:[\"justifycenter_desc\",\"JustifyCenter\"],justifyright:[\"justifyright_desc\",\"JustifyRight\"],justifyfull:[\"justifyfull_desc\",\"JustifyFull\"],bullist:[\"bullist_desc\",\"InsertUnorderedList\"],numlist:[\"numlist_desc\",\"InsertOrderedList\"],outdent:[\"outdent_desc\",\"Outdent\"],indent:[\"indent_desc\",\"Indent\"],cut:[\"cut_desc\",\"Cut\"],copy:[\"copy_desc\",\"Copy\"],paste:[\"paste_desc\",\"Paste\"],undo:[\"undo_desc\",\"Undo\"],redo:[\"redo_desc\",\"Redo\"],link:[\"link_desc\",\"mceLink\"],unlink:[\"unlink_desc\",\"unlink\"],image:[\"image_desc\",\"mceImage\"],cleanup:[\"cleanup_desc\",\"mceCleanup\"],help:[\"help_desc\",\"mceHelp\"],code:[\"code_desc\",\"mceCodeEditor\"],hr:[\"hr_desc\",\"InsertHorizontalRule\"],removeformat:[\"removeformat_desc\",\"RemoveFormat\"],sub:[\"sub_desc\",\"subscript\"],sup:[\"sup_desc\",\"superscript\"],forecolor:[\"forecolor_desc\",\"ForeColor\"],forecolorpicker:[\"forecolor_desc\",\"mceForeColor\"],backcolor:[\"backcolor_desc\",\"HiliteColor\"],backcolorpicker:[\"backcolor_desc\",\"mceBackColor\"],charmap:[\"charmap_desc\",\"mceCharMap\"],visualaid:[\"visualaid_desc\",\"mceToggleVisualAid\"],anchor:[\"anchor_desc\",\"mceInsertAnchor\"],newdocument:[\"newdocument_desc\",\"mceNewDocument\"],blockquote:[\"blockquote_desc\",\"mceBlockQuote\"]},stateControls:[\"bold\",\"italic\",\"underline\",\"strikethrough\",\"bullist\",\"numlist\",\"justifyleft\",\"justifycenter\",\"justifyright\",\"justifyfull\",\"sub\",\"sup\",\"blockquote\"],init:function(j,k){var l=this,m,i,n;l.editor=j;l.url=k;l.onResolveName=new e.util.Dispatcher(this);l.settings=m=h({theme_advanced_path:true,theme_advanced_toolbar_location:\"bottom\",theme_advanced_buttons1:\"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect\",theme_advanced_buttons2:\"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code\",theme_advanced_buttons3:\"hr,removeformat,visualaid,|,sub,sup,|,charmap\",theme_advanced_blockformats:\"p,address,pre,h1,h2,h3,h4,h5,h6\",theme_advanced_toolbar_align:\"center\",theme_advanced_fonts:\"Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats\",theme_advanced_more_colors:1,theme_advanced_row_height:23,theme_advanced_resize_horizontal:1,theme_advanced_resizing_use_cookie:1,theme_advanced_font_sizes:\"1,2,3,4,5,6,7\",readonly:j.settings.readonly},j.settings);if(!m.font_size_style_values){m.font_size_style_values=\"8pt,10pt,12pt,14pt,18pt,24pt,36pt\"}if(e.is(m.theme_advanced_font_sizes,\"string\")){m.font_size_style_values=e.explode(m.font_size_style_values);m.font_size_classes=e.explode(m.font_size_classes||\"\");n={};j.settings.theme_advanced_font_sizes=m.theme_advanced_font_sizes;f(j.getParam(\"theme_advanced_font_sizes\",\"\",\"hash\"),function(q,p){var o;if(p==q&&q>=1&&q<=7){p=q+\" (\"+l.sizes[q-1]+\"pt)\";if(j.settings.convert_fonts_to_spans){o=m.font_size_classes[q-1];q=m.font_size_style_values[q-1]||(l.sizes[q-1]+\"pt\")}}if(/^\\s*\\./.test(q)){o=q.replace(/\\./g,\"\")}n[p]=o?{\"class\":o}:{fontSize:q}});m.theme_advanced_font_sizes=n}if((i=m.theme_advanced_path_location)&&i!=\"none\"){m.theme_advanced_statusbar_location=m.theme_advanced_path_location}if(m.theme_advanced_statusbar_location==\"none\"){m.theme_advanced_statusbar_location=0}j.onInit.add(function(){j.onNodeChange.add(l._nodeChanged,l);if(j.settings.content_css!==false){j.dom.loadCSS(j.baseURI.toAbsolute(\"themes/advanced/skins/\"+j.settings.skin+\"/content.css\"))}});j.onSetProgressState.add(function(q,o,r){var s,t=q.id,p;if(o){l.progressTimer=setTimeout(function(){s=q.getContainer();s=s.insertBefore(d.create(\"DIV\",{style:\"position:relative\"}),s.firstChild);p=d.get(q.id+\"_tbl\");d.add(s,\"div\",{id:t+\"_blocker\",\"class\":\"mceBlocker\",style:{width:p.clientWidth+2,height:p.clientHeight+2}});d.add(s,\"div\",{id:t+\"_progress\",\"class\":\"mceProgress\",style:{left:p.clientWidth/2,top:p.clientHeight/2}})},r||0)}else{d.remove(t+\"_blocker\");d.remove(t+\"_progress\");clearTimeout(l.progressTimer)}});d.loadCSS(m.editor_css?j.documentBaseURI.toAbsolute(m.editor_css):k+\"/skins/\"+j.settings.skin+\"/ui.css\");if(m.skin_variant){d.loadCSS(k+\"/skins/\"+j.settings.skin+\"/ui_\"+m.skin_variant+\".css\")}},createControl:function(l,i){var j,k;if(k=i.createControl(l)){return k}switch(l){case\"styleselect\":return this._createStyleSelect();case\"formatselect\":return this._createBlockFormats();case\"fontselect\":return this._createFontSelect();case\"fontsizeselect\":return this._createFontSizeSelect();case\"forecolor\":return this._createForeColorMenu();case\"backcolor\":return this._createBackColorMenu()}if((j=this.controls[l])){return i.createButton(l,{title:\"advanced.\"+j[0],cmd:j[1],ui:j[2],value:j[3]})}},execCommand:function(k,j,l){var i=this[\"_\"+k];if(i){i.call(this,j,l);return true}return false},_importClasses:function(j){var i=this.editor,k=i.controlManager.get(\"styleselect\");if(k.getLength()==0){f(i.dom.getClasses(),function(l){k.add(l[\"class\"],l[\"class\"])})}},_createStyleSelect:function(m){var j=this,i=j.editor,k=i.controlManager,l=k.createListBox(\"styleselect\",{title:\"advanced.style_select\",onselect:function(n){if(l.selectedValue===n){i.execCommand(\"mceSetStyleInfo\",0,{command:\"removeformat\"});l.select();return false}else{i.execCommand(\"mceSetCSSClass\",0,n)}}});if(l){f(i.getParam(\"theme_advanced_styles\",\"\",\"hash\"),function(o,n){if(o){l.add(j.editor.translate(n),o)}});l.onPostRender.add(function(o,p){if(!l.NativeListBox){b.add(p.id+\"_text\",\"focus\",j._importClasses,j);b.add(p.id+\"_text\",\"mousedown\",j._importClasses,j);b.add(p.id+\"_open\",\"focus\",j._importClasses,j);b.add(p.id+\"_open\",\"mousedown\",j._importClasses,j)}else{b.add(p.id,\"focus\",j._importClasses,j)}})}return l},_createFontSelect:function(){var k,j=this,i=j.editor;k=i.controlManager.createListBox(\"fontselect\",{title:\"advanced.fontdefault\",cmd:\"FontName\"});if(k){f(i.getParam(\"theme_advanced_fonts\",j.settings.theme_advanced_fonts,\"hash\"),function(m,l){k.add(i.translate(l),m,{style:m.indexOf(\"dings\")==-1?\"font-family:\"+m:\"\"})})}return k},_createFontSizeSelect:function(){var m=this,k=m.editor,n,l=0,j=[];n=k.controlManager.createListBox(\"fontsizeselect\",{title:\"advanced.font_size\",onselect:function(i){if(i.fontSize){k.execCommand(\"FontSize\",false,i.fontSize)}else{f(m.settings.theme_advanced_font_sizes,function(p,o){if(p[\"class\"]){j.push(p[\"class\"])}});k.editorCommands._applyInlineStyle(\"span\",{\"class\":i[\"class\"]},{check_classes:j})}}});if(n){f(m.settings.theme_advanced_font_sizes,function(o,i){var p=o.fontSize;if(p>=1&&p<=7){p=m.sizes[parseInt(p)-1]+\"pt\"}n.add(i,o,{style:\"font-size:\"+p,\"class\":\"mceFontSize\"+(l++)+(\" \"+(o[\"class\"]||\"\"))})})}return n},_createBlockFormats:function(){var k,i={p:\"advanced.paragraph\",address:\"advanced.address\",pre:\"advanced.pre\",h1:\"advanced.h1\",h2:\"advanced.h2\",h3:\"advanced.h3\",h4:\"advanced.h4\",h5:\"advanced.h5\",h6:\"advanced.h6\",div:\"advanced.div\",blockquote:\"advanced.blockquote\",code:\"advanced.code\",dt:\"advanced.dt\",dd:\"advanced.dd\",samp:\"advanced.samp\"},j=this;k=j.editor.controlManager.createListBox(\"formatselect\",{title:\"advanced.block\",cmd:\"FormatBlock\"});if(k){f(j.editor.getParam(\"theme_advanced_blockformats\",j.settings.theme_advanced_blockformats,\"hash\"),function(m,l){k.add(j.editor.translate(l!=m?l:i[m]),m,{\"class\":\"mce_formatPreview mce_\"+m})})}return k},_createForeColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_text_colors){l.colors=i}if(k.theme_advanced_default_foreground_color){l.default_color=k.theme_advanced_default_foreground_color}l.title=\"advanced.forecolor_desc\";l.cmd=\"ForeColor\";l.scope=this;m=j.editor.controlManager.createColorSplitButton(\"forecolor\",l);return m},_createBackColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_background_colors){l.colors=i}if(k.theme_advanced_default_background_color){l.default_color=k.theme_advanced_default_background_color}l.title=\"advanced.backcolor_desc\";l.cmd=\"HiliteColor\";l.scope=this;m=j.editor.controlManager.createColorSplitButton(\"backcolor\",l);return m},renderUI:function(k){var m,l,q,v=this,r=v.editor,w=v.settings,u,j,i;m=j=d.create(\"span\",{id:r.id+\"_parent\",\"class\":\"mceEditor \"+r.settings.skin+\"Skin\"+(w.skin_variant?\" \"+r.settings.skin+\"Skin\"+v._ufirst(w.skin_variant):\"\")});if(!d.boxModel){m=d.add(m,\"div\",{\"class\":\"mceOldBoxModel\"})}m=u=d.add(m,\"table\",{id:r.id+\"_tbl\",\"class\":\"mceLayout\",cellSpacing:0,cellPadding:0});m=q=d.add(m,\"tbody\");switch((w.theme_advanced_layout_manager||\"\").toLowerCase()){case\"rowlayout\":l=v._rowLayout(w,q,k);break;case\"customlayout\":l=r.execCallback(\"theme_advanced_custom_layout\",w,q,k,j);break;default:l=v._simpleLayout(w,q,k,j)}m=k.targetNode;i=d.stdMode?u.getElementsByTagName(\"tr\"):u.rows;d.addClass(i[0],\"mceFirst\");d.addClass(i[i.length-1],\"mceLast\");f(d.select(\"tr\",q),function(o){d.addClass(o.firstChild,\"mceFirst\");d.addClass(o.childNodes[o.childNodes.length-1],\"mceLast\")});if(d.get(w.theme_advanced_toolbar_container)){d.get(w.theme_advanced_toolbar_container).appendChild(j)}else{d.insertAfter(j,m)}b.add(r.id+\"_path_row\",\"click\",function(n){n=n.target;if(n.nodeName==\"A\"){v._sel(n.className.replace(/^.*mcePath_([0-9]+).*$/,\"$1\"));return b.cancel(n)}});if(!r.getParam(\"accessibility_focus\")){b.add(d.add(j,\"a\",{href:\"#\"},\"<!-- IE -->\"),\"focus\",function(){tinyMCE.get(r.id).focus()})}if(w.theme_advanced_toolbar_location==\"external\"){k.deltaHeight=0}v.deltaHeight=k.deltaHeight;k.targetNode=null;return{iframeContainer:l,editorContainer:r.id+\"_parent\",sizeContainer:u,deltaHeight:k.deltaHeight}},getInfo:function(){return{longname:\"Advanced theme\",author:\"Moxiecode Systems AB\",authorurl:\"http://tinymce.moxiecode.com\",version:e.majorVersion+\".\"+e.minorVersion}},resizeBy:function(i,j){var k=d.get(this.editor.id+\"_tbl\");this.resizeTo(k.clientWidth+i,k.clientHeight+j)},resizeTo:function(i,l){var j=this.editor,k=j.settings,n=d.get(j.id+\"_tbl\"),o=d.get(j.id+\"_ifr\"),m;i=Math.max(k.theme_advanced_resizing_min_width||100,i);l=Math.max(k.theme_advanced_resizing_min_height||100,l);i=Math.min(k.theme_advanced_resizing_max_width||65535,i);l=Math.min(k.theme_advanced_resizing_max_height||65535,l);m=n.clientHeight-o.clientHeight;d.setStyle(o,\"height\",l-m);d.setStyles(n,{width:i,height:l})},destroy:function(){var i=this.editor.id;b.clear(i+\"_resize\");b.clear(i+\"_path_row\");b.clear(i+\"_external_close\")},_simpleLayout:function(y,r,k,i){var x=this,u=x.editor,v=y.theme_advanced_toolbar_location,m=y.theme_advanced_statusbar_location,l,j,q,w;if(y.readonly){l=d.add(r,\"tr\");l=j=d.add(l,\"td\",{\"class\":\"mceIframeContainer\"});return j}if(v==\"top\"){x._addToolbars(r,k)}if(v==\"external\"){l=w=d.create(\"div\",{style:\"position:relative\"});l=d.add(l,\"div\",{id:u.id+\"_external\",\"class\":\"mceExternalToolbar\"});d.add(l,\"a\",{id:u.id+\"_external_close\",href:\"javascript:;\",\"class\":\"mceExternalClose\"});l=d.add(l,\"table\",{id:u.id+\"_tblext\",cellSpacing:0,cellPadding:0});q=d.add(l,\"tbody\");if(i.firstChild.className==\"mceOldBoxModel\"){i.firstChild.appendChild(w)}else{i.insertBefore(w,i.firstChild)}x._addToolbars(q,k);u.onMouseUp.add(function(){var o=d.get(u.id+\"_external\");d.show(o);d.hide(g);var n=b.add(u.id+\"_external_close\",\"click\",function(){d.hide(u.id+\"_external\");b.remove(u.id+\"_external_close\",\"click\",n)});d.show(o);d.setStyle(o,\"top\",0-d.getRect(u.id+\"_tblext\").h-1);d.hide(o);d.show(o);o.style.filter=\"\";g=u.id+\"_external\";o=null})}if(m==\"top\"){x._addStatusBar(r,k)}if(!y.theme_advanced_toolbar_container){l=d.add(r,\"tr\");l=j=d.add(l,\"td\",{\"class\":\"mceIframeContainer\"})}if(v==\"bottom\"){x._addToolbars(r,k)}if(m==\"bottom\"){x._addStatusBar(r,k)}return j},_rowLayout:function(w,m,k){var v=this,p=v.editor,u,x,i=p.controlManager,l,j,r,q;u=w.theme_advanced_containers_default_class||\"\";x=w.theme_advanced_containers_default_align||\"center\";f(c(w.theme_advanced_containers||\"\"),function(s,o){var n=w[\"theme_advanced_container_\"+s]||\"\";switch(n.toLowerCase()){case\"mceeditor\":l=d.add(m,\"tr\");l=j=d.add(l,\"td\",{\"class\":\"mceIframeContainer\"});break;case\"mceelementpath\":v._addStatusBar(m,k);break;default:q=(w[\"theme_advanced_container_\"+s+\"_align\"]||x).toLowerCase();q=\"mce\"+v._ufirst(q);l=d.add(d.add(m,\"tr\"),\"td\",{\"class\":\"mceToolbar \"+(w[\"theme_advanced_container_\"+s+\"_class\"]||u)+\" \"+q||x});r=i.createToolbar(\"toolbar\"+o);v._addControls(n,r);d.setHTML(l,r.renderHTML());k.deltaHeight-=w.theme_advanced_row_height}});return j},_addControls:function(j,i){var k=this,l=k.settings,m,n=k.editor.controlManager;if(l.theme_advanced_disable&&!k._disabled){m={};f(c(l.theme_advanced_disable),function(o){m[o]=1});k._disabled=m}else{m=k._disabled}f(c(j),function(p){var o;if(m&&m[p]){return}if(p==\"tablecontrols\"){f([\"table\",\"|\",\"row_props\",\"cell_props\",\"|\",\"row_before\",\"row_after\",\"delete_row\",\"|\",\"col_before\",\"col_after\",\"delete_col\",\"|\",\"split_cells\",\"merge_cells\"],function(q){q=k.createControl(q,n);if(q){i.add(q)}});return}o=k.createControl(p,n);if(o){i.add(o)}})},_addToolbars:function(w,k){var z=this,p,m,r=z.editor,A=z.settings,y,j=r.controlManager,u,l,q=[],x;x=A.theme_advanced_toolbar_align.toLowerCase();x=\"mce\"+z._ufirst(x);l=d.add(d.add(w,\"tr\"),\"td\",{\"class\":\"mceToolbar \"+x});if(!r.getParam(\"accessibility_focus\")){q.push(d.createHTML(\"a\",{href:\"#\",onfocus:\"tinyMCE.get('\"+r.id+\"').focus();\"},\"<!-- IE -->\"))}q.push(d.createHTML(\"a\",{href:\"#\",accesskey:\"q\",title:r.getLang(\"advanced.toolbar_focus\")},\"<!-- IE -->\"));for(p=1;(y=A[\"theme_advanced_buttons\"+p]);p++){m=j.createToolbar(\"toolbar\"+p,{\"class\":\"mceToolbarRow\"+p});if(A[\"theme_advanced_buttons\"+p+\"_add\"]){y+=\",\"+A[\"theme_advanced_buttons\"+p+\"_add\"]}if(A[\"theme_advanced_buttons\"+p+\"_add_before\"]){y=A[\"theme_advanced_buttons\"+p+\"_add_before\"]+\",\"+y}z._addControls(y,m);q.push(m.renderHTML());k.deltaHeight-=A.theme_advanced_row_height}q.push(d.createHTML(\"a\",{href:\"#\",accesskey:\"z\",title:r.getLang(\"advanced.toolbar_focus\"),onfocus:\"tinyMCE.getInstanceById('\"+r.id+\"').focus();\"},\"<!-- IE -->\"));d.setHTML(l,q.join(\"\"))},_addStatusBar:function(m,j){var k,v=this,p=v.editor,w=v.settings,i,q,u,l;k=d.add(m,\"tr\");k=l=d.add(k,\"td\",{\"class\":\"mceStatusbar\"});k=d.add(k,\"div\",{id:p.id+\"_path_row\"},w.theme_advanced_path?p.translate(\"advanced.path\")+\": \":\"&#160;\");d.add(k,\"a\",{href:\"#\",accesskey:\"x\"});if(w.theme_advanced_resizing){d.add(l,\"a\",{id:p.id+\"_resize\",href:\"javascript:;\",onclick:\"return false;\",\"class\":\"mceResize\"});if(w.theme_advanced_resizing_use_cookie){p.onPostRender.add(function(){var n=a.getHash(\"TinyMCE_\"+p.id+\"_size\"),r=d.get(p.id+\"_tbl\");if(!n){return}if(w.theme_advanced_resize_horizontal){r.style.width=Math.max(10,n.cw)+\"px\"}r.style.height=Math.max(10,n.ch)+\"px\";d.get(p.id+\"_ifr\").style.height=Math.max(10,parseInt(n.ch)+v.deltaHeight)+\"px\"})}p.onPostRender.add(function(){b.add(p.id+\"_resize\",\"mousedown\",function(x){var z,t,o,s,y,r;z=d.get(p.id+\"_tbl\");o=z.clientWidth;s=z.clientHeight;miw=w.theme_advanced_resizing_min_width||100;mih=w.theme_advanced_resizing_min_height||100;maw=w.theme_advanced_resizing_max_width||65535;mah=w.theme_advanced_resizing_max_height||65535;t=d.add(d.get(p.id+\"_parent\"),\"div\",{\"class\":\"mcePlaceHolder\"});d.setStyles(t,{width:o,height:s});d.hide(z);d.show(t);i={x:x.screenX,y:x.screenY,w:o,h:s,dx:null,dy:null};q=b.add(d.doc,\"mousemove\",function(B){var n,A;i.dx=B.screenX-i.x;i.dy=B.screenY-i.y;n=Math.max(miw,i.w+i.dx);A=Math.max(mih,i.h+i.dy);n=Math.min(maw,n);A=Math.min(mah,A);if(w.theme_advanced_resize_horizontal){t.style.width=n+\"px\"}t.style.height=A+\"px\";return b.cancel(B)});u=b.add(d.doc,\"mouseup\",function(n){var A;b.remove(d.doc,\"mousemove\",q);b.remove(d.doc,\"mouseup\",u);z.style.display=\"\";d.remove(t);if(i.dx===null){return}A=d.get(p.id+\"_ifr\");if(w.theme_advanced_resize_horizontal){z.style.width=Math.max(10,i.w+i.dx)+\"px\"}z.style.height=Math.max(10,i.h+i.dy)+\"px\";A.style.height=Math.max(10,A.clientHeight+i.dy)+\"px\";if(w.theme_advanced_resizing_use_cookie){a.setHash(\"TinyMCE_\"+p.id+\"_size\",{cw:i.w+i.dx,ch:i.h+i.dy})}});return b.cancel(x)})})}j.deltaHeight-=21;k=m=null},_nodeChanged:function(l,u,k,q){var y=this,i,r=0,x,m,z=y.settings,w,j,o;if(z.readonly){return}e.each(y.stateControls,function(n){u.setActive(n,l.queryCommandState(y.controls[n][1]))});u.setActive(\"visualaid\",l.hasVisual);u.setDisabled(\"undo\",!l.undoManager.hasUndo()&&!l.typing);u.setDisabled(\"redo\",!l.undoManager.hasRedo());u.setDisabled(\"outdent\",!l.queryCommandState(\"Outdent\"));i=d.getParent(k,\"A\");if(m=u.get(\"link\")){if(!i||!i.name){m.setDisabled(!i&&q);m.setActive(!!i)}}if(m=u.get(\"unlink\")){m.setDisabled(!i&&q);m.setActive(!!i&&!i.name)}if(m=u.get(\"anchor\")){m.setActive(!!i&&i.name);if(e.isWebKit){i=d.getParent(k,\"IMG\");m.setActive(!!i&&d.getAttrib(i,\"mce_name\")==\"a\")}}i=d.getParent(k,\"IMG\");if(m=u.get(\"image\")){m.setActive(!!i&&k.className.indexOf(\"mceItem\")==-1)}if(m=u.get(\"styleselect\")){if(k.className){y._importClasses();m.select(k.className)}else{m.select()}}if(m=u.get(\"formatselect\")){i=d.getParent(k,d.isBlock);if(i){m.select(i.nodeName.toLowerCase())}}if(l.settings.convert_fonts_to_spans){l.dom.getParent(k,function(p){if(p.nodeName===\"SPAN\"){if(!w&&p.className){w=p.className}if(!j&&p.style.fontSize){j=p.style.fontSize}if(!o&&p.style.fontFamily){o=p.style.fontFamily.replace(/[\\\"\\']+/g,\"\").replace(/^([^,]+).*/,\"$1\").toLowerCase()}}return false});if(m=u.get(\"fontselect\")){m.select(function(n){return n.replace(/^([^,]+).*/,\"$1\").toLowerCase()==o})}if(m=u.get(\"fontsizeselect\")){m.select(function(n){if(n.fontSize&&n.fontSize===j){return true}if(n[\"class\"]&&n[\"class\"]===w){return true}})}}else{if(m=u.get(\"fontselect\")){m.select(l.queryCommandValue(\"FontName\"))}if(m=u.get(\"fontsizeselect\")){x=l.queryCommandValue(\"FontSize\");m.select(function(n){return n.fontSize==x})}}if(z.theme_advanced_path&&z.theme_advanced_statusbar_location){i=d.get(l.id+\"_path\")||d.add(l.id+\"_path_row\",\"span\",{id:l.id+\"_path\"});d.setHTML(i,\"\");l.dom.getParent(k,function(A){var p=A.nodeName.toLowerCase(),s,v,t=\"\";if(A.nodeType!=1||A.nodeName===\"BR\"||(d.hasClass(A,\"mceItemHidden\")||d.hasClass(A,\"mceItemRemoved\"))){return}if(x=d.getAttrib(A,\"mce_name\")){p=x}if(e.isIE&&A.scopeName!==\"HTML\"){p=A.scopeName+\":\"+p}p=p.replace(/mce\\:/g,\"\");switch(p){case\"b\":p=\"strong\";break;case\"i\":p=\"em\";break;case\"img\":if(x=d.getAttrib(A,\"src\")){t+=\"src: \"+x+\" \"}break;case\"a\":if(x=d.getAttrib(A,\"name\")){t+=\"name: \"+x+\" \";p+=\"#\"+x}if(x=d.getAttrib(A,\"href\")){t+=\"href: \"+x+\" \"}break;case\"font\":if(z.convert_fonts_to_spans){p=\"span\"}if(x=d.getAttrib(A,\"face\")){t+=\"font: \"+x+\" \"}if(x=d.getAttrib(A,\"size\")){t+=\"size: \"+x+\" \"}if(x=d.getAttrib(A,\"color\")){t+=\"color: \"+x+\" \"}break;case\"span\":if(x=d.getAttrib(A,\"style\")){t+=\"style: \"+x+\" \"}break}if(x=d.getAttrib(A,\"id\")){t+=\"id: \"+x+\" \"}if(x=A.className){x=x.replace(/(webkit-[\\w\\-]+|Apple-[\\w\\-]+|mceItem\\w+|mceVisualAid)/g,\"\");if(x&&x.indexOf(\"mceItem\")==-1){t+=\"class: \"+x+\" \";if(d.isBlock(A)||p==\"img\"||p==\"span\"){p+=\".\"+x}}}p=p.replace(/(html:)/g,\"\");p={name:p,node:A,title:t};y.onResolveName.dispatch(y,p);t=p.title;p=p.name;v=d.create(\"a\",{href:\"javascript:;\",onmousedown:\"return false;\",title:t,\"class\":\"mcePath_\"+(r++)},p);if(i.hasChildNodes()){i.insertBefore(d.doc.createTextNode(\" \\u00bb \"),i.firstChild);i.insertBefore(v,i.firstChild)}else{i.appendChild(v)}},l.getBody())}},_sel:function(i){this.editor.execCommand(\"mceSelectNodeDepth\",false,i)},_mceInsertAnchor:function(k,j){var i=this.editor;i.windowManager.open({url:e.baseURL+\"/themes/advanced/anchor.htm\",width:320+parseInt(i.getLang(\"advanced.anchor_delta_width\",0)),height:90+parseInt(i.getLang(\"advanced.anchor_delta_height\",0)),inline:true},{theme_url:this.url})},_mceCharMap:function(){var i=this.editor;i.windowManager.open({url:e.baseURL+\"/themes/advanced/charmap.htm\",width:550+parseInt(i.getLang(\"advanced.charmap_delta_width\",0)),height:250+parseInt(i.getLang(\"advanced.charmap_delta_height\",0)),inline:true},{theme_url:this.url})},_mceHelp:function(){var i=this.editor;i.windowManager.open({url:e.baseURL+\"/themes/advanced/about.htm\",width:480,height:380,inline:true},{theme_url:this.url})},_mceColorPicker:function(k,j){var i=this.editor;j=j||{};i.windowManager.open({url:e.baseURL+\"/themes/advanced/color_picker.htm\",width:375+parseInt(i.getLang(\"advanced.colorpicker_delta_width\",0)),height:250+parseInt(i.getLang(\"advanced.colorpicker_delta_height\",0)),close_previous:false,inline:true},{input_color:j.color,func:j.func,theme_url:this.url})},_mceCodeEditor:function(j,k){var i=this.editor;i.windowManager.open({url:e.baseURL+\"/themes/advanced/source_editor.htm\",width:parseInt(i.getParam(\"theme_advanced_source_editor_width\",720)),height:parseInt(i.getParam(\"theme_advanced_source_editor_height\",580)),inline:true,resizable:true,maximizable:true},{theme_url:this.url})},_mceImage:function(j,k){var i=this.editor;if(i.dom.getAttrib(i.selection.getNode(),\"class\").indexOf(\"mceItem\")!=-1){return}i.windowManager.open({url:e.baseURL+\"/themes/advanced/image.htm\",width:355+parseInt(i.getLang(\"advanced.image_delta_width\",0)),height:275+parseInt(i.getLang(\"advanced.image_delta_height\",0)),inline:true},{theme_url:this.url})},_mceLink:function(j,k){var i=this.editor;i.windowManager.open({url:e.baseURL+\"/themes/advanced/link.htm\",width:310+parseInt(i.getLang(\"advanced.link_delta_width\",0)),height:200+parseInt(i.getLang(\"advanced.link_delta_height\",0)),inline:true},{theme_url:this.url})},_mceNewDocument:function(){var i=this.editor;i.windowManager.confirm(\"advanced.newdocument\",function(j){if(j){i.execCommand(\"mceSetContent\",false,\"\")}})},_mceForeColor:function(){var i=this;this._mceColorPicker(0,{color:i.fgColor,func:function(j){i.fgColor=j;i.editor.execCommand(\"ForeColor\",false,j)}})},_mceBackColor:function(){var i=this;this._mceColorPicker(0,{color:i.bgColor,func:function(j){i.bgColor=j;i.editor.execCommand(\"HiliteColor\",false,j)}})},_ufirst:function(i){return i.substring(0,1).toUpperCase()+i.substring(1)}});e.ThemeManager.add(\"advanced\",e.themes.AdvancedTheme)}(tinymce));"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/image.htm",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n\t<title>{#advanced_dlg.image_title}</title>\n\t<script type=\"text/javascript\" src=\"../../tiny_mce_popup.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/mctabs.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/form_utils.js\"></script>\n\t<script type=\"text/javascript\" src=\"js/image.js\"></script>\n</head>\n<body id=\"image\" style=\"display: none\">\n<form onsubmit=\"ImageDialog.update();return false;\" action=\"#\">\n\t<div class=\"tabs\">\n\t\t<ul>\n\t\t\t<li id=\"general_tab\" class=\"current\"><span><a href=\"javascript:mcTabs.displayTab('general_tab','general_panel');\" onmousedown=\"return false;\">{#advanced_dlg.image_title}</a></span></li>\n\t\t</ul>\n\t</div>\n\n\t<div class=\"panel_wrapper\">\n\t\t<div id=\"general_panel\" class=\"panel current\">\n     <table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n          <tr>\n            <td class=\"nowrap\"><label for=\"src\">{#advanced_dlg.image_src}</label></td>\n            <td><table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n                <tr>\n                  <td><input id=\"src\" name=\"src\" type=\"text\" class=\"mceFocus\" value=\"\" style=\"width: 200px\" onchange=\"ImageDialog.getImageData();\" /></td>\n                  <td id=\"srcbrowsercontainer\">&nbsp;</td>\n                </tr>\n              </table></td>\n          </tr>\n\t\t  <tr>\n\t\t\t<td><label for=\"image_list\">{#advanced_dlg.image_list}</label></td>\n\t\t\t<td><select id=\"image_list\" name=\"image_list\" onchange=\"document.getElementById('src').value=this.options[this.selectedIndex].value;document.getElementById('alt').value=this.options[this.selectedIndex].text;\"></select></td>\n\t\t  </tr>\n          <tr>\n            <td class=\"nowrap\"><label for=\"alt\">{#advanced_dlg.image_alt}</label></td>\n            <td><input id=\"alt\" name=\"alt\" type=\"text\" value=\"\" style=\"width: 200px\" /></td>\n          </tr>\n          <tr>\n            <td class=\"nowrap\"><label for=\"align\">{#advanced_dlg.image_align}</label></td>\n            <td><select id=\"align\" name=\"align\" onchange=\"ImageDialog.updateStyle();\">\n                <option value=\"\">{#not_set}</option>\n                <option value=\"baseline\">{#advanced_dlg.image_align_baseline}</option>\n                <option value=\"top\">{#advanced_dlg.image_align_top}</option>\n                <option value=\"middle\">{#advanced_dlg.image_align_middle}</option>\n                <option value=\"bottom\">{#advanced_dlg.image_align_bottom}</option>\n                <option value=\"text-top\">{#advanced_dlg.image_align_texttop}</option>\n                <option value=\"text-bottom\">{#advanced_dlg.image_align_textbottom}</option>\n                <option value=\"left\">{#advanced_dlg.image_align_left}</option>\n                <option value=\"right\">{#advanced_dlg.image_align_right}</option>\n              </select></td>\n          </tr>\n          <tr>\n            <td class=\"nowrap\"><label for=\"width\">{#advanced_dlg.image_dimensions}</label></td>\n            <td><input id=\"width\" name=\"width\" type=\"text\" value=\"\" size=\"3\" maxlength=\"5\" />\n              x\n              <input id=\"height\" name=\"height\" type=\"text\" value=\"\" size=\"3\" maxlength=\"5\" /></td>\n          </tr>\n          <tr>\n            <td class=\"nowrap\"><label for=\"border\">{#advanced_dlg.image_border}</label></td>\n            <td><input id=\"border\" name=\"border\" type=\"text\" value=\"\" size=\"3\" maxlength=\"3\" onchange=\"ImageDialog.updateStyle();\" /></td>\n          </tr>\n          <tr>\n            <td class=\"nowrap\"><label for=\"vspace\">{#advanced_dlg.image_vspace}</label></td>\n            <td><input id=\"vspace\" name=\"vspace\" type=\"text\" value=\"\" size=\"3\" maxlength=\"3\" onchange=\"ImageDialog.updateStyle();\" /></td>\n          </tr>\n          <tr>\n            <td class=\"nowrap\"><label for=\"hspace\">{#advanced_dlg.image_hspace}</label></td>\n            <td><input id=\"hspace\" name=\"hspace\" type=\"text\" value=\"\" size=\"3\" maxlength=\"3\" onchange=\"ImageDialog.updateStyle();\" /></td>\n          </tr>\n        </table>\n\t\t</div>\n\t</div>\n\n\t<div class=\"mceActionPanel\">\n\t\t<div style=\"float: left\">\n\t\t\t<input type=\"submit\" id=\"insert\" name=\"insert\" value=\"{#insert}\" />\n\t\t</div>\n\n\t\t<div style=\"float: right\">\n\t\t\t<input type=\"button\" id=\"cancel\" name=\"cancel\" value=\"{#cancel}\" onclick=\"tinyMCEPopup.close();\" />\n\t\t</div>\n\t</div>\n</form>\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/js/about.js",
    "content": "tinyMCEPopup.requireLangPack();\n\nfunction init() {\n\tvar ed, tcont;\n\n\ttinyMCEPopup.resizeToInnerSize();\n\ted = tinyMCEPopup.editor;\n\n\t// Give FF some time\n\twindow.setTimeout(insertHelpIFrame, 10);\n\n\ttcont = document.getElementById('plugintablecontainer');\n\tdocument.getElementById('plugins_tab').style.display = 'none';\n\n\tvar html = \"\";\n\thtml += '<table id=\"plugintable\">';\n\thtml += '<thead>';\n\thtml += '<tr>';\n\thtml += '<td>' + ed.getLang('advanced_dlg.about_plugin') + '</td>';\n\thtml += '<td>' + ed.getLang('advanced_dlg.about_author') + '</td>';\n\thtml += '<td>' + ed.getLang('advanced_dlg.about_version') + '</td>';\n\thtml += '</tr>';\n\thtml += '</thead>';\n\thtml += '<tbody>';\n\n\ttinymce.each(ed.plugins, function(p, n) {\n\t\tvar info;\n\n\t\tif (!p.getInfo)\n\t\t\treturn;\n\n\t\thtml += '<tr>';\n\n\t\tinfo = p.getInfo();\n\n\t\tif (info.infourl != null && info.infourl != '')\n\t\t\thtml += '<td width=\"50%\" title=\"' + n + '\"><a href=\"' + info.infourl + '\" target=\"_blank\">' + info.longname + '</a></td>';\n\t\telse\n\t\t\thtml += '<td width=\"50%\" title=\"' + n + '\">' + info.longname + '</td>';\n\n\t\tif (info.authorurl != null && info.authorurl != '')\n\t\t\thtml += '<td width=\"35%\"><a href=\"' + info.authorurl + '\" target=\"_blank\">' + info.author + '</a></td>';\n\t\telse\n\t\t\thtml += '<td width=\"35%\">' + info.author + '</td>';\n\n\t\thtml += '<td width=\"15%\">' + info.version + '</td>';\n\t\thtml += '</tr>';\n\n\t\tdocument.getElementById('plugins_tab').style.display = '';\n\n\t});\n\n\thtml += '</tbody>';\n\thtml += '</table>';\n\n\ttcont.innerHTML = html;\n\n\ttinyMCEPopup.dom.get('version').innerHTML = tinymce.majorVersion + \".\" + tinymce.minorVersion;\n\ttinyMCEPopup.dom.get('date').innerHTML = tinymce.releaseDate;\n}\n\nfunction insertHelpIFrame() {\n\tvar html;\n\n\tif (tinyMCEPopup.getParam('docs_url')) {\n\t\thtml = '<iframe width=\"100%\" height=\"300\" src=\"' + tinyMCEPopup.editor.baseURI.toAbsolute(tinyMCEPopup.getParam('docs_url')) + '\"></iframe>';\n\t\tdocument.getElementById('iframecontainer').innerHTML = html;\n\t\tdocument.getElementById('help_tab').style.display = 'block';\n\t}\n}\n\ntinyMCEPopup.onInit.add(init);\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/js/anchor.js",
    "content": "tinyMCEPopup.requireLangPack();\n\nvar AnchorDialog = {\n\tinit : function(ed) {\n\t\tvar action, elm, f = document.forms[0];\n\n\t\tthis.editor = ed;\n\t\telm = ed.dom.getParent(ed.selection.getNode(), 'A,IMG');\n\t\tv = ed.dom.getAttrib(elm, 'name');\n\n\t\tif (v) {\n\t\t\tthis.action = 'update';\n\t\t\tf.anchorName.value = v;\n\t\t}\n\n\t\tf.insert.value = ed.getLang(elm ? 'update' : 'insert');\n\t},\n\n\tupdate : function() {\n\t\tvar ed = this.editor;\n\t\t\n\t\ttinyMCEPopup.restoreSelection();\n\n\t\tif (this.action != 'update')\n\t\t\ted.selection.collapse(1);\n\n\t\t// Webkit acts weird if empty inline element is inserted so we need to use a image instead\n\t\tif (tinymce.isWebKit)\n\t\t\ted.execCommand('mceInsertContent', 0, ed.dom.createHTML('img', {mce_name : 'a', name : document.forms[0].anchorName.value, 'class' : 'mceItemAnchor'}));\n\t\telse\n\t\t\ted.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', {name : document.forms[0].anchorName.value, 'class' : 'mceItemAnchor'}, ''));\n\n\t\ttinyMCEPopup.close();\n\t}\n};\n\ntinyMCEPopup.onInit.add(AnchorDialog.init, AnchorDialog);\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/js/charmap.js",
    "content": "tinyMCEPopup.requireLangPack();\n\nvar charmap = [\n\t['&nbsp;',    '&#160;',  true, 'no-break space'],\n\t['&amp;',     '&#38;',   true, 'ampersand'],\n\t['&quot;',    '&#34;',   true, 'quotation mark'],\n// finance\n\t['&cent;',    '&#162;',  true, 'cent sign'],\n\t['&euro;',    '&#8364;', true, 'euro sign'],\n\t['&pound;',   '&#163;',  true, 'pound sign'],\n\t['&yen;',     '&#165;',  true, 'yen sign'],\n// signs\n\t['&copy;',    '&#169;',  true, 'copyright sign'],\n\t['&reg;',     '&#174;',  true, 'registered sign'],\n\t['&trade;',   '&#8482;', true, 'trade mark sign'],\n\t['&permil;',  '&#8240;', true, 'per mille sign'],\n\t['&micro;',   '&#181;',  true, 'micro sign'],\n\t['&middot;',  '&#183;',  true, 'middle dot'],\n\t['&bull;',    '&#8226;', true, 'bullet'],\n\t['&hellip;',  '&#8230;', true, 'three dot leader'],\n\t['&prime;',   '&#8242;', true, 'minutes / feet'],\n\t['&Prime;',   '&#8243;', true, 'seconds / inches'],\n\t['&sect;',    '&#167;',  true, 'section sign'],\n\t['&para;',    '&#182;',  true, 'paragraph sign'],\n\t['&szlig;',   '&#223;',  true, 'sharp s / ess-zed'],\n// quotations\n\t['&lsaquo;',  '&#8249;', true, 'single left-pointing angle quotation mark'],\n\t['&rsaquo;',  '&#8250;', true, 'single right-pointing angle quotation mark'],\n\t['&laquo;',   '&#171;',  true, 'left pointing guillemet'],\n\t['&raquo;',   '&#187;',  true, 'right pointing guillemet'],\n\t['&lsquo;',   '&#8216;', true, 'left single quotation mark'],\n\t['&rsquo;',   '&#8217;', true, 'right single quotation mark'],\n\t['&ldquo;',   '&#8220;', true, 'left double quotation mark'],\n\t['&rdquo;',   '&#8221;', true, 'right double quotation mark'],\n\t['&sbquo;',   '&#8218;', true, 'single low-9 quotation mark'],\n\t['&bdquo;',   '&#8222;', true, 'double low-9 quotation mark'],\n\t['&lt;',      '&#60;',   true, 'less-than sign'],\n\t['&gt;',      '&#62;',   true, 'greater-than sign'],\n\t['&le;',      '&#8804;', true, 'less-than or equal to'],\n\t['&ge;',      '&#8805;', true, 'greater-than or equal to'],\n\t['&ndash;',   '&#8211;', true, 'en dash'],\n\t['&mdash;',   '&#8212;', true, 'em dash'],\n\t['&macr;',    '&#175;',  true, 'macron'],\n\t['&oline;',   '&#8254;', true, 'overline'],\n\t['&curren;',  '&#164;',  true, 'currency sign'],\n\t['&brvbar;',  '&#166;',  true, 'broken bar'],\n\t['&uml;',     '&#168;',  true, 'diaeresis'],\n\t['&iexcl;',   '&#161;',  true, 'inverted exclamation mark'],\n\t['&iquest;',  '&#191;',  true, 'turned question mark'],\n\t['&circ;',    '&#710;',  true, 'circumflex accent'],\n\t['&tilde;',   '&#732;',  true, 'small tilde'],\n\t['&deg;',     '&#176;',  true, 'degree sign'],\n\t['&minus;',   '&#8722;', true, 'minus sign'],\n\t['&plusmn;',  '&#177;',  true, 'plus-minus sign'],\n\t['&divide;',  '&#247;',  true, 'division sign'],\n\t['&frasl;',   '&#8260;', true, 'fraction slash'],\n\t['&times;',   '&#215;',  true, 'multiplication sign'],\n\t['&sup1;',    '&#185;',  true, 'superscript one'],\n\t['&sup2;',    '&#178;',  true, 'superscript two'],\n\t['&sup3;',    '&#179;',  true, 'superscript three'],\n\t['&frac14;',  '&#188;',  true, 'fraction one quarter'],\n\t['&frac12;',  '&#189;',  true, 'fraction one half'],\n\t['&frac34;',  '&#190;',  true, 'fraction three quarters'],\n// math / logical\n\t['&fnof;',    '&#402;',  true, 'function / florin'],\n\t['&int;',     '&#8747;', true, 'integral'],\n\t['&sum;',     '&#8721;', true, 'n-ary sumation'],\n\t['&infin;',   '&#8734;', true, 'infinity'],\n\t['&radic;',   '&#8730;', true, 'square root'],\n\t['&sim;',     '&#8764;', false,'similar to'],\n\t['&cong;',    '&#8773;', false,'approximately equal to'],\n\t['&asymp;',   '&#8776;', true, 'almost equal to'],\n\t['&ne;',      '&#8800;', true, 'not equal to'],\n\t['&equiv;',   '&#8801;', true, 'identical to'],\n\t['&isin;',    '&#8712;', false,'element of'],\n\t['&notin;',   '&#8713;', false,'not an element of'],\n\t['&ni;',      '&#8715;', false,'contains as member'],\n\t['&prod;',    '&#8719;', true, 'n-ary product'],\n\t['&and;',     '&#8743;', false,'logical and'],\n\t['&or;',      '&#8744;', false,'logical or'],\n\t['&not;',     '&#172;',  true, 'not sign'],\n\t['&cap;',     '&#8745;', true, 'intersection'],\n\t['&cup;',     '&#8746;', false,'union'],\n\t['&part;',    '&#8706;', true, 'partial differential'],\n\t['&forall;',  '&#8704;', false,'for all'],\n\t['&exist;',   '&#8707;', false,'there exists'],\n\t['&empty;',   '&#8709;', false,'diameter'],\n\t['&nabla;',   '&#8711;', false,'backward difference'],\n\t['&lowast;',  '&#8727;', false,'asterisk operator'],\n\t['&prop;',    '&#8733;', false,'proportional to'],\n\t['&ang;',     '&#8736;', false,'angle'],\n// undefined\n\t['&acute;',   '&#180;',  true, 'acute accent'],\n\t['&cedil;',   '&#184;',  true, 'cedilla'],\n\t['&ordf;',    '&#170;',  true, 'feminine ordinal indicator'],\n\t['&ordm;',    '&#186;',  true, 'masculine ordinal indicator'],\n\t['&dagger;',  '&#8224;', true, 'dagger'],\n\t['&Dagger;',  '&#8225;', true, 'double dagger'],\n// alphabetical special chars\n\t['&Agrave;',  '&#192;',  true, 'A - grave'],\n\t['&Aacute;',  '&#193;',  true, 'A - acute'],\n\t['&Acirc;',   '&#194;',  true, 'A - circumflex'],\n\t['&Atilde;',  '&#195;',  true, 'A - tilde'],\n\t['&Auml;',    '&#196;',  true, 'A - diaeresis'],\n\t['&Aring;',   '&#197;',  true, 'A - ring above'],\n\t['&AElig;',   '&#198;',  true, 'ligature AE'],\n\t['&Ccedil;',  '&#199;',  true, 'C - cedilla'],\n\t['&Egrave;',  '&#200;',  true, 'E - grave'],\n\t['&Eacute;',  '&#201;',  true, 'E - acute'],\n\t['&Ecirc;',   '&#202;',  true, 'E - circumflex'],\n\t['&Euml;',    '&#203;',  true, 'E - diaeresis'],\n\t['&Igrave;',  '&#204;',  true, 'I - grave'],\n\t['&Iacute;',  '&#205;',  true, 'I - acute'],\n\t['&Icirc;',   '&#206;',  true, 'I - circumflex'],\n\t['&Iuml;',    '&#207;',  true, 'I - diaeresis'],\n\t['&ETH;',     '&#208;',  true, 'ETH'],\n\t['&Ntilde;',  '&#209;',  true, 'N - tilde'],\n\t['&Ograve;',  '&#210;',  true, 'O - grave'],\n\t['&Oacute;',  '&#211;',  true, 'O - acute'],\n\t['&Ocirc;',   '&#212;',  true, 'O - circumflex'],\n\t['&Otilde;',  '&#213;',  true, 'O - tilde'],\n\t['&Ouml;',    '&#214;',  true, 'O - diaeresis'],\n\t['&Oslash;',  '&#216;',  true, 'O - slash'],\n\t['&OElig;',   '&#338;',  true, 'ligature OE'],\n\t['&Scaron;',  '&#352;',  true, 'S - caron'],\n\t['&Ugrave;',  '&#217;',  true, 'U - grave'],\n\t['&Uacute;',  '&#218;',  true, 'U - acute'],\n\t['&Ucirc;',   '&#219;',  true, 'U - circumflex'],\n\t['&Uuml;',    '&#220;',  true, 'U - diaeresis'],\n\t['&Yacute;',  '&#221;',  true, 'Y - acute'],\n\t['&Yuml;',    '&#376;',  true, 'Y - diaeresis'],\n\t['&THORN;',   '&#222;',  true, 'THORN'],\n\t['&agrave;',  '&#224;',  true, 'a - grave'],\n\t['&aacute;',  '&#225;',  true, 'a - acute'],\n\t['&acirc;',   '&#226;',  true, 'a - circumflex'],\n\t['&atilde;',  '&#227;',  true, 'a - tilde'],\n\t['&auml;',    '&#228;',  true, 'a - diaeresis'],\n\t['&aring;',   '&#229;',  true, 'a - ring above'],\n\t['&aelig;',   '&#230;',  true, 'ligature ae'],\n\t['&ccedil;',  '&#231;',  true, 'c - cedilla'],\n\t['&egrave;',  '&#232;',  true, 'e - grave'],\n\t['&eacute;',  '&#233;',  true, 'e - acute'],\n\t['&ecirc;',   '&#234;',  true, 'e - circumflex'],\n\t['&euml;',    '&#235;',  true, 'e - diaeresis'],\n\t['&igrave;',  '&#236;',  true, 'i - grave'],\n\t['&iacute;',  '&#237;',  true, 'i - acute'],\n\t['&icirc;',   '&#238;',  true, 'i - circumflex'],\n\t['&iuml;',    '&#239;',  true, 'i - diaeresis'],\n\t['&eth;',     '&#240;',  true, 'eth'],\n\t['&ntilde;',  '&#241;',  true, 'n - tilde'],\n\t['&ograve;',  '&#242;',  true, 'o - grave'],\n\t['&oacute;',  '&#243;',  true, 'o - acute'],\n\t['&ocirc;',   '&#244;',  true, 'o - circumflex'],\n\t['&otilde;',  '&#245;',  true, 'o - tilde'],\n\t['&ouml;',    '&#246;',  true, 'o - diaeresis'],\n\t['&oslash;',  '&#248;',  true, 'o slash'],\n\t['&oelig;',   '&#339;',  true, 'ligature oe'],\n\t['&scaron;',  '&#353;',  true, 's - caron'],\n\t['&ugrave;',  '&#249;',  true, 'u - grave'],\n\t['&uacute;',  '&#250;',  true, 'u - acute'],\n\t['&ucirc;',   '&#251;',  true, 'u - circumflex'],\n\t['&uuml;',    '&#252;',  true, 'u - diaeresis'],\n\t['&yacute;',  '&#253;',  true, 'y - acute'],\n\t['&thorn;',   '&#254;',  true, 'thorn'],\n\t['&yuml;',    '&#255;',  true, 'y - diaeresis'],\n    ['&Alpha;',   '&#913;',  true, 'Alpha'],\n\t['&Beta;',    '&#914;',  true, 'Beta'],\n\t['&Gamma;',   '&#915;',  true, 'Gamma'],\n\t['&Delta;',   '&#916;',  true, 'Delta'],\n\t['&Epsilon;', '&#917;',  true, 'Epsilon'],\n\t['&Zeta;',    '&#918;',  true, 'Zeta'],\n\t['&Eta;',     '&#919;',  true, 'Eta'],\n\t['&Theta;',   '&#920;',  true, 'Theta'],\n\t['&Iota;',    '&#921;',  true, 'Iota'],\n\t['&Kappa;',   '&#922;',  true, 'Kappa'],\n\t['&Lambda;',  '&#923;',  true, 'Lambda'],\n\t['&Mu;',      '&#924;',  true, 'Mu'],\n\t['&Nu;',      '&#925;',  true, 'Nu'],\n\t['&Xi;',      '&#926;',  true, 'Xi'],\n\t['&Omicron;', '&#927;',  true, 'Omicron'],\n\t['&Pi;',      '&#928;',  true, 'Pi'],\n\t['&Rho;',     '&#929;',  true, 'Rho'],\n\t['&Sigma;',   '&#931;',  true, 'Sigma'],\n\t['&Tau;',     '&#932;',  true, 'Tau'],\n\t['&Upsilon;', '&#933;',  true, 'Upsilon'],\n\t['&Phi;',     '&#934;',  true, 'Phi'],\n\t['&Chi;',     '&#935;',  true, 'Chi'],\n\t['&Psi;',     '&#936;',  true, 'Psi'],\n\t['&Omega;',   '&#937;',  true, 'Omega'],\n\t['&alpha;',   '&#945;',  true, 'alpha'],\n\t['&beta;',    '&#946;',  true, 'beta'],\n\t['&gamma;',   '&#947;',  true, 'gamma'],\n\t['&delta;',   '&#948;',  true, 'delta'],\n\t['&epsilon;', '&#949;',  true, 'epsilon'],\n\t['&zeta;',    '&#950;',  true, 'zeta'],\n\t['&eta;',     '&#951;',  true, 'eta'],\n\t['&theta;',   '&#952;',  true, 'theta'],\n\t['&iota;',    '&#953;',  true, 'iota'],\n\t['&kappa;',   '&#954;',  true, 'kappa'],\n\t['&lambda;',  '&#955;',  true, 'lambda'],\n\t['&mu;',      '&#956;',  true, 'mu'],\n\t['&nu;',      '&#957;',  true, 'nu'],\n\t['&xi;',      '&#958;',  true, 'xi'],\n\t['&omicron;', '&#959;',  true, 'omicron'],\n\t['&pi;',      '&#960;',  true, 'pi'],\n\t['&rho;',     '&#961;',  true, 'rho'],\n\t['&sigmaf;',  '&#962;',  true, 'final sigma'],\n\t['&sigma;',   '&#963;',  true, 'sigma'],\n\t['&tau;',     '&#964;',  true, 'tau'],\n\t['&upsilon;', '&#965;',  true, 'upsilon'],\n\t['&phi;',     '&#966;',  true, 'phi'],\n\t['&chi;',     '&#967;',  true, 'chi'],\n\t['&psi;',     '&#968;',  true, 'psi'],\n\t['&omega;',   '&#969;',  true, 'omega'],\n// symbols\n\t['&alefsym;', '&#8501;', false,'alef symbol'],\n\t['&piv;',     '&#982;',  false,'pi symbol'],\n\t['&real;',    '&#8476;', false,'real part symbol'],\n\t['&thetasym;','&#977;',  false,'theta symbol'],\n\t['&upsih;',   '&#978;',  false,'upsilon - hook symbol'],\n\t['&weierp;',  '&#8472;', false,'Weierstrass p'],\n\t['&image;',   '&#8465;', false,'imaginary part'],\n// arrows\n\t['&larr;',    '&#8592;', true, 'leftwards arrow'],\n\t['&uarr;',    '&#8593;', true, 'upwards arrow'],\n\t['&rarr;',    '&#8594;', true, 'rightwards arrow'],\n\t['&darr;',    '&#8595;', true, 'downwards arrow'],\n\t['&harr;',    '&#8596;', true, 'left right arrow'],\n\t['&crarr;',   '&#8629;', false,'carriage return'],\n\t['&lArr;',    '&#8656;', false,'leftwards double arrow'],\n\t['&uArr;',    '&#8657;', false,'upwards double arrow'],\n\t['&rArr;',    '&#8658;', false,'rightwards double arrow'],\n\t['&dArr;',    '&#8659;', false,'downwards double arrow'],\n\t['&hArr;',    '&#8660;', false,'left right double arrow'],\n\t['&there4;',  '&#8756;', false,'therefore'],\n\t['&sub;',     '&#8834;', false,'subset of'],\n\t['&sup;',     '&#8835;', false,'superset of'],\n\t['&nsub;',    '&#8836;', false,'not a subset of'],\n\t['&sube;',    '&#8838;', false,'subset of or equal to'],\n\t['&supe;',    '&#8839;', false,'superset of or equal to'],\n\t['&oplus;',   '&#8853;', false,'circled plus'],\n\t['&otimes;',  '&#8855;', false,'circled times'],\n\t['&perp;',    '&#8869;', false,'perpendicular'],\n\t['&sdot;',    '&#8901;', false,'dot operator'],\n\t['&lceil;',   '&#8968;', false,'left ceiling'],\n\t['&rceil;',   '&#8969;', false,'right ceiling'],\n\t['&lfloor;',  '&#8970;', false,'left floor'],\n\t['&rfloor;',  '&#8971;', false,'right floor'],\n\t['&lang;',    '&#9001;', false,'left-pointing angle bracket'],\n\t['&rang;',    '&#9002;', false,'right-pointing angle bracket'],\n\t['&loz;',     '&#9674;', true,'lozenge'],\n\t['&spades;',  '&#9824;', false,'black spade suit'],\n\t['&clubs;',   '&#9827;', true, 'black club suit'],\n\t['&hearts;',  '&#9829;', true, 'black heart suit'],\n\t['&diams;',   '&#9830;', true, 'black diamond suit'],\n\t['&ensp;',    '&#8194;', false,'en space'],\n\t['&emsp;',    '&#8195;', false,'em space'],\n\t['&thinsp;',  '&#8201;', false,'thin space'],\n\t['&zwnj;',    '&#8204;', false,'zero width non-joiner'],\n\t['&zwj;',     '&#8205;', false,'zero width joiner'],\n\t['&lrm;',     '&#8206;', false,'left-to-right mark'],\n\t['&rlm;',     '&#8207;', false,'right-to-left mark'],\n\t['&shy;',     '&#173;',  false,'soft hyphen']\n];\n\ntinyMCEPopup.onInit.add(function() {\n\ttinyMCEPopup.dom.setHTML('charmapView', renderCharMapHTML());\n});\n\nfunction renderCharMapHTML() {\n\tvar charsPerRow = 20, tdWidth=20, tdHeight=20, i;\n\tvar html = '<table border=\"0\" cellspacing=\"1\" cellpadding=\"0\" width=\"' + (tdWidth*charsPerRow) + '\"><tr height=\"' + tdHeight + '\">';\n\tvar cols=-1;\n\n\tfor (i=0; i<charmap.length; i++) {\n\t\tif (charmap[i][2]==true) {\n\t\t\tcols++;\n\t\t\thtml += ''\n\t\t\t\t+ '<td class=\"charmap\">'\n\t\t\t\t+ '<a onmouseover=\"previewChar(\\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\\',\\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\\',\\'' + charmap[i][3] + '\\');\" onfocus=\"previewChar(\\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\\',\\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\\',\\'' + charmap[i][3] + '\\');\" href=\"javascript:void(0)\" onclick=\"insertChar(\\'' + charmap[i][1].substring(2,charmap[i][1].length-1) + '\\');\" onclick=\"return false;\" onmousedown=\"return false;\" title=\"' + charmap[i][3] + '\">'\n\t\t\t\t+ charmap[i][1]\n\t\t\t\t+ '</a></td>';\n\t\t\tif ((cols+1) % charsPerRow == 0)\n\t\t\t\thtml += '</tr><tr height=\"' + tdHeight + '\">';\n\t\t}\n\t }\n\n\tif (cols % charsPerRow > 0) {\n\t\tvar padd = charsPerRow - (cols % charsPerRow);\n\t\tfor (var i=0; i<padd-1; i++)\n\t\t\thtml += '<td width=\"' + tdWidth + '\" height=\"' + tdHeight + '\" class=\"charmap\">&nbsp;</td>';\n\t}\n\n\thtml += '</tr></table>';\n\n\treturn html;\n}\n\nfunction insertChar(chr) {\n\ttinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';');\n\n\t// Refocus in window\n\tif (tinyMCEPopup.isWindow)\n\t\twindow.focus();\n\n\ttinyMCEPopup.editor.focus();\n\ttinyMCEPopup.close();\n}\n\nfunction previewChar(codeA, codeB, codeN) {\n\tvar elmA = document.getElementById('codeA');\n\tvar elmB = document.getElementById('codeB');\n\tvar elmV = document.getElementById('codeV');\n\tvar elmN = document.getElementById('codeN');\n\n\tif (codeA=='#160;') {\n\t\telmV.innerHTML = '__';\n\t} else {\n\t\telmV.innerHTML = '&' + codeA;\n\t}\n\n\telmB.innerHTML = '&amp;' + codeA;\n\telmA.innerHTML = '&amp;' + codeB;\n\telmN.innerHTML = codeN;\n}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/js/color_picker.js",
    "content": "tinyMCEPopup.requireLangPack();\n\nvar detail = 50, strhex = \"0123456789abcdef\", i, isMouseDown = false, isMouseOver = false;\n\nvar colors = [\n\t\"#000000\",\"#000033\",\"#000066\",\"#000099\",\"#0000cc\",\"#0000ff\",\"#330000\",\"#330033\",\n\t\"#330066\",\"#330099\",\"#3300cc\",\"#3300ff\",\"#660000\",\"#660033\",\"#660066\",\"#660099\",\n\t\"#6600cc\",\"#6600ff\",\"#990000\",\"#990033\",\"#990066\",\"#990099\",\"#9900cc\",\"#9900ff\",\n\t\"#cc0000\",\"#cc0033\",\"#cc0066\",\"#cc0099\",\"#cc00cc\",\"#cc00ff\",\"#ff0000\",\"#ff0033\",\n\t\"#ff0066\",\"#ff0099\",\"#ff00cc\",\"#ff00ff\",\"#003300\",\"#003333\",\"#003366\",\"#003399\",\n\t\"#0033cc\",\"#0033ff\",\"#333300\",\"#333333\",\"#333366\",\"#333399\",\"#3333cc\",\"#3333ff\",\n\t\"#663300\",\"#663333\",\"#663366\",\"#663399\",\"#6633cc\",\"#6633ff\",\"#993300\",\"#993333\",\n\t\"#993366\",\"#993399\",\"#9933cc\",\"#9933ff\",\"#cc3300\",\"#cc3333\",\"#cc3366\",\"#cc3399\",\n\t\"#cc33cc\",\"#cc33ff\",\"#ff3300\",\"#ff3333\",\"#ff3366\",\"#ff3399\",\"#ff33cc\",\"#ff33ff\",\n\t\"#006600\",\"#006633\",\"#006666\",\"#006699\",\"#0066cc\",\"#0066ff\",\"#336600\",\"#336633\",\n\t\"#336666\",\"#336699\",\"#3366cc\",\"#3366ff\",\"#666600\",\"#666633\",\"#666666\",\"#666699\",\n\t\"#6666cc\",\"#6666ff\",\"#996600\",\"#996633\",\"#996666\",\"#996699\",\"#9966cc\",\"#9966ff\",\n\t\"#cc6600\",\"#cc6633\",\"#cc6666\",\"#cc6699\",\"#cc66cc\",\"#cc66ff\",\"#ff6600\",\"#ff6633\",\n\t\"#ff6666\",\"#ff6699\",\"#ff66cc\",\"#ff66ff\",\"#009900\",\"#009933\",\"#009966\",\"#009999\",\n\t\"#0099cc\",\"#0099ff\",\"#339900\",\"#339933\",\"#339966\",\"#339999\",\"#3399cc\",\"#3399ff\",\n\t\"#669900\",\"#669933\",\"#669966\",\"#669999\",\"#6699cc\",\"#6699ff\",\"#999900\",\"#999933\",\n\t\"#999966\",\"#999999\",\"#9999cc\",\"#9999ff\",\"#cc9900\",\"#cc9933\",\"#cc9966\",\"#cc9999\",\n\t\"#cc99cc\",\"#cc99ff\",\"#ff9900\",\"#ff9933\",\"#ff9966\",\"#ff9999\",\"#ff99cc\",\"#ff99ff\",\n\t\"#00cc00\",\"#00cc33\",\"#00cc66\",\"#00cc99\",\"#00cccc\",\"#00ccff\",\"#33cc00\",\"#33cc33\",\n\t\"#33cc66\",\"#33cc99\",\"#33cccc\",\"#33ccff\",\"#66cc00\",\"#66cc33\",\"#66cc66\",\"#66cc99\",\n\t\"#66cccc\",\"#66ccff\",\"#99cc00\",\"#99cc33\",\"#99cc66\",\"#99cc99\",\"#99cccc\",\"#99ccff\",\n\t\"#cccc00\",\"#cccc33\",\"#cccc66\",\"#cccc99\",\"#cccccc\",\"#ccccff\",\"#ffcc00\",\"#ffcc33\",\n\t\"#ffcc66\",\"#ffcc99\",\"#ffcccc\",\"#ffccff\",\"#00ff00\",\"#00ff33\",\"#00ff66\",\"#00ff99\",\n\t\"#00ffcc\",\"#00ffff\",\"#33ff00\",\"#33ff33\",\"#33ff66\",\"#33ff99\",\"#33ffcc\",\"#33ffff\",\n\t\"#66ff00\",\"#66ff33\",\"#66ff66\",\"#66ff99\",\"#66ffcc\",\"#66ffff\",\"#99ff00\",\"#99ff33\",\n\t\"#99ff66\",\"#99ff99\",\"#99ffcc\",\"#99ffff\",\"#ccff00\",\"#ccff33\",\"#ccff66\",\"#ccff99\",\n\t\"#ccffcc\",\"#ccffff\",\"#ffff00\",\"#ffff33\",\"#ffff66\",\"#ffff99\",\"#ffffcc\",\"#ffffff\"\n];\n\nvar named = {\n\t'#F0F8FF':'AliceBlue','#FAEBD7':'AntiqueWhite','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige',\n\t'#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'BlanchedAlmond','#0000FF':'Blue','#8A2BE2':'BlueViolet','#A52A2A':'Brown',\n\t'#DEB887':'BurlyWood','#5F9EA0':'CadetBlue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'CornflowerBlue',\n\t'#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'DarkBlue','#008B8B':'DarkCyan','#B8860B':'DarkGoldenRod',\n\t'#A9A9A9':'DarkGray','#A9A9A9':'DarkGrey','#006400':'DarkGreen','#BDB76B':'DarkKhaki','#8B008B':'DarkMagenta','#556B2F':'DarkOliveGreen',\n\t'#FF8C00':'Darkorange','#9932CC':'DarkOrchid','#8B0000':'DarkRed','#E9967A':'DarkSalmon','#8FBC8F':'DarkSeaGreen','#483D8B':'DarkSlateBlue',\n\t'#2F4F4F':'DarkSlateGray','#2F4F4F':'DarkSlateGrey','#00CED1':'DarkTurquoise','#9400D3':'DarkViolet','#FF1493':'DeepPink','#00BFFF':'DeepSkyBlue',\n\t'#696969':'DimGray','#696969':'DimGrey','#1E90FF':'DodgerBlue','#B22222':'FireBrick','#FFFAF0':'FloralWhite','#228B22':'ForestGreen',\n\t'#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'GhostWhite','#FFD700':'Gold','#DAA520':'GoldenRod','#808080':'Gray','#808080':'Grey',\n\t'#008000':'Green','#ADFF2F':'GreenYellow','#F0FFF0':'HoneyDew','#FF69B4':'HotPink','#CD5C5C':'IndianRed','#4B0082':'Indigo','#FFFFF0':'Ivory',\n\t'#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'LavenderBlush','#7CFC00':'LawnGreen','#FFFACD':'LemonChiffon','#ADD8E6':'LightBlue',\n\t'#F08080':'LightCoral','#E0FFFF':'LightCyan','#FAFAD2':'LightGoldenRodYellow','#D3D3D3':'LightGray','#D3D3D3':'LightGrey','#90EE90':'LightGreen',\n\t'#FFB6C1':'LightPink','#FFA07A':'LightSalmon','#20B2AA':'LightSeaGreen','#87CEFA':'LightSkyBlue','#778899':'LightSlateGray','#778899':'LightSlateGrey',\n\t'#B0C4DE':'LightSteelBlue','#FFFFE0':'LightYellow','#00FF00':'Lime','#32CD32':'LimeGreen','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon',\n\t'#66CDAA':'MediumAquaMarine','#0000CD':'MediumBlue','#BA55D3':'MediumOrchid','#9370D8':'MediumPurple','#3CB371':'MediumSeaGreen','#7B68EE':'MediumSlateBlue',\n\t'#00FA9A':'MediumSpringGreen','#48D1CC':'MediumTurquoise','#C71585':'MediumVioletRed','#191970':'MidnightBlue','#F5FFFA':'MintCream','#FFE4E1':'MistyRose','#FFE4B5':'Moccasin',\n\t'#FFDEAD':'NavajoWhite','#000080':'Navy','#FDF5E6':'OldLace','#808000':'Olive','#6B8E23':'OliveDrab','#FFA500':'Orange','#FF4500':'OrangeRed','#DA70D6':'Orchid',\n\t'#EEE8AA':'PaleGoldenRod','#98FB98':'PaleGreen','#AFEEEE':'PaleTurquoise','#D87093':'PaleVioletRed','#FFEFD5':'PapayaWhip','#FFDAB9':'PeachPuff',\n\t'#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'PowderBlue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'RosyBrown','#4169E1':'RoyalBlue',\n\t'#8B4513':'SaddleBrown','#FA8072':'Salmon','#F4A460':'SandyBrown','#2E8B57':'SeaGreen','#FFF5EE':'SeaShell','#A0522D':'Sienna','#C0C0C0':'Silver',\n\t'#87CEEB':'SkyBlue','#6A5ACD':'SlateBlue','#708090':'SlateGray','#708090':'SlateGrey','#FFFAFA':'Snow','#00FF7F':'SpringGreen',\n\t'#4682B4':'SteelBlue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet',\n\t'#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'WhiteSmoke','#FFFF00':'Yellow','#9ACD32':'YellowGreen'\n};\n\nfunction init() {\n\tvar inputColor = convertRGBToHex(tinyMCEPopup.getWindowArg('input_color'));\n\n\ttinyMCEPopup.resizeToInnerSize();\n\n\tgeneratePicker();\n\n\tif (inputColor) {\n\t\tchangeFinalColor(inputColor);\n\n\t\tcol = convertHexToRGB(inputColor);\n\n\t\tif (col)\n\t\t\tupdateLight(col.r, col.g, col.b);\n\t}\n}\n\nfunction insertAction() {\n\tvar color = document.getElementById(\"color\").value, f = tinyMCEPopup.getWindowArg('func');\n\n\ttinyMCEPopup.restoreSelection();\n\n\tif (f)\n\t\tf(color);\n\n\ttinyMCEPopup.close();\n}\n\nfunction showColor(color, name) {\n\tif (name)\n\t\tdocument.getElementById(\"colorname\").innerHTML = name;\n\n\tdocument.getElementById(\"preview\").style.backgroundColor = color;\n\tdocument.getElementById(\"color\").value = color.toLowerCase();\n}\n\nfunction convertRGBToHex(col) {\n\tvar re = new RegExp(\"rgb\\\\s*\\\\(\\\\s*([0-9]+).*,\\\\s*([0-9]+).*,\\\\s*([0-9]+).*\\\\)\", \"gi\");\n\n\tif (!col)\n\t\treturn col;\n\n\tvar rgb = col.replace(re, \"$1,$2,$3\").split(',');\n\tif (rgb.length == 3) {\n\t\tr = parseInt(rgb[0]).toString(16);\n\t\tg = parseInt(rgb[1]).toString(16);\n\t\tb = parseInt(rgb[2]).toString(16);\n\n\t\tr = r.length == 1 ? '0' + r : r;\n\t\tg = g.length == 1 ? '0' + g : g;\n\t\tb = b.length == 1 ? '0' + b : b;\n\n\t\treturn \"#\" + r + g + b;\n\t}\n\n\treturn col;\n}\n\nfunction convertHexToRGB(col) {\n\tif (col.indexOf('#') != -1) {\n\t\tcol = col.replace(new RegExp('[^0-9A-F]', 'gi'), '');\n\n\t\tr = parseInt(col.substring(0, 2), 16);\n\t\tg = parseInt(col.substring(2, 4), 16);\n\t\tb = parseInt(col.substring(4, 6), 16);\n\n\t\treturn {r : r, g : g, b : b};\n\t}\n\n\treturn null;\n}\n\nfunction generatePicker() {\n\tvar el = document.getElementById('light'), h = '', i;\n\n\tfor (i = 0; i < detail; i++){\n\t\th += '<div id=\"gs'+i+'\" style=\"background-color:#000000; width:15px; height:3px; border-style:none; border-width:0px;\"'\n\t\t+ ' onclick=\"changeFinalColor(this.style.backgroundColor)\"'\n\t\t+ ' onmousedown=\"isMouseDown = true; return false;\"'\n\t\t+ ' onmouseup=\"isMouseDown = false;\"'\n\t\t+ ' onmousemove=\"if (isMouseDown && isMouseOver) changeFinalColor(this.style.backgroundColor); return false;\"'\n\t\t+ ' onmouseover=\"isMouseOver = true;\"'\n\t\t+ ' onmouseout=\"isMouseOver = false;\"'\n\t\t+ '></div>';\n\t}\n\n\tel.innerHTML = h;\n}\n\nfunction generateWebColors() {\n\tvar el = document.getElementById('webcolors'), h = '', i;\n\n\tif (el.className == 'generated')\n\t\treturn;\n\n\th += '<table border=\"0\" cellspacing=\"1\" cellpadding=\"0\">'\n\t\t+ '<tr>';\n\n\tfor (i=0; i<colors.length; i++) {\n\t\th += '<td bgcolor=\"' + colors[i] + '\" width=\"10\" height=\"10\">'\n\t\t\t+ '<a href=\"javascript:insertAction();\" onfocus=\"showColor(\\'' + colors[i] +  '\\');\" onmouseover=\"showColor(\\'' + colors[i] +  '\\');\" style=\"display:block;width:10px;height:10px;overflow:hidden;\">'\n\t\t\t+ '</a></td>';\n\t\tif ((i+1) % 18 == 0)\n\t\t\th += '</tr><tr>';\n\t}\n\n\th += '</table>';\n\n\tel.innerHTML = h;\n\tel.className = 'generated';\n}\n\nfunction generateNamedColors() {\n\tvar el = document.getElementById('namedcolors'), h = '', n, v, i = 0;\n\n\tif (el.className == 'generated')\n\t\treturn;\n\n\tfor (n in named) {\n\t\tv = named[n];\n\t\th += '<a href=\"javascript:insertAction();\" onmouseover=\"showColor(\\'' + n +  '\\',\\'' + v + '\\');\" style=\"background-color: ' + n + '\"><!-- IE --></a>'\n\t}\n\n\tel.innerHTML = h;\n\tel.className = 'generated';\n}\n\nfunction dechex(n) {\n\treturn strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16);\n}\n\nfunction computeColor(e) {\n\tvar x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB;\n\n\tx = e.offsetX ? e.offsetX : (e.target ? e.clientX - e.target.x : 0);\n\ty = e.offsetY ? e.offsetY : (e.target ? e.clientY - e.target.y : 0);\n\n\tpartWidth = document.getElementById('colors').width / 6;\n\tpartDetail = detail / 2;\n\timHeight = document.getElementById('colors').height;\n\n\tr = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255;\n\tg = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255\t+ (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth);\n\tb = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth);\n\n\tcoef = (imHeight - y) / imHeight;\n\tr = 128 + (r - 128) * coef;\n\tg = 128 + (g - 128) * coef;\n\tb = 128 + (b - 128) * coef;\n\n\tchangeFinalColor('#' + dechex(r) + dechex(g) + dechex(b));\n\tupdateLight(r, g, b);\n}\n\nfunction updateLight(r, g, b) {\n\tvar i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color;\n\n\tfor (i=0; i<detail; i++) {\n\t\tif ((i>=0) && (i<partDetail)) {\n\t\t\tfinalCoef = i / partDetail;\n\t\t\tfinalR = dechex(255 - (255 - r) * finalCoef);\n\t\t\tfinalG = dechex(255 - (255 - g) * finalCoef);\n\t\t\tfinalB = dechex(255 - (255 - b) * finalCoef);\n\t\t} else {\n\t\t\tfinalCoef = 2 - i / partDetail;\n\t\t\tfinalR = dechex(r * finalCoef);\n\t\t\tfinalG = dechex(g * finalCoef);\n\t\t\tfinalB = dechex(b * finalCoef);\n\t\t}\n\n\t\tcolor = finalR + finalG + finalB;\n\n\t\tsetCol('gs' + i, '#'+color);\n\t}\n}\n\nfunction changeFinalColor(color) {\n\tif (color.indexOf('#') == -1)\n\t\tcolor = convertRGBToHex(color);\n\n\tsetCol('preview', color);\n\tdocument.getElementById('color').value = color;\n}\n\nfunction setCol(e, c) {\n\ttry {\n\t\tdocument.getElementById(e).style.backgroundColor = c;\n\t} catch (ex) {\n\t\t// Ignore IE warning\n\t}\n}\n\ntinyMCEPopup.onInit.add(init);\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/js/image.js",
    "content": "var ImageDialog = {\n\tpreInit : function() {\n\t\tvar url;\n\n\t\ttinyMCEPopup.requireLangPack();\n\n\t\tif (url = tinyMCEPopup.getParam(\"external_image_list_url\"))\n\t\t\tdocument.write('<script language=\"javascript\" type=\"text/javascript\" src=\"' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '\"></script>');\n\t},\n\n\tinit : function() {\n\t\tvar f = document.forms[0], ed = tinyMCEPopup.editor;\n\n\t\t// Setup browse button\n\t\tdocument.getElementById('srcbrowsercontainer').innerHTML = getBrowserHTML('srcbrowser','src','image','theme_advanced_image');\n\t\tif (isVisible('srcbrowser'))\n\t\t\tdocument.getElementById('src').style.width = '180px';\n\n\t\te = ed.selection.getNode();\n\n\t\tthis.fillFileList('image_list', 'tinyMCEImageList');\n\n\t\tif (e.nodeName == 'IMG') {\n\t\t\tf.src.value = ed.dom.getAttrib(e, 'src');\n\t\t\tf.alt.value = ed.dom.getAttrib(e, 'alt');\n\t\t\tf.border.value = this.getAttrib(e, 'border');\n\t\t\tf.vspace.value = this.getAttrib(e, 'vspace');\n\t\t\tf.hspace.value = this.getAttrib(e, 'hspace');\n\t\t\tf.width.value = ed.dom.getAttrib(e, 'width');\n\t\t\tf.height.value = ed.dom.getAttrib(e, 'height');\n\t\t\tf.insert.value = ed.getLang('update');\n\t\t\tthis.styleVal = ed.dom.getAttrib(e, 'style');\n\t\t\tselectByValue(f, 'image_list', f.src.value);\n\t\t\tselectByValue(f, 'align', this.getAttrib(e, 'align'));\n\t\t\tthis.updateStyle();\n\t\t}\n\t},\n\n\tfillFileList : function(id, l) {\n\t\tvar dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl;\n\n\t\tl = window[l];\n\n\t\tif (l && l.length > 0) {\n\t\t\tlst.options[lst.options.length] = new Option('', '');\n\n\t\t\ttinymce.each(l, function(o) {\n\t\t\t\tlst.options[lst.options.length] = new Option(o[0], o[1]);\n\t\t\t});\n\t\t} else\n\t\t\tdom.remove(dom.getParent(id, 'tr'));\n\t},\n\n\tupdate : function() {\n\t\tvar f = document.forms[0], nl = f.elements, ed = tinyMCEPopup.editor, args = {}, el;\n\n\t\ttinyMCEPopup.restoreSelection();\n\n\t\tif (f.src.value === '') {\n\t\t\tif (ed.selection.getNode().nodeName == 'IMG') {\n\t\t\t\ted.dom.remove(ed.selection.getNode());\n\t\t\t\ted.execCommand('mceRepaint');\n\t\t\t}\n\n\t\t\ttinyMCEPopup.close();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!ed.settings.inline_styles) {\n\t\t\targs = tinymce.extend(args, {\n\t\t\t\tvspace : nl.vspace.value,\n\t\t\t\thspace : nl.hspace.value,\n\t\t\t\tborder : nl.border.value,\n\t\t\t\talign : getSelectValue(f, 'align')\n\t\t\t});\n\t\t} else\n\t\t\targs.style = this.styleVal;\n\n\t\ttinymce.extend(args, {\n\t\t\tsrc : f.src.value,\n\t\t\talt : f.alt.value,\n\t\t\twidth : f.width.value,\n\t\t\theight : f.height.value\n\t\t});\n\n\t\tel = ed.selection.getNode();\n\n\t\tif (el && el.nodeName == 'IMG') {\n\t\t\ted.dom.setAttribs(el, args);\n\t\t} else {\n\t\t\ted.execCommand('mceInsertContent', false, '<img id=\"__mce_tmp\" />', {skip_undo : 1});\n\t\t\ted.dom.setAttribs('__mce_tmp', args);\n\t\t\ted.dom.setAttrib('__mce_tmp', 'id', '');\n\t\t\ted.undoManager.add();\n\t\t}\n\n\t\ttinyMCEPopup.close();\n\t},\n\n\tupdateStyle : function() {\n\t\tvar dom = tinyMCEPopup.dom, st, v, f = document.forms[0];\n\n\t\tif (tinyMCEPopup.editor.settings.inline_styles) {\n\t\t\tst = tinyMCEPopup.dom.parseStyle(this.styleVal);\n\n\t\t\t// Handle align\n\t\t\tv = getSelectValue(f, 'align');\n\t\t\tif (v) {\n\t\t\t\tif (v == 'left' || v == 'right') {\n\t\t\t\t\tst['float'] = v;\n\t\t\t\t\tdelete st['vertical-align'];\n\t\t\t\t} else {\n\t\t\t\t\tst['vertical-align'] = v;\n\t\t\t\t\tdelete st['float'];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdelete st['float'];\n\t\t\t\tdelete st['vertical-align'];\n\t\t\t}\n\n\t\t\t// Handle border\n\t\t\tv = f.border.value;\n\t\t\tif (v || v == '0') {\n\t\t\t\tif (v == '0')\n\t\t\t\t\tst['border'] = '0';\n\t\t\t\telse\n\t\t\t\t\tst['border'] = v + 'px solid black';\n\t\t\t} else\n\t\t\t\tdelete st['border'];\n\n\t\t\t// Handle hspace\n\t\t\tv = f.hspace.value;\n\t\t\tif (v) {\n\t\t\t\tdelete st['margin'];\n\t\t\t\tst['margin-left'] = v + 'px';\n\t\t\t\tst['margin-right'] = v + 'px';\n\t\t\t} else {\n\t\t\t\tdelete st['margin-left'];\n\t\t\t\tdelete st['margin-right'];\n\t\t\t}\n\n\t\t\t// Handle vspace\n\t\t\tv = f.vspace.value;\n\t\t\tif (v) {\n\t\t\t\tdelete st['margin'];\n\t\t\t\tst['margin-top'] = v + 'px';\n\t\t\t\tst['margin-bottom'] = v + 'px';\n\t\t\t} else {\n\t\t\t\tdelete st['margin-top'];\n\t\t\t\tdelete st['margin-bottom'];\n\t\t\t}\n\n\t\t\t// Merge\n\t\t\tst = tinyMCEPopup.dom.parseStyle(dom.serializeStyle(st));\n\t\t\tthis.styleVal = dom.serializeStyle(st);\n\t\t}\n\t},\n\n\tgetAttrib : function(e, at) {\n\t\tvar ed = tinyMCEPopup.editor, dom = ed.dom, v, v2;\n\n\t\tif (ed.settings.inline_styles) {\n\t\t\tswitch (at) {\n\t\t\t\tcase 'align':\n\t\t\t\t\tif (v = dom.getStyle(e, 'float'))\n\t\t\t\t\t\treturn v;\n\n\t\t\t\t\tif (v = dom.getStyle(e, 'vertical-align'))\n\t\t\t\t\t\treturn v;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'hspace':\n\t\t\t\t\tv = dom.getStyle(e, 'margin-left')\n\t\t\t\t\tv2 = dom.getStyle(e, 'margin-right');\n\t\t\t\t\tif (v && v == v2)\n\t\t\t\t\t\treturn parseInt(v.replace(/[^0-9]/g, ''));\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'vspace':\n\t\t\t\t\tv = dom.getStyle(e, 'margin-top')\n\t\t\t\t\tv2 = dom.getStyle(e, 'margin-bottom');\n\t\t\t\t\tif (v && v == v2)\n\t\t\t\t\t\treturn parseInt(v.replace(/[^0-9]/g, ''));\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'border':\n\t\t\t\t\tv = 0;\n\n\t\t\t\t\ttinymce.each(['top', 'right', 'bottom', 'left'], function(sv) {\n\t\t\t\t\t\tsv = dom.getStyle(e, 'border-' + sv + '-width');\n\n\t\t\t\t\t\t// False or not the same as prev\n\t\t\t\t\t\tif (!sv || (sv != v && v !== 0)) {\n\t\t\t\t\t\t\tv = 0;\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (sv)\n\t\t\t\t\t\t\tv = sv;\n\t\t\t\t\t});\n\n\t\t\t\t\tif (v)\n\t\t\t\t\t\treturn parseInt(v.replace(/[^0-9]/g, ''));\n\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (v = dom.getAttrib(e, at))\n\t\t\treturn v;\n\n\t\treturn '';\n\t},\n\n\tresetImageData : function() {\n\t\tvar f = document.forms[0];\n\n\t\tf.width.value = f.height.value = \"\";\t\n\t},\n\n\tupdateImageData : function() {\n\t\tvar f = document.forms[0], t = ImageDialog;\n\n\t\tif (f.width.value == \"\")\n\t\t\tf.width.value = t.preloadImg.width;\n\n\t\tif (f.height.value == \"\")\n\t\t\tf.height.value = t.preloadImg.height;\n\t},\n\n\tgetImageData : function() {\n\t\tvar f = document.forms[0];\n\n\t\tthis.preloadImg = new Image();\n\t\tthis.preloadImg.onload = this.updateImageData;\n\t\tthis.preloadImg.onerror = this.resetImageData;\n\t\tthis.preloadImg.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(f.src.value);\n\t}\n};\n\nImageDialog.preInit();\ntinyMCEPopup.onInit.add(ImageDialog.init, ImageDialog);\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/js/link.js",
    "content": "tinyMCEPopup.requireLangPack();\n\nvar LinkDialog = {\n\tpreInit : function() {\n\t\tvar url;\n\n\t\tif (url = tinyMCEPopup.getParam(\"external_link_list_url\"))\n\t\t\tdocument.write('<script language=\"javascript\" type=\"text/javascript\" src=\"' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '\"></script>');\n\t},\n\n\tinit : function() {\n\t\tvar f = document.forms[0], ed = tinyMCEPopup.editor;\n\n\t\t// Setup browse button\n\t\tdocument.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser', 'href', 'file', 'theme_advanced_link');\n\t\tif (isVisible('hrefbrowser'))\n\t\t\tdocument.getElementById('href').style.width = '180px';\n\n\t\tthis.fillClassList('class_list');\n\t\tthis.fillFileList('link_list', 'tinyMCELinkList');\n\t\tthis.fillTargetList('target_list');\n\n\t\tif (e = ed.dom.getParent(ed.selection.getNode(), 'A')) {\n\t\t\tf.href.value = ed.dom.getAttrib(e, 'href');\n\t\t\tf.linktitle.value = ed.dom.getAttrib(e, 'title');\n\t\t\tf.insert.value = ed.getLang('update');\n\t\t\tselectByValue(f, 'link_list', f.href.value);\n\t\t\tselectByValue(f, 'target_list', ed.dom.getAttrib(e, 'target'));\n\t\t\tselectByValue(f, 'class_list', ed.dom.getAttrib(e, 'class'));\n\t\t}\n\t},\n\n\tupdate : function() {\n\t\tvar f = document.forms[0], ed = tinyMCEPopup.editor, e, b;\n\n\t\ttinyMCEPopup.restoreSelection();\n\t\te = ed.dom.getParent(ed.selection.getNode(), 'A');\n\n\t\t// Remove element if there is no href\n\t\tif (!f.href.value) {\n\t\t\tif (e) {\n\t\t\t\ttinyMCEPopup.execCommand(\"mceBeginUndoLevel\");\n\t\t\t\tb = ed.selection.getBookmark();\n\t\t\t\ted.dom.remove(e, 1);\n\t\t\t\ted.selection.moveToBookmark(b);\n\t\t\t\ttinyMCEPopup.execCommand(\"mceEndUndoLevel\");\n\t\t\t\ttinyMCEPopup.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\ttinyMCEPopup.execCommand(\"mceBeginUndoLevel\");\n\n\t\t// Create new anchor elements\n\t\tif (e == null) {\n\t\t\ted.getDoc().execCommand(\"unlink\", false, null);\n\t\t\ttinyMCEPopup.execCommand(\"CreateLink\", false, \"#mce_temp_url#\", {skip_undo : 1});\n\n\t\t\ttinymce.each(ed.dom.select(\"a\"), function(n) {\n\t\t\t\tif (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') {\n\t\t\t\t\te = n;\n\n\t\t\t\t\ted.dom.setAttribs(e, {\n\t\t\t\t\t\thref : f.href.value,\n\t\t\t\t\t\ttitle : f.linktitle.value,\n\t\t\t\t\t\ttarget : f.target_list ? getSelectValue(f, \"target_list\") : null,\n\t\t\t\t\t\t'class' : f.class_list ? getSelectValue(f, \"class_list\") : null\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\ted.dom.setAttribs(e, {\n\t\t\t\thref : f.href.value,\n\t\t\t\ttitle : f.linktitle.value,\n\t\t\t\ttarget : f.target_list ? getSelectValue(f, \"target_list\") : null,\n\t\t\t\t'class' : f.class_list ? getSelectValue(f, \"class_list\") : null\n\t\t\t});\n\t\t}\n\n\t\t// Don't move caret if selection was image\n\t\tif (e.childNodes.length != 1 || e.firstChild.nodeName != 'IMG') {\n\t\t\ted.focus();\n\t\t\ted.selection.select(e);\n\t\t\ted.selection.collapse(0);\n\t\t\ttinyMCEPopup.storeSelection();\n\t\t}\n\n\t\ttinyMCEPopup.execCommand(\"mceEndUndoLevel\");\n\t\ttinyMCEPopup.close();\n\t},\n\n\tcheckPrefix : function(n) {\n\t\tif (n.value && Validator.isEmail(n) && !/^\\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_email')))\n\t\t\tn.value = 'mailto:' + n.value;\n\n\t\tif (/^\\s*www\\./i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_external')))\n\t\t\tn.value = 'http://' + n.value;\n\t},\n\n\tfillFileList : function(id, l) {\n\t\tvar dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl;\n\n\t\tl = window[l];\n\n\t\tif (l && l.length > 0) {\n\t\t\tlst.options[lst.options.length] = new Option('', '');\n\n\t\t\ttinymce.each(l, function(o) {\n\t\t\t\tlst.options[lst.options.length] = new Option(o[0], o[1]);\n\t\t\t});\n\t\t} else\n\t\t\tdom.remove(dom.getParent(id, 'tr'));\n\t},\n\n\tfillClassList : function(id) {\n\t\tvar dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl;\n\n\t\tif (v = tinyMCEPopup.getParam('theme_advanced_styles')) {\n\t\t\tcl = [];\n\n\t\t\ttinymce.each(v.split(';'), function(v) {\n\t\t\t\tvar p = v.split('=');\n\n\t\t\t\tcl.push({'title' : p[0], 'class' : p[1]});\n\t\t\t});\n\t\t} else\n\t\t\tcl = tinyMCEPopup.editor.dom.getClasses();\n\n\t\tif (cl.length > 0) {\n\t\t\tlst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), '');\n\n\t\t\ttinymce.each(cl, function(o) {\n\t\t\t\tlst.options[lst.options.length] = new Option(o.title || o['class'], o['class']);\n\t\t\t});\n\t\t} else\n\t\t\tdom.remove(dom.getParent(id, 'tr'));\n\t},\n\n\tfillTargetList : function(id) {\n\t\tvar dom = tinyMCEPopup.dom, lst = dom.get(id), v;\n\n\t\tlst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), '');\n\t\tlst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_same'), '_self');\n\t\tlst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_blank'), '_blank');\n\n\t\tif (v = tinyMCEPopup.getParam('theme_advanced_link_targets')) {\n\t\t\ttinymce.each(v.split(','), function(v) {\n\t\t\t\tv = v.split('=');\n\t\t\t\tlst.options[lst.options.length] = new Option(v[0], v[1]);\n\t\t\t});\n\t\t}\n\t}\n};\n\nLinkDialog.preInit();\ntinyMCEPopup.onInit.add(LinkDialog.init, LinkDialog);\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/js/source_editor.js",
    "content": "tinyMCEPopup.requireLangPack();\ntinyMCEPopup.onInit.add(onLoadInit);\n\nfunction saveContent() {\n\ttinyMCEPopup.editor.setContent(document.getElementById('htmlSource').value, {source_view : true});\n\ttinyMCEPopup.close();\n}\n\nfunction onLoadInit() {\n\ttinyMCEPopup.resizeToInnerSize();\n\n\t// Remove Gecko spellchecking\n\tif (tinymce.isGecko)\n\t\tdocument.body.spellcheck = tinyMCEPopup.editor.getParam(\"gecko_spellcheck\");\n\n\tdocument.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent({source_view : true});\n\n\tif (tinyMCEPopup.editor.getParam(\"theme_advanced_source_editor_wrap\", true)) {\n\t\tsetWrap('soft');\n\t\tdocument.getElementById('wraped').checked = true;\n\t}\n\n\tresizeInputs();\n}\n\nfunction setWrap(val) {\n\tvar v, n, s = document.getElementById('htmlSource');\n\n\ts.wrap = val;\n\n\tif (!tinymce.isIE) {\n\t\tv = s.value;\n\t\tn = s.cloneNode(false);\n\t\tn.setAttribute(\"wrap\", val);\n\t\ts.parentNode.replaceChild(n, s);\n\t\tn.value = v;\n\t}\n}\n\nfunction toggleWordWrap(elm) {\n\tif (elm.checked)\n\t\tsetWrap('soft');\n\telse\n\t\tsetWrap('off');\n}\n\nvar wHeight=0, wWidth=0, owHeight=0, owWidth=0;\n\nfunction resizeInputs() {\n\tvar el = document.getElementById('htmlSource');\n\n\tif (!tinymce.isIE) {\n\t\t wHeight = self.innerHeight - 65;\n\t\t wWidth = self.innerWidth - 16;\n\t} else {\n\t\t wHeight = document.body.clientHeight - 70;\n\t\t wWidth = document.body.clientWidth - 16;\n\t}\n\n\tel.style.height = Math.abs(wHeight) + 'px';\n\tel.style.width  = Math.abs(wWidth) + 'px';\n}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/langs/typecho.js",
    "content": "/** hack js laguage pack */\n//tinymce.ScriptLoader.load(tinymce.baseURL + '/langs.php');\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/langs/typecho_dlg.js",
    "content": "\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/link.htm",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n\t<title>{#advanced_dlg.link_title}</title>\n\t<script type=\"text/javascript\" src=\"../../tiny_mce_popup.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/mctabs.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/form_utils.js\"></script>\n\t<script type=\"text/javascript\" src=\"../../utils/validate.js\"></script>\n\t<script type=\"text/javascript\" src=\"js/link.js\"></script>\n</head>\n<body id=\"link\" style=\"display: none\">\n<form onsubmit=\"LinkDialog.update();return false;\" action=\"#\">\n\t<div class=\"tabs\">\n\t\t<ul>\n\t\t\t<li id=\"general_tab\" class=\"current\"><span><a href=\"javascript:mcTabs.displayTab('general_tab','general_panel');\" onmousedown=\"return false;\">{#advanced_dlg.link_title}</a></span></li>\n\t\t</ul>\n\t</div>\n\n\t<div class=\"panel_wrapper\">\n\t\t<div id=\"general_panel\" class=\"panel current\">\n\n\t\t<table border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n          <tr>\n            <td class=\"nowrap\"><label for=\"href\">{#advanced_dlg.link_url}</label></td>\n            <td><table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> \n\t\t\t\t  <tr> \n\t\t\t\t\t<td><input id=\"href\" name=\"href\" type=\"text\" class=\"mceFocus\" value=\"\" style=\"width: 200px\" onchange=\"LinkDialog.checkPrefix(this);\" /></td> \n\t\t\t\t\t<td id=\"hrefbrowsercontainer\">&nbsp;</td>\n\t\t\t\t  </tr> \n\t\t\t\t</table></td>\n          </tr>\n\t\t  <tr>\n\t\t\t<td><label for=\"link_list\">{#advanced_dlg.link_list}</label></td>\n\t\t\t<td><select id=\"link_list\" name=\"link_list\" onchange=\"document.getElementById('href').value=this.options[this.selectedIndex].value;\"></select></td>\n\t\t  </tr>\n\t\t<tr>\n\t\t\t<td><label id=\"targetlistlabel\" for=\"targetlist\">{#advanced_dlg.link_target}</label></td>\n\t\t\t<td><select id=\"target_list\" name=\"target_list\"></select></td>\n\t\t</tr>\n          <tr>\n            <td class=\"nowrap\"><label for=\"linktitle\">{#advanced_dlg.link_titlefield}</label></td>\n            <td><input id=\"linktitle\" name=\"linktitle\" type=\"text\" value=\"\" style=\"width: 200px\" /></td>\n          </tr>\n\t\t\t<tr>\n\t\t\t\t<td><label for=\"class_list\">{#class_name}</label></td>\n\t\t\t\t<td><select id=\"class_list\" name=\"class_list\"></select></td>\n\t\t\t</tr>\n        </table>\n\t\t</div>\n\t</div>\n\n\t<div class=\"mceActionPanel\">\n\t\t<div style=\"float: left\">\n\t\t\t<input type=\"submit\" id=\"insert\" name=\"insert\" value=\"{#insert}\" />\n\t\t</div>\n\n\t\t<div style=\"float: right\">\n\t\t\t<input type=\"button\" id=\"cancel\" name=\"cancel\" value=\"{#cancel}\" onclick=\"tinyMCEPopup.close();\" />\n\t\t</div>\n\t</div>\n</form>\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/skins/typecho/content.css",
    "content": "body, td, pre {color:#000; font-family:Georgia,\"Times New Roman\",\"Bitstream Charter\",Times,serif; font-size:13px; line-height: 18px; margin:8px;}\nbody {background:#FFF;}\nbody.mceForceColors {background:#FFF; color:#000;}\nh1 {font-size: 2em}\nh2 {font-size: 1.5em}\nh3 {font-size: 1.17em}\nh4 {font-size: 1em}\nh5 {font-size: .83em}\nh6 {font-size: .75em}\n.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;}\na.mceItemAnchor {width:12px; line-height:6px; overflow:hidden; padding-left:12px; background:url(img/items.gif) no-repeat bottom left;}\nimg.mceItemAnchor {width:12px; height:12px; background:url(img/items.gif) no-repeat;}\nimg {border:0;}\ntable {cursor:default}\ntable td, table th {cursor:text}\nins {border-bottom:1px solid green; text-decoration: none; color:green}\ndel {color:red; text-decoration:line-through}\ncite {border-bottom:1px dashed blue}\nacronym {border-bottom:1px dotted #CCC; cursor:help}\nabbr, html\\:abbr {border-bottom:1px dashed #CCC; cursor:help}\ncode {display: block; border: 1px solid #AAAAAA; background: #F1ECDD; color: #000; line-height: 16px; overflow: auto;\n\tfont-family: 'andale mono','lucida console',monospace; font-size: 12px; padding: 10px; margin: 10px 0;}\npre {margin: 10px 0; padding: 5px; display: block; font-size: 12px;\n\tbackground: #EAF7FF; border: 1px solid #D5E7F0; font-family: \"Courier New\",Helvetica,sans-serif;}\n\n/* IE */\n* html body {\nscrollbar-3dlight-color:#F0F0EE;\nscrollbar-arrow-color:#676662;\nscrollbar-base-color:#F0F0EE;\nscrollbar-darkshadow-color:#DDD;\nscrollbar-face-color:#E0E0DD;\nscrollbar-highlight-color:#F0F0EE;\nscrollbar-shadow-color:#F0F0EE;\nscrollbar-track-color:#F5F5F5;\n}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/skins/typecho/dialog.css",
    "content": "/* Generic */\nbody {\nfont-family:\"Lucida Grande\",\"Lucida Sans Unicode\",Tahoma,Verdana; font-size:11px;\nscrollbar-3dlight-color:#F0F0EE;\nscrollbar-arrow-color:#676662;\nscrollbar-base-color:#F0F0EE;\nscrollbar-darkshadow-color:#DDDDDD;\nscrollbar-face-color:#E0E0DD;\nscrollbar-highlight-color:#F0F0EE;\nscrollbar-shadow-color:#F0F0EE;\nscrollbar-track-color:#F5F5F5;\nbackground:#DEE4C5;\npadding:0;\nmargin:8px 8px 0 8px;\n}\n\nhtml {background:#DEE4C5;}\ntd {font-size:9pt; padding: 0 6px 0 0; line-height: 32px;}\ntextarea {resize:none;outline:none;}\na:link, a:visited {color:black;}\na:hover {color:#2B6FB6;}\n\n/* Forms */\nfieldset {margin:0; padding:4px; border:none; font-family:\"Lucida Grande\",\"Lucida Sans Unicode\",Tahoma,Verdana; font-size:10pt;}\nlegend {color:#BD6800; font-weight:bold; margin-top: 10px;}\nlabel.msg {display:none;}\nlabel.invalid {color:#EE0000; display:inline;}\ninput.invalid {border:1px solid #EE0000;}\ninput {background:#FFF; border:1px solid #CCC;}\ninput, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:9pt;}\ninput, select, textarea {border:1px solid #808080;}\ninput.radio {border:1px none #000000; background:transparent; vertical-align:middle;}\ninput.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;}\n.input_noborder {border:0;}\n\n/* Buttons */\n#insert, #cancel, input.button, .updateButton {\nborder:0; margin:0; padding:0;\nfont-weight:bold;\nwidth:94px; height:26px;\nbackground: #fff url(./img/sprite.gif) repeat-x scroll center top;\nborder:1px solid #AFBA7C;\ncursor:pointer;\npadding-bottom:2px;\n-moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -moz-border-radius-bottomleft: 3px; -moz-border-radius-bottomright: 3px;\n-webkit-border-top-left-radius: 3px; -webkit-border-top-right-radius: 3px; -webkit-border-bottom-left-radius: 3px; -webkit-border-bottom-right-radius: 3px;\n/* hope IE support border radius, God save me! */\nborder-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px;\n}\n\n#insert:hover, #cancel:hover, input.button:hover, .updateButton:hover {\nborder:1px solid #545c30;\nbackground: #fff url(./img/sprite.gif) bottom repeat-x;\n}\n\n/* Browse */\na.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;}\n.mceOldBoxModel a.browse span {width:22px; height:20px;}\na.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;}\na.browse span.disabled {border:1px solid white; opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\na.browse:hover span.disabled {border:1px solid white; background-color:transparent;}\na.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;}\n.mceOldBoxModel a.pickcolor span {width:21px; height:17px;}\na.pickcolor:hover span {background-color:#B2BBD0;}\na.pickcolor:hover span.disabled {}\n\n/* Charmap */\ntable.charmap {border:1px solid #AAA; text-align:center}\ntd.charmap, #charmap a {width:18px; height:18px; color:#000; border:1px solid #AAA; text-align:center; font-size:12px; vertical-align:middle; line-height: 18px;}\n#charmap a {display:block; color:#000; text-decoration:none; border:0}\n#charmap a:hover {background:#CCC;color:#2B6FB6}\n#charmap #codeN {font-size:9pt; font-family:Arial,Helvetica,sans-serif; text-align:center}\n#charmap #codeV {font-size:40px; height:80px; border:1px solid #AAA; text-align:center}\n\n/* Source */\n.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;}\n.mceActionPanel {margin-top:5px;}\n\n/* Tabs classes */\n.tabs {width:100%; height:26px; line-height:normal; }\n.tabs ul {margin:0; padding:0; list-style:none;}\n.tabs li {float:left; margin:0 2px 0 0; line-height:25px; height:26px; display:block;\n-moz-border-radius-topleft: 3px;\n-moz-border-radius-topright: 3px;\n-webkit-border-top-left-radius: 3px;\n-webkit-border-top-right-radius: 3px;\n\n/* hope IE support border radius, God save me! */\nborder-bottom-top-radius: 3px;\nborder-bottom-top-radius: 3px;}\n.tabs li.current {background:#f7fbe9 url(../../../../../../images/btn.png) top repeat-x;}\n.tabs span {float:left; display:block; padding:0px 9pt;}\n.tabs .current span {}\n.tabs a {text-decoration:none; font-size:13px; font-weight:bold;}\n.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;}\n\n/* Panels */\n.panel_wrapper div.panel {display:none;}\n.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;}\n.panel_wrapper {padding:9pt; padding-top:5px; clear:both; background:#f7fbe9;}\n\n/* Columns */\n.column {float:left;}\n.properties {width:100%;}\n.properties .column1 {}\n.properties .column2 {text-align:left;}\n\n/* Titles */\nh1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;}\nh3 {font-size:14px;}\n.title {font-size:12px; font-weight:bold; color:#BD6800;}\n\n/* Dialog specific */\n#link .panel_wrapper, #link div.current {height:90px;}\n#image .panel_wrapper, #image div.current {height:220px;}\n#plugintable thead {font-weight:bold; background:#DDD;}\n#plugintable, #about #plugintable td {border:1px solid #919B9C;}\n#plugintable {width:96%; margin-top:9pt;}\n#pluginscontainer {height:290px; overflow:auto;}\n#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;}\n#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}\n#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}\n#colorpicker #light div {overflow:hidden;}\n#colorpicker #previewblock {float:right; padding-left:9pt; height:20px;}\n#colorpicker .panel_wrapper div.current {height:190px;}\n#colorpicker td {padding:0;}\n#colorpicker #namedcolors {width:150px;}\n#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}\n#colorpicker #colornamecontainer {margin-top:5px;}\n#colorpicker #picker_panel fieldset {margin:auto;width:325px;}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/skins/typecho/ui.css",
    "content": "/* Reset */\n.typechoSkin table, .typechoSkin tbody, .typechoSkin a, .typechoSkin img, .typechoSkin tr, .typechoSkin div, .typechoSkin td, .typechoSkin iframe, .typechoSkin span, .typechoSkin *, .typechoSkin .mceText {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000; vertical-align:baseline; width:auto; border-collapse:separate; text-align:left}\n.typechoSkin a:hover, .typechoSkin a:link, .typechoSkin a:visited, .typechoSkin a:active {text-decoration:none; font-weight:normal; cursor:default; color:#000}\n.typechoSkin table td {vertical-align:middle}\n\n/* Containers */\n.typechoSkin table {background:#D3DBB3}\n.typechoSkin iframe {display:block; background:#FFF}\n.typechoSkin .mceToolbar {height:26px}\n.typechoSkin .mceLeft {text-align:left}\n.typechoSkin .mceRight {text-align:right}\n\n/* External */\n.typechoSkin .mceExternalToolbar {position:absolute; border:1px solid #CCC; border-bottom:0; display:none;}\n.typechoSkin .mceExternalToolbar td.mceToolbar {padding-right:13px;}\n.typechoSkin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../../img/icons.gif) -820px 0}\n\n/* Layout */\n.typechoSkin table.mceLayout {border:0; border-left:1px solid #C1CD94; border-right:1px solid #C1CD94}\n.typechoSkin table.mceLayout tr.mceFirst td {border-top:1px solid #C1CD94}\n.typechoSkin table.mceLayout tr.mceLast td {border-bottom:1px solid #C1CD94}\n.typechoSkin table.mceToolbar, .typechoSkin tr.mceFirst .mceToolbar tr td, .typechoSkin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding: 2px 0;}\n.typechoSkin td.mceToolbar {padding-top:1px; vertical-align:top}\n.typechoSkin .mceIframeContainer {border-top:1px solid #C1CD94; border-bottom:1px solid #C1CD94}\n.typechoSkin .mceStatusbar {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; display:block; height:20px}\n.typechoSkin .mceStatusbar div {float:left; margin:2px}\n.typechoSkin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize}\n.typechoSkin .mceStatusbar a:hover {text-decoration:underline}\n.typechoSkin table.mceToolbar {margin-left:7px}\n.typechoSkin span.mceIcon, .typechoSkin img.mceIcon {display:block; width:20px; height:20px}\n.typechoSkin .mceIcon {background:url(../../img/icons.gif) no-repeat 20px 20px}\n.typechoSkin td.mceCenter {text-align:center;}\n.typechoSkin td.mceCenter table {margin:0 auto; text-align:left;}\n.typechoSkin td.mceRight table {margin:0 0 0 auto;}\n\n/* Button */\n.typechoSkin .mceButton {display:block; border:1px solid #AFBA7C; width:20px; height:20px; margin-right:1px; padding: 2px 3px;\nbackground: #fff url(./img/sprite.gif) top repeat-x;\n-moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -moz-border-radius-bottomleft: 3px; -moz-border-radius-bottomright: 3px;\n-webkit-border-top-left-radius: 3px; -webkit-border-top-right-radius: 3px; -webkit-border-bottom-left-radius: 3px; -webkit-border-bottom-right-radius: 3px;\n/* hope IE support border radius, God save me! */\nborder-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px;}\n.typechoSkin a.mceButtonEnabled:hover {border:1px solid #545c30; background: #fff url(./img/sprite.gif) bottom repeat-x; }\n.typechoSkin a.mceButtonActive, .typechoSkin a.mceButtonSelected {border:1px solid #545c30; background: #fff url(./img/sprite.gif) bottom repeat-x; }\n.typechoSkin .mceButtonDisabled .mceIcon {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\n.typechoSkin .mceButtonLabeled {width:auto}\n.typechoSkin .mceButtonLabeled span.mceIcon {float:left}\n.typechoSkin span.mceButtonLabel {display:block; font-size:10px; padding:4px 6px 0 22px; font-family:Tahoma,Verdana,Arial,Helvetica}\n.typechoSkin .mceButtonDisabled .mceButtonLabel {color:#888}\n\n/* Separator */\n.typechoSkin .mceSeparator {display:block; width:2px; height:20px; margin:2px 2px 0 4px}\n\n/* ListBox */\n.typechoSkin .mceListBox {direction:ltr}\n.typechoSkin .mceListBox, .typechoSkin .mceListBox a {display:block}\n.typechoSkin .mceListBox .mceText {padding-left:4px; width:70px; text-align:left; border:1px solid #CCC; border-right:0; background:#FFF; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden}\n.typechoSkin .mceListBox .mceOpen {width:9px; height:20px; background:url(../../img/icons.gif) -741px 0; margin-right:2px; border:1px solid #CCC;}\n.typechoSkin table.mceListBoxEnabled:hover .mceText, .typechoSkin .mceListBoxHover .mceText, .typechoSkin .mceListBoxSelected .mceText {border:1px solid #A2ABC0; border-right:0; background:#FFF}\n.typechoSkin table.mceListBoxEnabled:hover .mceOpen, .typechoSkin .mceListBoxHover .mceOpen, .typechoSkin .mceListBoxSelected .mceOpen {background-color:#FFF; border:1px solid #A2ABC0}\n.typechoSkin .mceListBoxDisabled a.mceText {color:gray; background-color:transparent;}\n.typechoSkin .mceListBoxMenu {overflow:auto; overflow-x:hidden}\n.typechoSkin .mceOldBoxModel .mceListBox .mceText {height:22px}\n.typechoSkin .mceOldBoxModel .mceListBox .mceOpen {width:11px; height:22px;}\n.typechoSkin select.mceNativeListBox {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:7pt; background:#F0F0EE; border:1px solid gray; margin-right:2px;}\n\n/* SplitButton */\n.typechoSkin .mceSplitButton {width:32px; height:20px; direction:ltr}\n.typechoSkin .mceSplitButton a, .typechoSkin .mceSplitButton span {height:20px; display:block}\n.typechoSkin .mceSplitButton a.mceAction {width:20px; border:1px solid #999; border-right:0; padding: 2px 3px; \nbackground: #fff url(./img/sprite.gif) top repeat-x;\n-moz-border-radius-topleft: 3px; -moz-border-radius-bottomleft: 3px;\n-webkit-border-top-left-radius: 3px; -webkit-border-bottom-left-radius: 3px;\n/* hope IE support border radius, God save me! */\nborder-top-left-radius: 3px; border-bottom-left-radius: 3px;}\n.typechoSkin .mceSplitButton span.mceAction {width:20px; background:url(../../img/icons.gif) 20px 20px;}\n.typechoSkin .mceSplitButton a.mceOpen {width:9px; background: #fff url(./img/sprite.gif) top repeat-x; border:1px solid #999; padding: 2px 1px; margin-right: 1px;\n-moz-border-radius-topright: 3px; -moz-border-radius-bottomright: 3px;\n-webkit-border-top-right-radius: 3px; -webkit-border-bottom-right-radius: 3px;\n/* hope IE support border radius, God save me! */\nborder-top-right-radius: 3px; border-bottom-right-radius: 3px;}\n.typechoSkin .mceSplitButton span.mceOpen {background:url(../../img/icons.gif) -741px 0;}\n.typechoSkin table.mceSplitButtonEnabled:hover a.mceAction, .typechoSkin .mceSplitButtonHover a.mceAction, .typechoSkin .mceSplitButtonSelected a.mceAction {border:1px solid #555; border-right:0; background: #fff url(./img/sprite.gif) bottom repeat-x;}\n.typechoSkin table.mceSplitButtonEnabled:hover a.mceOpen, .typechoSkin .mceSplitButtonHover a.mceOpen, .typechoSkin .mceSplitButtonSelected a.mceOpen {background: #fff url(./img/sprite.gif) bottom repeat-x; border:1px solid #555;}\n.typechoSkin .mceSplitButtonDisabled .mceAction, .typechoSkin .mceSplitButtonDisabled a.mceOpen {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\n.typechoSkin .mceSplitButtonActive a.mceAction {border:1px solid #0A246A; background-color:#C2CBE0}\n.typechoSkin .mceSplitButtonActive a.mceOpen {border-left:0;}\n\n/* ColorSplitButton */\n.typechoSkin div.mceColorSplitMenu table {background:#FFF; border:1px solid gray}\n.typechoSkin .mceColorSplitMenu td {padding:2px}\n.typechoSkin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden; border:1px solid #808080}\n.typechoSkin .mceColorSplitMenu td.mceMoreColors {padding:1px 3px 1px 1px}\n.typechoSkin .mceColorSplitMenu a.mceMoreColors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px; border:1px solid #FFF}\n.typechoSkin .mceColorSplitMenu a.mceMoreColors:hover {border:1px solid #0A246A; background-color:#B6BDD2}\n.typechoSkin a.mceMoreColors:hover {border:1px solid #0A246A}\n.typechoSkin .mceColorPreview {margin-left:2px; width:16px; height:4px; overflow:hidden; background:#9a9b9a}\n.typechoSkin .mce_forecolor span.mceAction, .typechoSkin .mce_backcolor span.mceAction {overflow:hidden; height:16px}\n\n/* Menu */\n.typechoSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #D4D0C8}\n.typechoSkin .mceNoIcons span.mceIcon {width:0;}\n.typechoSkin .mceNoIcons a .mceText {padding-left:10px}\n.typechoSkin .mceMenu table {background:#FFF}\n.typechoSkin .mceMenu a, .typechoSkin .mceMenu span, .typechoSkin .mceMenu {display:block}\n.typechoSkin .mceMenu td {height:20px}\n.typechoSkin .mceMenu a {position:relative;padding:3px 0 4px 0}\n.typechoSkin .mceMenu .mceText {position:relative; display:block; font-family:Tahoma,Verdana,Arial,Helvetica; color:#000; cursor:default; margin:0; padding:0 25px 0 25px; display:block}\n.typechoSkin .mceMenu span.mceText, .typechoSkin .mceMenu .mcePreview {font-size:11px}\n.typechoSkin .mceMenu pre.mceText {font-family:Monospace}\n.typechoSkin .mceMenu .mceIcon {position:absolute; top:0; left:0; width:22px;}\n.typechoSkin .mceMenu .mceMenuItemEnabled a:hover, .typechoSkin .mceMenu .mceMenuItemActive {background-color:#dbecf3}\n.typechoSkin td.mceMenuItemSeparator {background:#DDD; height:1px}\n.typechoSkin .mceMenuItemTitle a {border:0; background:#EEE; border-bottom:1px solid #DDD}\n.typechoSkin .mceMenuItemTitle span.mceText {color:#000; font-weight:bold; padding-left:4px}\n.typechoSkin .mceMenuItemDisabled .mceText {color:#888}\n.typechoSkin .mceMenuItemSelected .mceIcon {background:url(img/menu_check.gif)}\n.typechoSkin .mceNoIcons .mceMenuItemSelected a {background:url(img/menu_arrow.gif) no-repeat -6px center}\n.typechoSkin .mceMenu span.mceMenuLine {display:none}\n.typechoSkin .mceMenuItemSub a {background:url(img/menu_arrow.gif) no-repeat top right;}\n\n/* Progress,Resize */\n.typechoSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50); background:#FFF}\n.typechoSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}\n.typechoSkin .mcePlaceHolder {border:1px dotted gray}\n\n/* Formats */\n.typechoSkin .mce_formatPreview a {font-size:10px}\n.typechoSkin .mce_p span.mceText {}\n.typechoSkin .mce_address span.mceText {font-style:italic}\n.typechoSkin .mce_pre span.mceText {font-family:monospace}\n.typechoSkin .mce_h1 span.mceText {font-weight:bolder; font-size: 2em}\n.typechoSkin .mce_h2 span.mceText {font-weight:bolder; font-size: 1.5em}\n.typechoSkin .mce_h3 span.mceText {font-weight:bolder; font-size: 1.17em}\n.typechoSkin .mce_h4 span.mceText {font-weight:bolder; font-size: 1em}\n.typechoSkin .mce_h5 span.mceText {font-weight:bolder; font-size: .83em}\n.typechoSkin .mce_h6 span.mceText {font-weight:bolder; font-size: .75em}\n\n/* Theme */\n.typechoSkin span.mce_bold {background-position:0 0}\n.typechoSkin span.mce_italic {background-position:-60px 0}\n.typechoSkin span.mce_underline {background-position:-140px 0}\n.typechoSkin span.mce_strikethrough {background-position:-120px 0}\n.typechoSkin span.mce_undo {background-position:-160px 0}\n.typechoSkin span.mce_redo {background-position:-100px 0}\n.typechoSkin span.mce_cleanup {background-position:-40px 0}\n.typechoSkin span.mce_bullist {background-position:-20px 0}\n.typechoSkin span.mce_numlist {background-position:-80px 0}\n.typechoSkin span.mce_justifyleft {background-position:-460px 0}\n.typechoSkin span.mce_justifyright {background-position:-480px 0}\n.typechoSkin span.mce_justifycenter {background-position:-420px 0}\n.typechoSkin span.mce_justifyfull {background-position:-440px 0}\n.typechoSkin span.mce_anchor {background-position:-200px 0}\n.typechoSkin span.mce_indent {background-position:-400px 0}\n.typechoSkin span.mce_outdent {background-position:-540px 0}\n.typechoSkin span.mce_link {background-position:-500px 0}\n.typechoSkin span.mce_unlink {background-position:-640px 0}\n.typechoSkin span.mce_sub {background-position:-600px 0}\n.typechoSkin span.mce_sup {background-position:-620px 0}\n.typechoSkin span.mce_removeformat {background-position:-580px 0}\n.typechoSkin span.mce_newdocument {background-position:-520px 0}\n.typechoSkin span.mce_image {background-position:-380px 0}\n.typechoSkin span.mce_help {background-position:-340px 0}\n.typechoSkin span.mce_code {background-position:-260px 0}\n.typechoSkin span.mce_hr {background-position:-360px 0}\n.typechoSkin span.mce_visualaid {background-position:-660px 0}\n.typechoSkin span.mce_charmap {background-position:-240px 0}\n.typechoSkin span.mce_paste {background-position:-560px 0}\n.typechoSkin span.mce_copy {background-position:-700px 0}\n.typechoSkin span.mce_cut {background-position:-680px 0}\n.typechoSkin span.mce_blockquote {background-position:-220px 0}\n.typechoSkin .mce_forecolor span.mceAction {background-position:-720px 0}\n.typechoSkin .mce_backcolor span.mceAction {background-position:-760px 0}\n.typechoSkin span.mce_forecolorpicker {background-position:-720px 0}\n.typechoSkin span.mce_backcolorpicker {background-position:-760px 0}\n\n/* Plugins */\n.typechoSkin span.mce_advhr {background-position:-0px -20px}\n.typechoSkin span.mce_ltr {background-position:-20px -20px}\n.typechoSkin span.mce_rtl {background-position:-40px -20px}\n.typechoSkin span.mce_emotions {background-position:-60px -20px}\n.typechoSkin span.mce_fullpage {background-position:-80px -20px}\n.typechoSkin span.mce_fullscreen {background-position:-100px -20px}\n.typechoSkin span.mce_iespell {background-position:-120px -20px}\n.typechoSkin span.mce_insertdate {background-position:-140px -20px}\n.typechoSkin span.mce_inserttime {background-position:-160px -20px}\n.typechoSkin span.mce_absolute {background-position:-180px -20px}\n.typechoSkin span.mce_backward {background-position:-200px -20px}\n.typechoSkin span.mce_forward {background-position:-220px -20px}\n.typechoSkin span.mce_insert_layer {background-position:-240px -20px}\n.typechoSkin span.mce_insertlayer {background-position:-260px -20px}\n.typechoSkin span.mce_movebackward {background-position:-280px -20px}\n.typechoSkin span.mce_moveforward {background-position:-300px -20px}\n.typechoSkin span.mce_media {background-position:-320px -20px}\n.typechoSkin span.mce_nonbreaking {background-position:-340px -20px}\n.typechoSkin span.mce_pastetext {background-position:-360px -20px}\n.typechoSkin span.mce_pasteword {background-position:-380px -20px}\n.typechoSkin span.mce_selectall {background-position:-400px -20px}\n.typechoSkin span.mce_preview {background-position:-420px -20px}\n.typechoSkin span.mce_print {background-position:-440px -20px}\n.typechoSkin span.mce_cancel {background-position:-460px -20px}\n.typechoSkin span.mce_save {background-position:-480px -20px}\n.typechoSkin span.mce_replace {background-position:-500px -20px}\n.typechoSkin span.mce_search {background-position:-520px -20px}\n.typechoSkin span.mce_styleprops {background-position:-560px -20px}\n.typechoSkin span.mce_table {background-position:-580px -20px}\n.typechoSkin span.mce_cell_props {background-position:-600px -20px}\n.typechoSkin span.mce_delete_table {background-position:-620px -20px}\n.typechoSkin span.mce_delete_col {background-position:-640px -20px}\n.typechoSkin span.mce_delete_row {background-position:-660px -20px}\n.typechoSkin span.mce_col_after {background-position:-680px -20px}\n.typechoSkin span.mce_col_before {background-position:-700px -20px}\n.typechoSkin span.mce_row_after {background-position:-720px -20px}\n.typechoSkin span.mce_row_before {background-position:-740px -20px}\n.typechoSkin span.mce_merge_cells {background-position:-760px -20px}\n.typechoSkin span.mce_table_props {background-position:-980px -20px}\n.typechoSkin span.mce_row_props {background-position:-780px -20px}\n.typechoSkin span.mce_split_cells {background-position:-800px -20px}\n.typechoSkin span.mce_template {background-position:-820px -20px}\n.typechoSkin span.mce_visualchars {background-position:-840px -20px}\n.typechoSkin span.mce_abbr {background-position:-860px -20px}\n.typechoSkin span.mce_acronym {background-position:-880px -20px}\n.typechoSkin span.mce_attribs {background-position:-900px -20px}\n.typechoSkin span.mce_cite {background-position:-920px -20px}\n.typechoSkin span.mce_del {background-position:-940px -20px}\n.typechoSkin span.mce_ins {background-position:-960px -20px}\n.typechoSkin span.mce_morebreak {background-position:0 -40px}\n.typechoSkin .mce_spellchecker span.mceAction {background-position:-540px -20px}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/themes/advanced/source_editor.htm",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n\t<title>{#advanced_dlg.code_title}</title>\n\t<script type=\"text/javascript\" src=\"../../tiny_mce_popup.js\"></script>\n\t<script type=\"text/javascript\" src=\"js/source_editor.js\"></script>\n</head>\n<body onresize=\"resizeInputs();\" style=\"display:none; overflow:hidden;\">\n\t<form name=\"source\" onsubmit=\"saveContent();return false;\" action=\"#\">\n\t\t<div style=\"float: left\" class=\"title\">{#advanced_dlg.code_title}</div>\n\n\t\t<div id=\"wrapline\" style=\"float: right\">\n\t\t\t<input type=\"checkbox\" name=\"wraped\" id=\"wraped\" onclick=\"toggleWordWrap(this);\" class=\"wordWrapCode\" /><label for=\"wraped\">{#advanced_dlg.code_wordwrap}</label>\n\t\t</div>\n\n\t\t<br style=\"clear: both\" />\n\n\t\t<textarea name=\"htmlSource\" id=\"htmlSource\" rows=\"15\" cols=\"100\" style=\"width: 100%; height: 100%; font-family: 'Courier New',Courier,monospace; font-size: 12px;\" dir=\"ltr\" wrap=\"off\" class=\"mceFocus\"></textarea>\n\n\t\t<div class=\"mceActionPanel\">\n\t\t\t<div style=\"float: left\">\n\t\t\t\t<input type=\"submit\" name=\"insert\" value=\"{#update}\" id=\"insert\" />\n\t\t\t</div>\n\n\t\t\t<div style=\"float: right\">\n\t\t\t\t<input type=\"button\" name=\"cancel\" value=\"{#cancel}\" onclick=\"tinyMCEPopup.close();\" id=\"cancel\" />\n\t\t\t</div>\n\t\t</div>\n\t</form>\n</body>\n</html>\n"
  },
  {
    "path": "TinyMCE/tiny_mce/tiny_mce.js",
    "content": "var tinymce={majorVersion:\"3\",minorVersion:\"2.7\",releaseDate:\"2009-09-22\",_init:function(){var o=this,k=document,l=window,j=navigator,b=j.userAgent,h,a,g,f,e,m;o.isOpera=l.opera&&opera.buildNumber;o.isWebKit=/WebKit/.test(b);o.isIE=!o.isWebKit&&!o.isOpera&&(/MSIE/gi).test(b)&&(/Explorer/gi).test(j.appName);o.isIE6=o.isIE&&/MSIE [56]/.test(b);o.isGecko=!o.isWebKit&&/Gecko/.test(b);o.isMac=b.indexOf(\"Mac\")!=-1;o.isAir=/adobeair/i.test(b);if(l.tinyMCEPreInit){o.suffix=tinyMCEPreInit.suffix;o.baseURL=tinyMCEPreInit.base;o.query=tinyMCEPreInit.query;return}o.suffix=\"\";a=k.getElementsByTagName(\"base\");for(h=0;h<a.length;h++){if(m=a[h].href){if(/^https?:\\/\\/[^\\/]+$/.test(m)){m+=\"/\"}f=m?m.match(/.*\\//)[0]:\"\"}}function c(d){if(d.src&&/tiny_mce(|_gzip|_jquery|_prototype)(_dev|_src)?.js/.test(d.src)){if(/_(src|dev)\\.js/g.test(d.src)){o.suffix=\"_src\"}if((e=d.src.indexOf(\"?\"))!=-1){o.query=d.src.substring(e+1)}o.baseURL=d.src.substring(0,d.src.lastIndexOf(\"/\"));if(f&&o.baseURL.indexOf(\"://\")==-1&&o.baseURL.indexOf(\"/\")!==0){o.baseURL=f+o.baseURL}return o.baseURL}return null}a=k.getElementsByTagName(\"script\");for(h=0;h<a.length;h++){if(c(a[h])){return}}g=k.getElementsByTagName(\"head\")[0];if(g){a=g.getElementsByTagName(\"script\");for(h=0;h<a.length;h++){if(c(a[h])){return}}}return},is:function(b,a){var c=typeof(b);if(!a){return c!=\"undefined\"}if(a==\"array\"&&(b.hasOwnProperty&&b instanceof Array)){return true}return c==a},each:function(d,a,c){var e,b;if(!d){return 0}c=c||d;if(typeof(d.length)!=\"undefined\"){for(e=0,b=d.length;e<b;e++){if(a.call(c,d[e],e,d)===false){return 0}}}else{for(e in d){if(d.hasOwnProperty(e)){if(a.call(c,d[e],e,d)===false){return 0}}}}return 1},map:function(b,c){var d=[];tinymce.each(b,function(a){d.push(c(a))});return d},grep:function(b,c){var d=[];tinymce.each(b,function(a){if(!c||c(a)){d.push(a)}});return d},inArray:function(c,d){var e,b;if(c){for(e=0,b=c.length;e<b;e++){if(c[e]===d){return e}}}return -1},extend:function(f,d){var c,b=arguments;for(c=1;c<b.length;c++){d=b[c];tinymce.each(d,function(a,e){if(typeof(a)!==\"undefined\"){f[e]=a}})}return f},trim:function(a){return(a?\"\"+a:\"\").replace(/^\\s*|\\s*$/g,\"\")},create:function(j,a){var i=this,b,e,f,g,d,h=0;j=/^((static) )?([\\w.]+)(:([\\w.]+))?/.exec(j);f=j[3].match(/(^|\\.)(\\w+)$/i)[2];e=i.createNS(j[3].replace(/\\.\\w+$/,\"\"));if(e[f]){return}if(j[2]==\"static\"){e[f]=a;if(this.onCreate){this.onCreate(j[2],j[3],e[f])}return}if(!a[f]){a[f]=function(){};h=1}e[f]=a[f];i.extend(e[f].prototype,a);if(j[5]){b=i.resolve(j[5]).prototype;g=j[5].match(/\\.(\\w+)$/i)[1];d=e[f];if(h){e[f]=function(){return b[g].apply(this,arguments)}}else{e[f]=function(){this.parent=b[g];return d.apply(this,arguments)}}e[f].prototype[f]=e[f];i.each(b,function(c,k){e[f].prototype[k]=b[k]});i.each(a,function(c,k){if(b[k]){e[f].prototype[k]=function(){this.parent=b[k];return c.apply(this,arguments)}}else{if(k!=f){e[f].prototype[k]=c}}})}i.each(a[\"static\"],function(c,k){e[f][k]=c});if(this.onCreate){this.onCreate(j[2],j[3],e[f].prototype)}},walk:function(c,b,d,a){a=a||this;if(c){if(d){c=c[d]}tinymce.each(c,function(f,e){if(b.call(a,f,e,d)===false){return false}tinymce.walk(f,b,d,a)})}},createNS:function(d,c){var b,a;c=c||window;d=d.split(\".\");for(b=0;b<d.length;b++){a=d[b];if(!c[a]){c[a]={}}c=c[a]}return c},resolve:function(d,c){var b,a;c=c||window;d=d.split(\".\");for(b=0,a=d.length;b<a;b++){c=c[d[b]];if(!c){break}}return c},addUnload:function(e,d){var c=this,a=window;e={func:e,scope:d||this};if(!c.unloads){function b(){var f=c.unloads,h,i;if(f){for(i in f){h=f[i];if(h&&h.func){h.func.call(h.scope,1)}}if(a.detachEvent){a.detachEvent(\"onbeforeunload\",g);a.detachEvent(\"onunload\",b)}else{if(a.removeEventListener){a.removeEventListener(\"unload\",b,false)}}c.unloads=h=f=a=b=0;if(window.CollectGarbage){window.CollectGarbage()}}}function g(){var h=document;if(h.readyState==\"interactive\"){function f(){h.detachEvent(\"onstop\",f);if(b){b()}h=0}if(h){h.attachEvent(\"onstop\",f)}window.setTimeout(function(){if(h){h.detachEvent(\"onstop\",f)}},0)}}if(a.attachEvent){a.attachEvent(\"onunload\",b);a.attachEvent(\"onbeforeunload\",g)}else{if(a.addEventListener){a.addEventListener(\"unload\",b,false)}}c.unloads=[e]}else{c.unloads.push(e)}return e},removeUnload:function(c){var a=this.unloads,b=null;tinymce.each(a,function(e,d){if(e&&e.func==c){a.splice(d,1);b=c;return false}});return b},explode:function(a,b){return a?tinymce.map(a.split(b||\",\"),tinymce.trim):a},_addVer:function(b){var a;if(!this.query){return b}a=(b.indexOf(\"?\")==-1?\"?\":\"&\")+this.query;if(b.indexOf(\"#\")==-1){return b+a}return b.replace(\"#\",a+\"#\")}};window.tinymce=tinymce;tinymce._init();tinymce.create(\"tinymce.util.Dispatcher\",{scope:null,listeners:null,Dispatcher:function(a){this.scope=a||this;this.listeners=[]},add:function(a,b){this.listeners.push({cb:a,scope:b||this.scope});return a},addToTop:function(a,b){this.listeners.unshift({cb:a,scope:b||this.scope});return a},remove:function(a){var b=this.listeners,c=null;tinymce.each(b,function(e,d){if(a==e.cb){c=a;b.splice(d,1);return false}});return c},dispatch:function(){var f,d=arguments,e,b=this.listeners,g;for(e=0;e<b.length;e++){g=b[e];f=g.cb.apply(g.scope,d);if(f===false){break}}return f}});(function(){var a=tinymce.each;tinymce.create(\"tinymce.util.URI\",{URI:function(e,g){var f=this,h,d,c;e=tinymce.trim(e);g=f.settings=g||{};if(/^(mailto|tel|news|javascript|about|data):/i.test(e)||/^\\s*#/.test(e)){f.source=e;return}if(e.indexOf(\"/\")===0&&e.indexOf(\"//\")!==0){e=(g.base_uri?g.base_uri.protocol||\"http\":\"http\")+\"://mce_host\"+e}if(!/^\\w*:?\\/\\//.test(e)){e=(g.base_uri.protocol||\"http\")+\"://mce_host\"+f.toAbsPath(g.base_uri.path,e)}e=e.replace(/@@/g,\"(mce_at)\");e=/^(?:(?![^:@]+:[^:@\\/]*@)([^:\\/?#.]+):)?(?:\\/\\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/.exec(e);a([\"source\",\"protocol\",\"authority\",\"userInfo\",\"user\",\"password\",\"host\",\"port\",\"relative\",\"path\",\"directory\",\"file\",\"query\",\"anchor\"],function(b,j){var k=e[j];if(k){k=k.replace(/\\(mce_at\\)/g,\"@@\")}f[b]=k});if(c=g.base_uri){if(!f.protocol){f.protocol=c.protocol}if(!f.userInfo){f.userInfo=c.userInfo}if(!f.port&&f.host==\"mce_host\"){f.port=c.port}if(!f.host||f.host==\"mce_host\"){f.host=c.host}f.source=\"\"}},setPath:function(c){var b=this;c=/^(.*?)\\/?(\\w+)?$/.exec(c);b.path=c[0];b.directory=c[1];b.file=c[2];b.source=\"\";b.getURI()},toRelative:function(b){var c=this,d;if(b===\"./\"){return b}b=new tinymce.util.URI(b,{base_uri:c});if((b.host!=\"mce_host\"&&c.host!=b.host&&b.host)||c.port!=b.port||c.protocol!=b.protocol){return b.getURI()}d=c.toRelPath(c.path,b.path);if(b.query){d+=\"?\"+b.query}if(b.anchor){d+=\"#\"+b.anchor}return d},toAbsolute:function(b,c){var b=new tinymce.util.URI(b,{base_uri:this});return b.getURI(this.host==b.host&&this.protocol==b.protocol?c:0)},toRelPath:function(g,h){var c,f=0,d=\"\",e,b;g=g.substring(0,g.lastIndexOf(\"/\"));g=g.split(\"/\");c=h.split(\"/\");if(g.length>=c.length){for(e=0,b=g.length;e<b;e++){if(e>=c.length||g[e]!=c[e]){f=e+1;break}}}if(g.length<c.length){for(e=0,b=c.length;e<b;e++){if(e>=g.length||g[e]!=c[e]){f=e+1;break}}}if(f==1){return h}for(e=0,b=g.length-(f-1);e<b;e++){d+=\"../\"}for(e=f-1,b=c.length;e<b;e++){if(e!=f-1){d+=\"/\"+c[e]}else{d+=c[e]}}return d},toAbsPath:function(e,f){var c,b=0,h=[],d,g;d=/\\/$/.test(f)?\"/\":\"\";e=e.split(\"/\");f=f.split(\"/\");a(e,function(i){if(i){h.push(i)}});e=h;for(c=f.length-1,h=[];c>=0;c--){if(f[c].length==0||f[c]==\".\"){continue}if(f[c]==\"..\"){b++;continue}if(b>0){b--;continue}h.push(f[c])}c=e.length-b;if(c<=0){g=h.reverse().join(\"/\")}else{g=e.slice(0,c).join(\"/\")+\"/\"+h.reverse().join(\"/\")}if(g.indexOf(\"/\")!==0){g=\"/\"+g}if(d&&g.lastIndexOf(\"/\")!==g.length-1){g+=d}return g},getURI:function(d){var c,b=this;if(!b.source||d){c=\"\";if(!d){if(b.protocol){c+=b.protocol+\"://\"}if(b.userInfo){c+=b.userInfo+\"@\"}if(b.host){c+=b.host}if(b.port){c+=\":\"+b.port}}if(b.path){c+=b.path}if(b.query){c+=\"?\"+b.query}if(b.anchor){c+=\"#\"+b.anchor}b.source=c}return b.source}})})();(function(){var a=tinymce.each;tinymce.create(\"static tinymce.util.Cookie\",{getHash:function(d){var b=this.get(d),c;if(b){a(b.split(\"&\"),function(e){e=e.split(\"=\");c=c||{};c[unescape(e[0])]=unescape(e[1])})}return c},setHash:function(j,b,g,f,i,c){var h=\"\";a(b,function(e,d){h+=(!h?\"\":\"&\")+escape(d)+\"=\"+escape(e)});this.set(j,h,g,f,i,c)},get:function(i){var h=document.cookie,g,f=i+\"=\",d;if(!h){return}d=h.indexOf(\"; \"+f);if(d==-1){d=h.indexOf(f);if(d!=0){return null}}else{d+=2}g=h.indexOf(\";\",d);if(g==-1){g=h.length}return unescape(h.substring(d+f.length,g))},set:function(i,b,g,f,h,c){document.cookie=i+\"=\"+escape(b)+((g)?\"; expires=\"+g.toGMTString():\"\")+((f)?\"; path=\"+escape(f):\"\")+((h)?\"; domain=\"+h:\"\")+((c)?\"; secure\":\"\")},remove:function(e,b){var c=new Date();c.setTime(c.getTime()-1000);this.set(e,\"\",c,b,c)}})})();tinymce.create(\"static tinymce.util.JSON\",{serialize:function(e){var c,a,d=tinymce.util.JSON.serialize,b;if(e==null){return\"null\"}b=typeof e;if(b==\"string\"){a=\"\\bb\\tt\\nn\\ff\\rr\\\"\\\"''\\\\\\\\\";return'\"'+e.replace(/([\\u0080-\\uFFFF\\x00-\\x1f\\\"])/g,function(g,f){c=a.indexOf(f);if(c+1){return\"\\\\\"+a.charAt(c+1)}g=f.charCodeAt().toString(16);return\"\\\\u\"+\"0000\".substring(g.length)+g})+'\"'}if(b==\"object\"){if(e.hasOwnProperty&&e instanceof Array){for(c=0,a=\"[\";c<e.length;c++){a+=(c>0?\",\":\"\")+d(e[c])}return a+\"]\"}a=\"{\";for(c in e){a+=typeof e[c]!=\"function\"?(a.length>1?',\"':'\"')+c+'\":'+d(e[c]):\"\"}return a+\"}\"}return\"\"+e},parse:function(s){try{return eval(\"(\"+s+\")\")}catch(ex){}}});tinymce.create(\"static tinymce.util.XHR\",{send:function(g){var a,e,b=window,h=0;g.scope=g.scope||this;g.success_scope=g.success_scope||g.scope;g.error_scope=g.error_scope||g.scope;g.async=g.async===false?false:true;g.data=g.data||\"\";function d(i){a=0;try{a=new ActiveXObject(i)}catch(c){}return a}a=b.XMLHttpRequest?new XMLHttpRequest():d(\"Microsoft.XMLHTTP\")||d(\"Msxml2.XMLHTTP\");if(a){if(a.overrideMimeType){a.overrideMimeType(g.content_type)}a.open(g.type||(g.data?\"POST\":\"GET\"),g.url,g.async);if(g.content_type){a.setRequestHeader(\"Content-Type\",g.content_type)}a.setRequestHeader(\"X-Requested-With\",\"XMLHttpRequest\");a.send(g.data);function f(){if(!g.async||a.readyState==4||h++>10000){if(g.success&&h<10000&&a.status==200){g.success.call(g.success_scope,\"\"+a.responseText,a,g)}else{if(g.error){g.error.call(g.error_scope,h>10000?\"TIMED_OUT\":\"GENERAL\",a,g)}}a=null}else{b.setTimeout(f,10)}}if(!g.async){return f()}e=b.setTimeout(f,10)}}});(function(){var c=tinymce.extend,b=tinymce.util.JSON,a=tinymce.util.XHR;tinymce.create(\"tinymce.util.JSONRequest\",{JSONRequest:function(d){this.settings=c({},d);this.count=0},send:function(f){var e=f.error,d=f.success;f=c(this.settings,f);f.success=function(h,g){h=b.parse(h);if(typeof(h)==\"undefined\"){h={error:\"JSON Parse error.\"}}if(h.error){e.call(f.error_scope||f.scope,h.error,g)}else{d.call(f.success_scope||f.scope,h.result)}};f.error=function(h,g){e.call(f.error_scope||f.scope,h,g)};f.data=b.serialize({id:f.id||\"c\"+(this.count++),method:f.method,params:f.params});f.content_type=\"application/json\";a.send(f)},\"static\":{sendRPC:function(d){return new tinymce.util.JSONRequest().send(d)}}})}());(function(c){var e=c.each,b=c.is;var d=c.isWebKit,a=c.isIE;c.create(\"tinymce.dom.DOMUtils\",{doc:null,root:null,files:null,pixelStyles:/^(top|left|bottom|right|width|height|borderWidth)$/,props:{\"for\":\"htmlFor\",\"class\":\"className\",className:\"className\",checked:\"checked\",disabled:\"disabled\",maxlength:\"maxLength\",readonly:\"readOnly\",selected:\"selected\",value:\"value\",id:\"id\",name:\"name\",type:\"type\"},DOMUtils:function(i,g){var f=this;f.doc=i;f.win=window;f.files={};f.cssFlicker=false;f.counter=0;f.boxModel=!c.isIE||i.compatMode==\"CSS1Compat\";f.stdMode=i.documentMode===8;f.settings=g=c.extend({keep_values:false,hex_colors:1,process_html:1},g);if(c.isIE6){try{i.execCommand(\"BackgroundImageCache\",false,true)}catch(h){f.cssFlicker=true}}c.addUnload(f.destroy,f)},getRoot:function(){var f=this,g=f.settings;return(g&&f.get(g.root_element))||f.doc.body},getViewPort:function(g){var h,f;g=!g?this.win:g;h=g.document;f=this.boxModel?h.documentElement:h.body;return{x:g.pageXOffset||f.scrollLeft,y:g.pageYOffset||f.scrollTop,w:g.innerWidth||f.clientWidth,h:g.innerHeight||f.clientHeight}},getRect:function(i){var h,f=this,g;i=f.get(i);h=f.getPos(i);g=f.getSize(i);return{x:h.x,y:h.y,w:g.w,h:g.h}},getSize:function(j){var g=this,f,i;j=g.get(j);f=g.getStyle(j,\"width\");i=g.getStyle(j,\"height\");if(f.indexOf(\"px\")===-1){f=0}if(i.indexOf(\"px\")===-1){i=0}return{w:parseInt(f)||j.offsetWidth||j.clientWidth,h:parseInt(i)||j.offsetHeight||j.clientHeight}},getParent:function(i,h,g){return this.getParents(i,h,g,false)},getParents:function(p,k,i,m){var h=this,g,j=h.settings,l=[];p=h.get(p);m=m===undefined;if(j.strict_root){i=i||h.getRoot()}if(b(k,\"string\")){g=k;if(k===\"*\"){k=function(f){return f.nodeType==1}}else{k=function(f){return h.is(f,g)}}}while(p){if(p==i||!p.nodeType||p.nodeType===9){break}if(!k||k(p)){if(m){l.push(p)}else{return p}}p=p.parentNode}return m?l:null},get:function(f){var g;if(f&&this.doc&&typeof(f)==\"string\"){g=f;f=this.doc.getElementById(f);if(f&&f.id!==g){return this.doc.getElementsByName(g)[1]}}return f},getNext:function(g,f){return this._findSib(g,f,\"nextSibling\")},getPrev:function(g,f){return this._findSib(g,f,\"previousSibling\")},select:function(h,g){var f=this;return c.dom.Sizzle(h,f.get(g)||f.get(f.settings.root_element)||f.doc,[])},is:function(g,f){return c.dom.Sizzle.matches(f,g.nodeType?[g]:g).length>0},add:function(j,l,f,i,k){var g=this;return this.run(j,function(n){var m,h;m=b(l,\"string\")?g.doc.createElement(l):l;g.setAttribs(m,f);if(i){if(i.nodeType){m.appendChild(i)}else{g.setHTML(m,i)}}return !k?n.appendChild(m):m})},create:function(i,f,g){return this.add(this.doc.createElement(i),i,f,g,1)},createHTML:function(m,f,j){var l=\"\",i=this,g;l+=\"<\"+m;for(g in f){if(f.hasOwnProperty(g)){l+=\" \"+g+'=\"'+i.encode(f[g])+'\"'}}if(c.is(j)){return l+\">\"+j+\"</\"+m+\">\"}return l+\" />\"},remove:function(h,f){var g=this;return this.run(h,function(m){var l,k,j;l=m.parentNode;if(!l){return null}if(f){for(j=m.childNodes.length-1;j>=0;j--){g.insertAfter(m.childNodes[j],m)}}if(g.fixPsuedoLeaks){l=m.cloneNode(true);f=\"IELeakGarbageBin\";k=g.get(f)||g.add(g.doc.body,\"div\",{id:f,style:\"display:none\"});k.appendChild(m);k.innerHTML=\"\";return l}return l.removeChild(m)})},setStyle:function(i,f,g){var h=this;return h.run(i,function(l){var k,j;k=l.style;f=f.replace(/-(\\D)/g,function(n,m){return m.toUpperCase()});if(h.pixelStyles.test(f)&&(c.is(g,\"number\")||/^[\\-0-9\\.]+$/.test(g))){g+=\"px\"}switch(f){case\"opacity\":if(a){k.filter=g===\"\"?\"\":\"alpha(opacity=\"+(g*100)+\")\";if(!i.currentStyle||!i.currentStyle.hasLayout){k.display=\"inline-block\"}}k[f]=k[\"-moz-opacity\"]=k[\"-khtml-opacity\"]=g||\"\";break;case\"float\":a?k.styleFloat=g:k.cssFloat=g;break;default:k[f]=g||\"\"}if(h.settings.update_styles){h.setAttrib(l,\"mce_style\")}})},getStyle:function(i,f,h){i=this.get(i);if(!i){return false}if(this.doc.defaultView&&h){f=f.replace(/[A-Z]/g,function(j){return\"-\"+j});try{return this.doc.defaultView.getComputedStyle(i,null).getPropertyValue(f)}catch(g){return null}}f=f.replace(/-(\\D)/g,function(k,j){return j.toUpperCase()});if(f==\"float\"){f=a?\"styleFloat\":\"cssFloat\"}if(i.currentStyle&&h){return i.currentStyle[f]}return i.style[f]},setStyles:function(i,j){var g=this,h=g.settings,f;f=h.update_styles;h.update_styles=0;e(j,function(k,l){g.setStyle(i,l,k)});h.update_styles=f;if(h.update_styles){g.setAttrib(i,h.cssText)}},setAttrib:function(h,i,f){var g=this;if(!h||!i){return}if(g.settings.strict){i=i.toLowerCase()}return this.run(h,function(k){var j=g.settings;switch(i){case\"style\":if(!b(f,\"string\")){e(f,function(l,m){g.setStyle(k,m,l)});return}if(j.keep_values){if(f&&!g._isRes(f)){k.setAttribute(\"mce_style\",f,2)}else{k.removeAttribute(\"mce_style\",2)}}k.style.cssText=f;break;case\"class\":k.className=f||\"\";break;case\"src\":case\"href\":if(j.keep_values){if(j.url_converter){f=j.url_converter.call(j.url_converter_scope||g,f,i,k)}g.setAttrib(k,\"mce_\"+i,f,2)}break;case\"shape\":k.setAttribute(\"mce_style\",f);break}if(b(f)&&f!==null&&f.length!==0){k.setAttribute(i,\"\"+f,2)}else{k.removeAttribute(i,2)}})},setAttribs:function(g,h){var f=this;return this.run(g,function(i){e(h,function(j,k){f.setAttrib(i,k,j)})})},getAttrib:function(i,j,h){var f,g=this;i=g.get(i);if(!i||i.nodeType!==1){return false}if(!b(h)){h=\"\"}if(/^(src|href|style|coords|shape)$/.test(j)){f=i.getAttribute(\"mce_\"+j);if(f){return f}}if(a&&g.props[j]){f=i[g.props[j]];f=f&&f.nodeValue?f.nodeValue:f}if(!f){f=i.getAttribute(j,2)}if(/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(j)){if(i[g.props[j]]===true&&f===\"\"){return j}return f?j:\"\"}if(i.nodeName===\"FORM\"&&i.getAttributeNode(j)){return i.getAttributeNode(j).nodeValue}if(j===\"style\"){f=f||i.style.cssText;if(f){f=g.serializeStyle(g.parseStyle(f));if(g.settings.keep_values&&!g._isRes(f)){i.setAttribute(\"mce_style\",f)}}}if(d&&j===\"class\"&&f){f=f.replace(/(apple|webkit)\\-[a-z\\-]+/gi,\"\")}if(a){switch(j){case\"rowspan\":case\"colspan\":if(f===1){f=\"\"}break;case\"size\":if(f===\"+0\"||f===20||f===0){f=\"\"}break;case\"width\":case\"height\":case\"vspace\":case\"checked\":case\"disabled\":case\"readonly\":if(f===0){f=\"\"}break;case\"hspace\":if(f===-1){f=\"\"}break;case\"maxlength\":case\"tabindex\":if(f===32768||f===2147483647||f===\"32768\"){f=\"\"}break;case\"multiple\":case\"compact\":case\"noshade\":case\"nowrap\":if(f===65535){return j}return h;case\"shape\":f=f.toLowerCase();break;default:if(j.indexOf(\"on\")===0&&f){f=(\"\"+f).replace(/^function\\s+\\w+\\(\\)\\s+\\{\\s+(.*)\\s+\\}$/,\"$1\")}}}return(f!==undefined&&f!==null&&f!==\"\")?\"\"+f:h},getPos:function(m,i){var g=this,f=0,l=0,j,k=g.doc,h;m=g.get(m);i=i||k.body;if(m){if(a&&!g.stdMode){m=m.getBoundingClientRect();j=g.boxModel?k.documentElement:k.body;f=g.getStyle(g.select(\"html\")[0],\"borderWidth\");f=(f==\"medium\"||g.boxModel&&!g.isIE6)&&2||f;m.top+=g.win.self!=g.win.top?2:0;return{x:m.left+j.scrollLeft-f,y:m.top+j.scrollTop-f}}h=m;while(h&&h!=i&&h.nodeType){f+=h.offsetLeft||0;l+=h.offsetTop||0;h=h.offsetParent}h=m.parentNode;while(h&&h!=i&&h.nodeType){f-=h.scrollLeft||0;l-=h.scrollTop||0;h=h.parentNode}}return{x:f,y:l}},parseStyle:function(h){var i=this,j=i.settings,k={};if(!h){return k}function f(w,q,v){var o,u,m,n;o=k[w+\"-top\"+q];if(!o){return}u=k[w+\"-right\"+q];if(o!=u){return}m=k[w+\"-bottom\"+q];if(u!=m){return}n=k[w+\"-left\"+q];if(m!=n){return}k[v]=n;delete k[w+\"-top\"+q];delete k[w+\"-right\"+q];delete k[w+\"-bottom\"+q];delete k[w+\"-left\"+q]}function g(n,m,l,p){var o;o=k[m];if(!o){return}o=k[l];if(!o){return}o=k[p];if(!o){return}k[n]=k[m]+\" \"+k[l]+\" \"+k[p];delete k[m];delete k[l];delete k[p]}h=h.replace(/&(#?[a-z0-9]+);/g,\"&$1_MCE_SEMI_\");e(h.split(\";\"),function(m){var l,n=[];if(m){m=m.replace(/_MCE_SEMI_/g,\";\");m=m.replace(/url\\([^\\)]+\\)/g,function(o){n.push(o);return\"url(\"+n.length+\")\"});m=m.split(\":\");l=c.trim(m[1]);l=l.replace(/url\\(([^\\)]+)\\)/g,function(p,o){return n[parseInt(o)-1]});l=l.replace(/rgb\\([^\\)]+\\)/g,function(o){return i.toHex(o)});if(j.url_converter){l=l.replace(/url\\([\\'\\\"]?([^\\)\\'\\\"]+)[\\'\\\"]?\\)/g,function(o,p){return\"url(\"+j.url_converter.call(j.url_converter_scope||i,i.decode(p),\"style\",null)+\")\"})}k[c.trim(m[0]).toLowerCase()]=l}});f(\"border\",\"\",\"border\");f(\"border\",\"-width\",\"border-width\");f(\"border\",\"-color\",\"border-color\");f(\"border\",\"-style\",\"border-style\");f(\"padding\",\"\",\"padding\");f(\"margin\",\"\",\"margin\");g(\"border\",\"border-width\",\"border-style\",\"border-color\");if(a){if(k.border==\"medium none\"){k.border=\"\"}}return k},serializeStyle:function(g){var f=\"\";e(g,function(i,h){if(h&&i){if(c.isGecko&&h.indexOf(\"-moz-\")===0){return}switch(h){case\"color\":case\"background-color\":i=i.toLowerCase();break}f+=(f?\" \":\"\")+h+\": \"+i+\";\"}});return f},loadCSS:function(f){var h=this,i=h.doc,g;if(!f){f=\"\"}g=h.select(\"head\")[0];e(f.split(\",\"),function(j){var k;if(h.files[j]){return}h.files[j]=true;k=h.create(\"link\",{rel:\"stylesheet\",href:c._addVer(j)});if(a&&i.documentMode){k.onload=function(){i.recalc();k.onload=null}}g.appendChild(k)})},addClass:function(f,g){return this.run(f,function(h){var i;if(!g){return 0}if(this.hasClass(h,g)){return h.className}i=this.removeClass(h,g);return h.className=(i!=\"\"?(i+\" \"):\"\")+g})},removeClass:function(h,i){var f=this,g;return f.run(h,function(k){var j;if(f.hasClass(k,i)){if(!g){g=new RegExp(\"(^|\\\\s+)\"+i+\"(\\\\s+|$)\",\"g\")}j=k.className.replace(g,\" \");return k.className=c.trim(j!=\" \"?j:\"\")}return k.className})},hasClass:function(g,f){g=this.get(g);if(!g||!f){return false}return(\" \"+g.className+\" \").indexOf(\" \"+f+\" \")!==-1},show:function(f){return this.setStyle(f,\"display\",\"block\")},hide:function(f){return this.setStyle(f,\"display\",\"none\")},isHidden:function(f){f=this.get(f);return !f||f.style.display==\"none\"||this.getStyle(f,\"display\")==\"none\"},uniqueId:function(f){return(!f?\"mce_\":f)+(this.counter++)},setHTML:function(i,g){var f=this;return this.run(i,function(m){var h,k,j,q,l,h;g=f.processHTML(g);if(a){function o(){try{m.innerHTML=\"<br />\"+g;m.removeChild(m.firstChild)}catch(n){while(m.firstChild){m.firstChild.removeNode()}h=f.create(\"div\");h.innerHTML=\"<br />\"+g;e(h.childNodes,function(r,p){if(p){m.appendChild(r)}})}}if(f.settings.fix_ie_paragraphs){g=g.replace(/<p><\\/p>|<p([^>]+)><\\/p>|<p[^\\/+]\\/>/gi,'<p$1 mce_keep=\"true\">&nbsp;</p>')}o();if(f.settings.fix_ie_paragraphs){j=m.getElementsByTagName(\"p\");for(k=j.length-1,h=0;k>=0;k--){q=j[k];if(!q.hasChildNodes()){if(!q.mce_keep){h=1;break}q.removeAttribute(\"mce_keep\")}}}if(h){g=g.replace(/<p ([^>]+)>|<p>/ig,'<div $1 mce_tmp=\"1\">');g=g.replace(/<\\/p>/g,\"</div>\");o();if(f.settings.fix_ie_paragraphs){j=m.getElementsByTagName(\"DIV\");for(k=j.length-1;k>=0;k--){q=j[k];if(q.mce_tmp){l=f.doc.createElement(\"p\");q.cloneNode(false).outerHTML.replace(/([a-z0-9\\-_]+)=/gi,function(p,n){var r;if(n!==\"mce_tmp\"){r=q.getAttribute(n);if(!r&&n===\"class\"){r=q.className}l.setAttribute(n,r)}});for(h=0;h<q.childNodes.length;h++){l.appendChild(q.childNodes[h].cloneNode(true))}q.swapNode(l)}}}}}else{m.innerHTML=g}return g})},processHTML:function(j){var g=this,i=g.settings,k=[];if(!i.process_html){return j}if(c.isGecko){j=j.replace(/<(\\/?)strong>|<strong( [^>]+)>/gi,\"<$1b$2>\");j=j.replace(/<(\\/?)em>|<em( [^>]+)>/gi,\"<$1i$2>\")}else{if(a){j=j.replace(/&apos;/g,\"&#39;\");j=j.replace(/\\s+(disabled|checked|readonly|selected)\\s*=\\s*[\\\"\\']?(false|0)[\\\"\\']?/gi,\"\")}}j=j.replace(/<a( )([^>]+)\\/>|<a\\/>/gi,\"<a$1$2></a>\");if(i.keep_values){if(/<script|noscript|style/i.test(j)){function f(h){h=h.replace(/(<!--\\[CDATA\\[|\\]\\]-->)/g,\"\\n\");h=h.replace(/^[\\r\\n]*|[\\r\\n]*$/g,\"\");h=h.replace(/^\\s*(\\/\\/\\s*<!--|\\/\\/\\s*<!\\[CDATA\\[|<!--|<!\\[CDATA\\[)[\\r\\n]*/g,\"\");h=h.replace(/\\s*(\\/\\/\\s*\\]\\]>|\\/\\/\\s*-->|\\]\\]>|-->|\\]\\]-->)\\s*$/g,\"\");return h}j=j.replace(/<script([^>]+|)>([\\s\\S]*?)<\\/script>/gi,function(h,m,l){if(!m){m=' type=\"text/javascript\"'}m=m.replace(/src=\\\"([^\\\"]+)\\\"?/i,function(n,o){if(i.url_converter){o=g.encode(i.url_converter.call(i.url_converter_scope||g,g.decode(o),\"src\",\"script\"))}return'mce_src=\"'+o+'\"'});if(c.trim(l)){k.push(f(l));l=\"<!--\\nMCE_SCRIPT:\"+(k.length-1)+\"\\n// -->\"}return\"<mce:script\"+m+\">\"+l+\"</mce:script>\"});j=j.replace(/<style([^>]+|)>([\\s\\S]*?)<\\/style>/gi,function(h,m,l){if(l){k.push(f(l));l=\"<!--\\nMCE_SCRIPT:\"+(k.length-1)+\"\\n-->\"}return\"<mce:style\"+m+\">\"+l+\"</mce:style><style \"+m+' mce_bogus=\"1\">'+l+\"</style>\"});j=j.replace(/<noscript([^>]+|)>([\\s\\S]*?)<\\/noscript>/g,function(h,m,l){return\"<mce:noscript\"+m+\"><!--\"+g.encode(l).replace(/--/g,\"&#45;&#45;\")+\"--></mce:noscript>\"})}j=j.replace(/<!\\[CDATA\\[([\\s\\S]+)\\]\\]>/g,\"<!--[CDATA[$1]]-->\");j=j.replace(/<([\\w:]+) [^>]*(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)[^>]*>/gi,function(l){function h(o,m,n){if(n===\"false\"||n===\"0\"){return\"\"}return\" \"+m+'=\"'+m+'\"'}l=l.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=[\\\"]([^\\\"]+)[\\\"]/gi,h);l=l.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=[\\']([^\\']+)[\\']/gi,h);l=l.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=([^\\s\\\"\\'>]+)/gi,h);l=l.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)([\\s>])/gi,' $1=\"$1\"$2');return l});j=j.replace(/<([\\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi,function(h,m){function l(o,n,q){var p=q;if(h.indexOf(\"mce_\"+n)!=-1){return o}if(n==\"style\"){if(g._isRes(q)){return o}p=g.encode(g.serializeStyle(g.parseStyle(p)))}else{if(n!=\"coords\"&&n!=\"shape\"){if(i.url_converter){p=g.encode(i.url_converter.call(i.url_converter_scope||g,g.decode(q),n,m))}}}return\" \"+n+'=\"'+q+'\" mce_'+n+'=\"'+p+'\"'}h=h.replace(/ (src|href|style|coords|shape)=[\\\"]([^\\\"]+)[\\\"]/gi,l);h=h.replace(/ (src|href|style|coords|shape)=[\\']([^\\']+)[\\']/gi,l);return h.replace(/ (src|href|style|coords|shape)=([^\\s\\\"\\'>]+)/gi,l)});j=j.replace(/MCE_SCRIPT:([0-9]+)/g,function(l,h){return k[h]})}return j},getOuterHTML:function(f){var g;f=this.get(f);if(!f){return null}if(f.outerHTML!==undefined){return f.outerHTML}g=(f.ownerDocument||this.doc).createElement(\"body\");g.appendChild(f.cloneNode(true));return g.innerHTML},setOuterHTML:function(j,g,k){var f=this;function i(m,l,p){var q,o;o=p.createElement(\"body\");o.innerHTML=l;q=o.lastChild;while(q){f.insertAfter(q.cloneNode(true),m);q=q.previousSibling}f.remove(m)}return this.run(j,function(l){l=f.get(l);if(l.nodeType==1){k=k||l.ownerDocument||f.doc;if(a){try{if(a&&l.nodeType==1){l.outerHTML=g}else{i(l,g,k)}}catch(h){i(l,g,k)}}else{i(l,g,k)}}})},decode:function(g){var h,i,f;if(/&[^;]+;/.test(g)){h=this.doc.createElement(\"div\");h.innerHTML=g;i=h.firstChild;f=\"\";if(i){do{f+=i.nodeValue}while(i.nextSibling)}return f||g}return g},encode:function(f){return f?(\"\"+f).replace(/[<>&\\\"]/g,function(h,g){switch(h){case\"&\":return\"&amp;\";case'\"':return\"&quot;\";case\"<\":return\"&lt;\";case\">\":return\"&gt;\"}return h}):f},insertAfter:function(h,g){var f=this;g=f.get(g);return this.run(h,function(k){var j,i;j=g.parentNode;i=g.nextSibling;if(i){j.insertBefore(k,i)}else{j.appendChild(k)}return k})},isBlock:function(f){if(f.nodeType&&f.nodeType!==1){return false}f=f.nodeName||f;return/^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TH|TBODY|TR|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(f)},replace:function(i,h,f){var g=this;if(b(h,\"array\")){i=i.cloneNode(true)}return g.run(h,function(j){if(f){e(j.childNodes,function(k){i.appendChild(k.cloneNode(true))})}if(g.fixPsuedoLeaks&&j.nodeType===1){j.parentNode.insertBefore(i,j);g.remove(j);return i}return j.parentNode.replaceChild(i,j)})},findCommonAncestor:function(h,f){var i=h,g;while(i){g=f;while(g&&i!=g){g=g.parentNode}if(i==g){break}i=i.parentNode}if(!i&&h.ownerDocument){return h.ownerDocument.documentElement}return i},toHex:function(f){var h=/^\\s*rgb\\s*?\\(\\s*?([0-9]+)\\s*?,\\s*?([0-9]+)\\s*?,\\s*?([0-9]+)\\s*?\\)\\s*$/i.exec(f);function g(i){i=parseInt(i).toString(16);return i.length>1?i:\"0\"+i}if(h){f=\"#\"+g(h[1])+g(h[2])+g(h[3]);return f}return f},getClasses:function(){var l=this,g=[],k,m={},n=l.settings.class_filter,j;if(l.classes){return l.classes}function o(f){e(f.imports,function(i){o(i)});e(f.cssRules||f.rules,function(i){switch(i.type||1){case 1:if(i.selectorText){e(i.selectorText.split(\",\"),function(p){p=p.replace(/^\\s*|\\s*$|^\\s\\./g,\"\");if(/\\.mce/.test(p)||!/\\.[\\w\\-]+$/.test(p)){return}j=p;p=p.replace(/.*\\.([a-z0-9_\\-]+).*/i,\"$1\");if(n&&!(p=n(p,j))){return}if(!m[p]){g.push({\"class\":p});m[p]=1}})}break;case 3:o(i.styleSheet);break}})}try{e(l.doc.styleSheets,o)}catch(h){}if(g.length>0){l.classes=g}return g},run:function(j,i,h){var g=this,k;if(g.doc&&typeof(j)===\"string\"){j=g.get(j)}if(!j){return false}h=h||this;if(!j.nodeType&&(j.length||j.length===0)){k=[];e(j,function(l,f){if(l){if(typeof(l)==\"string\"){l=g.doc.getElementById(l)}k.push(i.call(h,l,f))}});return k}return i.call(h,j)},getAttribs:function(g){var f;g=this.get(g);if(!g){return[]}if(a){f=[];if(g.nodeName==\"OBJECT\"){return g.attributes}if(g.nodeName===\"OPTION\"&&this.getAttrib(g,\"selected\")){f.push({specified:1,nodeName:\"selected\"})}g.cloneNode(false).outerHTML.replace(/<\\/?[\\w:]+ ?|=[\\\"][^\\\"]+\\\"|=\\'[^\\']+\\'|=\\w+|>/gi,\"\").replace(/[\\w:]+/gi,function(h){f.push({specified:1,nodeName:h})});return f}return g.attributes},destroy:function(g){var f=this;if(f.events){f.events.destroy()}f.win=f.doc=f.root=f.events=null;if(!g){c.removeUnload(f.destroy)}},createRng:function(){var f=this.doc;return f.createRange?f.createRange():new c.dom.Range(this)},split:function(l,k,o){var p=this,f=p.createRng(),m,j,n;function g(r,q){r=r[q];if(r&&r[q]&&r[q].nodeType==1&&i(r[q])){p.remove(r[q])}}function i(q){q=p.getOuterHTML(q);q=q.replace(/<(img|hr|table)/gi,\"-\");q=q.replace(/<[^>]+>/g,\"\");return q.replace(/[ \\t\\r\\n]+|&nbsp;|&#160;/g,\"\")==\"\"}function h(r){var q=0;while(r.previousSibling){q++;r=r.previousSibling}return q}if(l&&k){f.setStart(l.parentNode,h(l));f.setEnd(k.parentNode,h(k));m=f.extractContents();f=p.createRng();f.setStart(k.parentNode,h(k)+1);f.setEnd(l.parentNode,h(l)+1);j=f.extractContents();n=l.parentNode;g(m,\"lastChild\");if(!i(m)){n.insertBefore(m,l)}if(o){n.replaceChild(o,k)}else{n.insertBefore(k,l)}g(j,\"firstChild\");if(!i(j)){n.insertBefore(j,l)}p.remove(l);return o||k}},bind:function(j,f,i,h){var g=this;if(!g.events){g.events=new c.dom.EventUtils()}return g.events.add(j,f,i,h||this)},unbind:function(i,f,h){var g=this;if(!g.events){g.events=new c.dom.EventUtils()}return g.events.remove(i,f,h)},_findSib:function(j,g,h){var i=this,k=g;if(j){if(b(k,\"string\")){k=function(f){return i.is(f,g)}}for(j=j[h];j;j=j[h]){if(k(j)){return j}}}return null},_isRes:function(f){return/^(top|left|bottom|right|width|height)/i.test(f)||/;\\s*(top|left|bottom|right|width|height)/i.test(f)}});c.DOM=new c.dom.DOMUtils(document,{process_html:0})})(tinymce);(function(f){var h=0,c=1,e=2,d=tinymce.extend;function g(m,k){var j,l;if(m.parentNode!=k){return -1}for(l=k.firstChild,j=0;l!=m;l=l.nextSibling){j++}return j}function b(k){var j=0;while(k.previousSibling){j++;k=k.previousSibling}return j}function i(j,k){var l;if(j.nodeType==3){return j}if(k<0){return j}l=j.firstChild;while(l!=null&&k>0){--k;l=l.nextSibling}if(l!=null){return l}return j}function a(k){var j=k.doc;d(this,{dom:k,startContainer:j,startOffset:0,endContainer:j,endOffset:0,collapsed:true,commonAncestorContainer:j,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3})}d(a.prototype,{setStart:function(k,j){this._setEndPoint(true,k,j)},setEnd:function(k,j){this._setEndPoint(false,k,j)},setStartBefore:function(j){this.setStart(j.parentNode,b(j))},setStartAfter:function(j){this.setStart(j.parentNode,b(j)+1)},setEndBefore:function(j){this.setEnd(j.parentNode,b(j))},setEndAfter:function(j){this.setEnd(j.parentNode,b(j)+1)},collapse:function(k){var j=this;if(k){j.endContainer=j.startContainer;j.endOffset=j.startOffset}else{j.startContainer=j.endContainer;j.startOffset=j.endOffset}j.collapsed=true},selectNode:function(j){this.setStartBefore(j);this.setEndAfter(j)},selectNodeContents:function(j){this.setStart(j,0);this.setEnd(j,j.nodeType===1?j.childNodes.length:j.nodeValue.length)},compareBoundaryPoints:function(m,n){var l=this,p=l.startContainer,o=l.startOffset,k=l.endContainer,j=l.endOffset;if(m===0){return l._compareBoundaryPoints(p,o,p,o)}if(m===1){return l._compareBoundaryPoints(p,o,k,j)}if(m===2){return l._compareBoundaryPoints(k,j,k,j)}if(m===3){return l._compareBoundaryPoints(k,j,p,o)}},deleteContents:function(){this._traverse(e)},extractContents:function(){return this._traverse(h)},cloneContents:function(){return this._traverse(c)},insertNode:function(m){var j=this,l,k;if(m.nodeType===3||m.nodeType===4){l=j.startContainer.splitText(j.startOffset);j.startContainer.parentNode.insertBefore(m,l)}else{if(j.startContainer.childNodes.length>0){k=j.startContainer.childNodes[j.startOffset]}j.startContainer.insertBefore(m,k)}},surroundContents:function(l){var j=this,k=j.extractContents();j.insertNode(l);l.appendChild(k);j.selectNode(l)},cloneRange:function(){var j=this;return d(new a(j.dom),{startContainer:j.startContainer,startOffset:j.startOffset,endContainer:j.endContainer,endOffset:j.endOffset,collapsed:j.collapsed,commonAncestorContainer:j.commonAncestorContainer})},_isCollapsed:function(){return(this.startContainer==this.endContainer&&this.startOffset==this.endOffset)},_compareBoundaryPoints:function(m,p,k,o){var q,l,j,r,t,s;if(m==k){if(p==o){return 0}else{if(p<o){return -1}else{return 1}}}q=k;while(q&&q.parentNode!=m){q=q.parentNode}if(q){l=0;j=m.firstChild;while(j!=q&&l<p){l++;j=j.nextSibling}if(p<=l){return -1}else{return 1}}q=m;while(q&&q.parentNode!=k){q=q.parentNode}if(q){l=0;j=k.firstChild;while(j!=q&&l<o){l++;j=j.nextSibling}if(l<o){return -1}else{return 1}}r=this.dom.findCommonAncestor(m,k);t=m;while(t&&t.parentNode!=r){t=t.parentNode}if(!t){t=r}s=k;while(s&&s.parentNode!=r){s=s.parentNode}if(!s){s=r}if(t==s){return 0}j=r.firstChild;while(j){if(j==t){return -1}if(j==s){return 1}j=j.nextSibling}},_setEndPoint:function(k,q,p){var l=this,j,m;if(k){l.startContainer=q;l.startOffset=p}else{l.endContainer=q;l.endOffset=p}j=l.endContainer;while(j.parentNode){j=j.parentNode}m=l.startContainer;while(m.parentNode){m=m.parentNode}if(m!=j){l.collapse(k)}else{if(l._compareBoundaryPoints(l.startContainer,l.startOffset,l.endContainer,l.endOffset)>0){l.collapse(k)}}l.collapsed=l._isCollapsed();l.commonAncestorContainer=l.dom.findCommonAncestor(l.startContainer,l.endContainer)},_traverse:function(r){var s=this,q,m=0,v=0,k,o,l,n,j,u;if(s.startContainer==s.endContainer){return s._traverseSameContainer(r)}for(q=s.endContainer,k=q.parentNode;k!=null;q=k,k=k.parentNode){if(k==s.startContainer){return s._traverseCommonStartContainer(q,r)}++m}for(q=s.startContainer,k=q.parentNode;k!=null;q=k,k=k.parentNode){if(k==s.endContainer){return s._traverseCommonEndContainer(q,r)}++v}o=v-m;l=s.startContainer;while(o>0){l=l.parentNode;o--}n=s.endContainer;while(o<0){n=n.parentNode;o++}for(j=l.parentNode,u=n.parentNode;j!=u;j=j.parentNode,u=u.parentNode){l=j;n=u}return s._traverseCommonAncestors(l,n,r)},_traverseSameContainer:function(o){var r=this,q,u,j,k,l,p,m;if(o!=e){q=r.dom.doc.createDocumentFragment()}if(r.startOffset==r.endOffset){return q}if(r.startContainer.nodeType==3){u=r.startContainer.nodeValue;j=u.substring(r.startOffset,r.endOffset);if(o!=c){r.startContainer.deleteData(r.startOffset,r.endOffset-r.startOffset);r.collapse(true)}if(o==e){return null}q.appendChild(r.dom.doc.createTextNode(j));return q}k=i(r.startContainer,r.startOffset);l=r.endOffset-r.startOffset;while(l>0){p=k.nextSibling;m=r._traverseFullySelected(k,o);if(q){q.appendChild(m)}--l;k=p}if(o!=c){r.collapse(true)}return q},_traverseCommonStartContainer:function(j,p){var s=this,r,k,l,m,q,o;if(p!=e){r=s.dom.doc.createDocumentFragment()}k=s._traverseRightBoundary(j,p);if(r){r.appendChild(k)}l=g(j,s.startContainer);m=l-s.startOffset;if(m<=0){if(p!=c){s.setEndBefore(j);s.collapse(false)}return r}k=j.previousSibling;while(m>0){q=k.previousSibling;o=s._traverseFullySelected(k,p);if(r){r.insertBefore(o,r.firstChild)}--m;k=q}if(p!=c){s.setEndBefore(j);s.collapse(false)}return r},_traverseCommonEndContainer:function(m,p){var s=this,r,o,j,k,q,l;if(p!=e){r=s.dom.doc.createDocumentFragment()}j=s._traverseLeftBoundary(m,p);if(r){r.appendChild(j)}o=g(m,s.endContainer);++o;k=s.endOffset-o;j=m.nextSibling;while(k>0){q=j.nextSibling;l=s._traverseFullySelected(j,p);if(r){r.appendChild(l)}--k;j=q}if(p!=c){s.setStartAfter(m);s.collapse(true)}return r},_traverseCommonAncestors:function(p,j,s){var w=this,l,v,o,q,r,k,u,m;if(s!=e){v=w.dom.doc.createDocumentFragment()}l=w._traverseLeftBoundary(p,s);if(v){v.appendChild(l)}o=p.parentNode;q=g(p,o);r=g(j,o);++q;k=r-q;u=p.nextSibling;while(k>0){m=u.nextSibling;l=w._traverseFullySelected(u,s);if(v){v.appendChild(l)}u=m;--k}l=w._traverseRightBoundary(j,s);if(v){v.appendChild(l)}if(s!=c){w.setStartAfter(p);w.collapse(true)}return v},_traverseRightBoundary:function(p,q){var s=this,l=i(s.endContainer,s.endOffset-1),r,o,n,j,k;var m=l!=s.endContainer;if(l==p){return s._traverseNode(l,m,false,q)}r=l.parentNode;o=s._traverseNode(r,false,false,q);while(r!=null){while(l!=null){n=l.previousSibling;j=s._traverseNode(l,m,false,q);if(q!=e){o.insertBefore(j,o.firstChild)}m=true;l=n}if(r==p){return o}l=r.previousSibling;r=r.parentNode;k=s._traverseNode(r,false,false,q);if(q!=e){k.appendChild(o)}o=k}return null},_traverseLeftBoundary:function(p,q){var s=this,m=i(s.startContainer,s.startOffset);var n=m!=s.startContainer,r,o,l,j,k;if(m==p){return s._traverseNode(m,n,true,q)}r=m.parentNode;o=s._traverseNode(r,false,true,q);while(r!=null){while(m!=null){l=m.nextSibling;j=s._traverseNode(m,n,true,q);if(q!=e){o.appendChild(j)}n=true;m=l}if(r==p){return o}m=r.nextSibling;r=r.parentNode;k=s._traverseNode(r,false,true,q);if(q!=e){k.appendChild(o)}o=k}return null},_traverseNode:function(j,o,r,s){var u=this,m,l,p,k,q;if(o){return u._traverseFullySelected(j,s)}if(j.nodeType==3){m=j.nodeValue;if(r){k=u.startOffset;l=m.substring(k);p=m.substring(0,k)}else{k=u.endOffset;l=m.substring(0,k);p=m.substring(k)}if(s!=c){j.nodeValue=p}if(s==e){return null}q=j.cloneNode(false);q.nodeValue=l;return q}if(s==e){return null}return j.cloneNode(false)},_traverseFullySelected:function(l,k){var j=this;if(k!=e){return k==c?l.cloneNode(true):l}l.parentNode.removeChild(l);return null}});f.Range=a})(tinymce.dom);(function(){function a(e){var d=this,h=\"\\uFEFF\",b,g;function c(j,i){if(j&&i){if(j.item&&i.item&&j.item(0)===i.item(0)){return 1}if(j.isEqual&&i.isEqual&&i.isEqual(j)){return 1}}return 0}function f(){var m=e.dom,j=e.getRng(),s=m.createRng(),p,k,n,q,o,l;function i(v){var t=v.parentNode.childNodes,u;for(u=t.length-1;u>=0;u--){if(t[u]==v){return u}}return -1}function r(v){var t=j.duplicate(),B,y,u,w,x=0,z=0,A,C;t.collapse(v);B=t.parentElement();t.pasteHTML(h);u=B.childNodes;for(y=0;y<u.length;y++){w=u[y];if(y>0&&(w.nodeType!==3||u[y-1].nodeType!==3)){z++}if(w.nodeType===3){A=w.nodeValue.indexOf(h);if(A!==-1){x+=A;break}x+=w.nodeValue.length}else{x=0}}t.moveStart(\"character\",-1);t.text=\"\";return{index:z,offset:x,parent:B}}n=j.item?j.item(0):j.parentElement();if(n.ownerDocument!=m.doc){return s}if(j.item||!n.hasChildNodes()){s.setStart(n.parentNode,i(n));s.setEnd(s.startContainer,s.startOffset+1);return s}l=e.isCollapsed();p=r(true);k=r(false);p.parent.normalize();k.parent.normalize();q=p.parent.childNodes[Math.min(p.index,p.parent.childNodes.length-1)];if(q.nodeType!=3){s.setStart(p.parent,p.index)}else{s.setStart(p.parent.childNodes[p.index],p.offset)}o=k.parent.childNodes[Math.min(k.index,k.parent.childNodes.length-1)];if(o.nodeType!=3){if(!l){k.index++}s.setEnd(k.parent,k.index)}else{s.setEnd(k.parent.childNodes[k.index],k.offset)}if(!l){q=s.startContainer;if(q.nodeType==1){s.setStart(q,Math.min(s.startOffset,q.childNodes.length))}o=s.endContainer;if(o.nodeType==1){s.setEnd(o,Math.min(s.endOffset,o.childNodes.length))}}d.addRange(s);return s}this.addRange=function(j){var o,m=e.dom.doc.body,p,k,q,l,n,i;q=j.startContainer;l=j.startOffset;n=j.endContainer;i=j.endOffset;o=m.createTextRange();q=q.nodeType==1?q.childNodes[Math.min(l,q.childNodes.length-1)]:q;n=n.nodeType==1?n.childNodes[Math.min(l==i?i:i-1,n.childNodes.length-1)]:n;if(q==n&&q.nodeType==1){if(/^(IMG|TABLE)$/.test(q.nodeName)&&l!=i){o=m.createControlRange();o.addElement(q)}else{o=m.createTextRange();if(!q.hasChildNodes()&&q.canHaveHTML){q.innerHTML=h}o.moveToElementText(q);if(q.innerHTML==h){o.collapse(true);q.removeChild(q.firstChild)}}if(l==i){o.collapse(i<=j.endContainer.childNodes.length-1)}o.select();return}function r(t,v){var u,s,w;if(t.nodeType!=3){return -1}u=t.nodeValue;s=m.createTextRange();t.nodeValue=u.substring(0,v)+h+u.substring(v);s.moveToElementText(t.parentNode);s.findText(h);w=Math.abs(s.moveStart(\"character\",-1048575));t.nodeValue=u;return w}if(j.collapsed){pos=r(q,l);o=m.createTextRange();o.move(\"character\",pos);o.select();return}else{if(q==n&&q.nodeType==3){p=r(q,l);o=m.createTextRange();o.move(\"character\",p);o.moveEnd(\"character\",i-l);o.select();return}p=r(q,l);k=r(n,i);o=m.createTextRange();if(p==-1){o.moveToElementText(q);p=0}else{o.move(\"character\",p)}tmpRng=m.createTextRange();if(k==-1){tmpRng.moveToElementText(n)}else{tmpRng.move(\"character\",k)}o.setEndPoint(\"EndToEnd\",tmpRng);o.select();return}};this.getRangeAt=function(){if(!b||!c(g,e.getRng())){b=f();g=e.getRng()}return b};this.destroy=function(){g=b=null}}tinymce.dom.TridentSelection=a})();(function(){var p=/((?:\\((?:\\([^()]+\\)|[^()]+)+\\)|\\[(?:\\[[^[\\]]*\\]|['\"][^'\"]*['\"]|[^[\\]'\"]+)+\\]|\\\\.|[^ >+~,(\\[\\\\]+)+|[>+~])(\\s*,\\s*)?/g,i=0,d=Object.prototype.toString,n=false;var b=function(D,t,A,v){A=A||[];var e=t=t||document;if(t.nodeType!==1&&t.nodeType!==9){return[]}if(!D||typeof D!==\"string\"){return A}var B=[],C,y,G,F,z,s,r=true,w=o(t);p.lastIndex=0;while((C=p.exec(D))!==null){B.push(C[1]);if(C[2]){s=RegExp.rightContext;break}}if(B.length>1&&j.exec(D)){if(B.length===2&&f.relative[B[0]]){y=g(B[0]+B[1],t)}else{y=f.relative[B[0]]?[t]:b(B.shift(),t);while(B.length){D=B.shift();if(f.relative[D]){D+=B.shift()}y=g(D,y)}}}else{if(!v&&B.length>1&&t.nodeType===9&&!w&&f.match.ID.test(B[0])&&!f.match.ID.test(B[B.length-1])){var H=b.find(B.shift(),t,w);t=H.expr?b.filter(H.expr,H.set)[0]:H.set[0]}if(t){var H=v?{expr:B.pop(),set:a(v)}:b.find(B.pop(),B.length===1&&(B[0]===\"~\"||B[0]===\"+\")&&t.parentNode?t.parentNode:t,w);y=H.expr?b.filter(H.expr,H.set):H.set;if(B.length>0){G=a(y)}else{r=false}while(B.length){var u=B.pop(),x=u;if(!f.relative[u]){u=\"\"}else{x=B.pop()}if(x==null){x=t}f.relative[u](G,x,w)}}else{G=B=[]}}if(!G){G=y}if(!G){throw\"Syntax error, unrecognized expression: \"+(u||D)}if(d.call(G)===\"[object Array]\"){if(!r){A.push.apply(A,G)}else{if(t&&t.nodeType===1){for(var E=0;G[E]!=null;E++){if(G[E]&&(G[E]===true||G[E].nodeType===1&&h(t,G[E]))){A.push(y[E])}}}else{for(var E=0;G[E]!=null;E++){if(G[E]&&G[E].nodeType===1){A.push(y[E])}}}}}else{a(G,A)}if(s){b(s,e,A,v);b.uniqueSort(A)}return A};b.uniqueSort=function(r){if(c){n=false;r.sort(c);if(n){for(var e=1;e<r.length;e++){if(r[e]===r[e-1]){r.splice(e--,1)}}}}};b.matches=function(e,r){return b(e,null,null,r)};b.find=function(x,e,y){var w,u;if(!x){return[]}for(var t=0,s=f.order.length;t<s;t++){var v=f.order[t],u;if((u=f.match[v].exec(x))){var r=RegExp.leftContext;if(r.substr(r.length-1)!==\"\\\\\"){u[1]=(u[1]||\"\").replace(/\\\\/g,\"\");w=f.find[v](u,e,y);if(w!=null){x=x.replace(f.match[v],\"\");break}}}}if(!w){w=e.getElementsByTagName(\"*\")}return{set:w,expr:x}};b.filter=function(A,z,D,t){var s=A,F=[],x=z,v,e,w=z&&z[0]&&o(z[0]);while(A&&z.length){for(var y in f.filter){if((v=f.match[y].exec(A))!=null){var r=f.filter[y],E,C;e=false;if(x==F){F=[]}if(f.preFilter[y]){v=f.preFilter[y](v,x,D,F,t,w);if(!v){e=E=true}else{if(v===true){continue}}}if(v){for(var u=0;(C=x[u])!=null;u++){if(C){E=r(C,v,u,x);var B=t^!!E;if(D&&E!=null){if(B){e=true}else{x[u]=false}}else{if(B){F.push(C);e=true}}}}}if(E!==undefined){if(!D){x=F}A=A.replace(f.match[y],\"\");if(!e){return[]}break}}}if(A==s){if(e==null){throw\"Syntax error, unrecognized expression: \"+A}else{break}}s=A}return x};var f=b.selectors={order:[\"ID\",\"NAME\",\"TAG\"],match:{ID:/#((?:[\\w\\u00c0-\\uFFFF_-]|\\\\.)+)/,CLASS:/\\.((?:[\\w\\u00c0-\\uFFFF_-]|\\\\.)+)/,NAME:/\\[name=['\"]*((?:[\\w\\u00c0-\\uFFFF_-]|\\\\.)+)['\"]*\\]/,ATTR:/\\[\\s*((?:[\\w\\u00c0-\\uFFFF_-]|\\\\.)+)\\s*(?:(\\S?=)\\s*(['\"]*)(.*?)\\3|)\\s*\\]/,TAG:/^((?:[\\w\\u00c0-\\uFFFF\\*_-]|\\\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\\((even|odd|[\\dn+-]*)\\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\))?(?=[^-]|$)/,PSEUDO:/:((?:[\\w\\u00c0-\\uFFFF_-]|\\\\.)+)(?:\\((['\"]*)((?:\\([^\\)]+\\)|[^\\2\\(\\)]*)+)\\2\\))?/},attrMap:{\"class\":\"className\",\"for\":\"htmlFor\"},attrHandle:{href:function(e){return e.getAttribute(\"href\")}},relative:{\"+\":function(x,e,w){var u=typeof e===\"string\",y=u&&!/\\W/.test(e),v=u&&!y;if(y&&!w){e=e.toUpperCase()}for(var t=0,s=x.length,r;t<s;t++){if((r=x[t])){while((r=r.previousSibling)&&r.nodeType!==1){}x[t]=v||r&&r.nodeName===e?r||false:r===e}}if(v){b.filter(e,x,true)}},\">\":function(w,r,x){var u=typeof r===\"string\";if(u&&!/\\W/.test(r)){r=x?r:r.toUpperCase();for(var s=0,e=w.length;s<e;s++){var v=w[s];if(v){var t=v.parentNode;w[s]=t.nodeName===r?t:false}}}else{for(var s=0,e=w.length;s<e;s++){var v=w[s];if(v){w[s]=u?v.parentNode:v.parentNode===r}}if(u){b.filter(r,w,true)}}},\"\":function(t,r,v){var s=i++,e=q;if(!r.match(/\\W/)){var u=r=v?r:r.toUpperCase();e=m}e(\"parentNode\",r,s,t,u,v)},\"~\":function(t,r,v){var s=i++,e=q;if(typeof r===\"string\"&&!r.match(/\\W/)){var u=r=v?r:r.toUpperCase();e=m}e(\"previousSibling\",r,s,t,u,v)}},find:{ID:function(r,s,t){if(typeof s.getElementById!==\"undefined\"&&!t){var e=s.getElementById(r[1]);return e?[e]:[]}},NAME:function(s,v,w){if(typeof v.getElementsByName!==\"undefined\"){var r=[],u=v.getElementsByName(s[1]);for(var t=0,e=u.length;t<e;t++){if(u[t].getAttribute(\"name\")===s[1]){r.push(u[t])}}return r.length===0?null:r}},TAG:function(e,r){return r.getElementsByTagName(e[1])}},preFilter:{CLASS:function(t,r,s,e,w,x){t=\" \"+t[1].replace(/\\\\/g,\"\")+\" \";if(x){return t}for(var u=0,v;(v=r[u])!=null;u++){if(v){if(w^(v.className&&(\" \"+v.className+\" \").indexOf(t)>=0)){if(!s){e.push(v)}}else{if(s){r[u]=false}}}}return false},ID:function(e){return e[1].replace(/\\\\/g,\"\")},TAG:function(r,e){for(var s=0;e[s]===false;s++){}return e[s]&&o(e[s])?r[1]:r[1].toUpperCase()},CHILD:function(e){if(e[1]==\"nth\"){var r=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.exec(e[2]==\"even\"&&\"2n\"||e[2]==\"odd\"&&\"2n+1\"||!/\\D/.test(e[2])&&\"0n+\"+e[2]||e[2]);e[2]=(r[1]+(r[2]||1))-0;e[3]=r[3]-0}e[0]=i++;return e},ATTR:function(u,r,s,e,v,w){var t=u[1].replace(/\\\\/g,\"\");if(!w&&f.attrMap[t]){u[1]=f.attrMap[t]}if(u[2]===\"~=\"){u[4]=\" \"+u[4]+\" \"}return u},PSEUDO:function(u,r,s,e,v){if(u[1]===\"not\"){if(u[3].match(p).length>1||/^\\w/.test(u[3])){u[3]=b(u[3],null,null,r)}else{var t=b.filter(u[3],r,s,true^v);if(!s){e.push.apply(e,t)}return false}}else{if(f.match.POS.test(u[0])||f.match.CHILD.test(u[0])){return true}}return u},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!==\"hidden\"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){e.parentNode.selectedIndex;return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(s,r,e){return !!b(e[3],s).length},header:function(e){return/h\\d/i.test(e.nodeName)},text:function(e){return\"text\"===e.type},radio:function(e){return\"radio\"===e.type},checkbox:function(e){return\"checkbox\"===e.type},file:function(e){return\"file\"===e.type},password:function(e){return\"password\"===e.type},submit:function(e){return\"submit\"===e.type},image:function(e){return\"image\"===e.type},reset:function(e){return\"reset\"===e.type},button:function(e){return\"button\"===e.type||e.nodeName.toUpperCase()===\"BUTTON\"},input:function(e){return/input|select|textarea|button/i.test(e.nodeName)}},setFilters:{first:function(r,e){return e===0},last:function(s,r,e,t){return r===t.length-1},even:function(r,e){return e%2===0},odd:function(r,e){return e%2===1},lt:function(s,r,e){return r<e[3]-0},gt:function(s,r,e){return r>e[3]-0},nth:function(s,r,e){return e[3]-0==r},eq:function(s,r,e){return e[3]-0==r}},filter:{PSEUDO:function(w,s,t,x){var r=s[1],u=f.filters[r];if(u){return u(w,t,s,x)}else{if(r===\"contains\"){return(w.textContent||w.innerText||\"\").indexOf(s[3])>=0}else{if(r===\"not\"){var v=s[3];for(var t=0,e=v.length;t<e;t++){if(v[t]===w){return false}}return true}}}},CHILD:function(e,t){var w=t[1],r=e;switch(w){case\"only\":case\"first\":while(r=r.previousSibling){if(r.nodeType===1){return false}}if(w==\"first\"){return true}r=e;case\"last\":while(r=r.nextSibling){if(r.nodeType===1){return false}}return true;case\"nth\":var s=t[2],z=t[3];if(s==1&&z==0){return true}var v=t[0],y=e.parentNode;if(y&&(y.sizcache!==v||!e.nodeIndex)){var u=0;for(r=y.firstChild;r;r=r.nextSibling){if(r.nodeType===1){r.nodeIndex=++u}}y.sizcache=v}var x=e.nodeIndex-z;if(s==0){return x==0}else{return(x%s==0&&x/s>=0)}}},ID:function(r,e){return r.nodeType===1&&r.getAttribute(\"id\")===e},TAG:function(r,e){return(e===\"*\"&&r.nodeType===1)||r.nodeName===e},CLASS:function(r,e){return(\" \"+(r.className||r.getAttribute(\"class\"))+\" \").indexOf(e)>-1},ATTR:function(v,t){var s=t[1],e=f.attrHandle[s]?f.attrHandle[s](v):v[s]!=null?v[s]:v.getAttribute(s),w=e+\"\",u=t[2],r=t[4];return e==null?u===\"!=\":u===\"=\"?w===r:u===\"*=\"?w.indexOf(r)>=0:u===\"~=\"?(\" \"+w+\" \").indexOf(r)>=0:!r?w&&e!==false:u===\"!=\"?w!=r:u===\"^=\"?w.indexOf(r)===0:u===\"$=\"?w.substr(w.length-r.length)===r:u===\"|=\"?w===r||w.substr(0,r.length+1)===r+\"-\":false},POS:function(u,r,s,v){var e=r[2],t=f.setFilters[e];if(t){return t(u,s,r,v)}}}};var j=f.match.POS;for(var l in f.match){f.match[l]=new RegExp(f.match[l].source+/(?![^\\[]*\\])(?![^\\(]*\\))/.source)}var a=function(r,e){r=Array.prototype.slice.call(r);if(e){e.push.apply(e,r);return e}return r};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(k){a=function(u,t){var r=t||[];if(d.call(u)===\"[object Array]\"){Array.prototype.push.apply(r,u)}else{if(typeof u.length===\"number\"){for(var s=0,e=u.length;s<e;s++){r.push(u[s])}}else{for(var s=0;u[s];s++){r.push(u[s])}}}return r}}var c;if(document.documentElement.compareDocumentPosition){c=function(r,e){var s=r.compareDocumentPosition(e)&4?-1:r===e?0:1;if(s===0){n=true}return s}}else{if(\"sourceIndex\" in document.documentElement){c=function(r,e){var s=r.sourceIndex-e.sourceIndex;if(s===0){n=true}return s}}else{if(document.createRange){c=function(t,r){var s=t.ownerDocument.createRange(),e=r.ownerDocument.createRange();s.setStart(t,0);s.setEnd(t,0);e.setStart(r,0);e.setEnd(r,0);var u=s.compareBoundaryPoints(Range.START_TO_END,e);if(u===0){n=true}return u}}}}(function(){var r=document.createElement(\"div\"),s=\"script\"+(new Date).getTime();r.innerHTML=\"<a name='\"+s+\"'/>\";var e=document.documentElement;e.insertBefore(r,e.firstChild);if(!!document.getElementById(s)){f.find.ID=function(u,v,w){if(typeof v.getElementById!==\"undefined\"&&!w){var t=v.getElementById(u[1]);return t?t.id===u[1]||typeof t.getAttributeNode!==\"undefined\"&&t.getAttributeNode(\"id\").nodeValue===u[1]?[t]:undefined:[]}};f.filter.ID=function(v,t){var u=typeof v.getAttributeNode!==\"undefined\"&&v.getAttributeNode(\"id\");return v.nodeType===1&&u&&u.nodeValue===t}}e.removeChild(r)})();(function(){var e=document.createElement(\"div\");e.appendChild(document.createComment(\"\"));if(e.getElementsByTagName(\"*\").length>0){f.find.TAG=function(r,v){var u=v.getElementsByTagName(r[1]);if(r[1]===\"*\"){var t=[];for(var s=0;u[s];s++){if(u[s].nodeType===1){t.push(u[s])}}u=t}return u}}e.innerHTML=\"<a href='#'></a>\";if(e.firstChild&&typeof e.firstChild.getAttribute!==\"undefined\"&&e.firstChild.getAttribute(\"href\")!==\"#\"){f.attrHandle.href=function(r){return r.getAttribute(\"href\",2)}}})();if(document.querySelectorAll){(function(){var e=b,s=document.createElement(\"div\");s.innerHTML=\"<p class='TEST'></p>\";if(s.querySelectorAll&&s.querySelectorAll(\".TEST\").length===0){return}b=function(w,v,t,u){v=v||document;if(!u&&v.nodeType===9&&!o(v)){try{return a(v.querySelectorAll(w),t)}catch(x){}}return e(w,v,t,u)};for(var r in e){b[r]=e[r]}})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var e=document.createElement(\"div\");e.innerHTML=\"<div class='test e'></div><div class='test'></div>\";if(e.getElementsByClassName(\"e\").length===0){return}e.lastChild.className=\"e\";if(e.getElementsByClassName(\"e\").length===1){return}f.order.splice(1,0,\"CLASS\");f.find.CLASS=function(r,s,t){if(typeof s.getElementsByClassName!==\"undefined\"&&!t){return s.getElementsByClassName(r[1])}}})()}function m(r,w,v,A,x,z){var y=r==\"previousSibling\"&&!z;for(var t=0,s=A.length;t<s;t++){var e=A[t];if(e){if(y&&e.nodeType===1){e.sizcache=v;e.sizset=t}e=e[r];var u=false;while(e){if(e.sizcache===v){u=A[e.sizset];break}if(e.nodeType===1&&!z){e.sizcache=v;e.sizset=t}if(e.nodeName===w){u=e;break}e=e[r]}A[t]=u}}}function q(r,w,v,A,x,z){var y=r==\"previousSibling\"&&!z;for(var t=0,s=A.length;t<s;t++){var e=A[t];if(e){if(y&&e.nodeType===1){e.sizcache=v;e.sizset=t}e=e[r];var u=false;while(e){if(e.sizcache===v){u=A[e.sizset];break}if(e.nodeType===1){if(!z){e.sizcache=v;e.sizset=t}if(typeof w!==\"string\"){if(e===w){u=true;break}}else{if(b.filter(w,[e]).length>0){u=e;break}}}e=e[r]}A[t]=u}}}var h=document.compareDocumentPosition?function(r,e){return r.compareDocumentPosition(e)&16}:function(r,e){return r!==e&&(r.contains?r.contains(e):true)};var o=function(e){return e.nodeType===9&&e.documentElement.nodeName!==\"HTML\"||!!e.ownerDocument&&e.ownerDocument.documentElement.nodeName!==\"HTML\"};var g=function(e,x){var t=[],u=\"\",v,s=x.nodeType?[x]:x;while((v=f.match.PSEUDO.exec(e))){u+=v[0];e=e.replace(f.match.PSEUDO,\"\")}e=f.relative[e]?e+\"*\":e;for(var w=0,r=s.length;w<r;w++){b(e,s[w],t)}return b.filter(u,t)};window.tinymce.dom.Sizzle=b})();(function(d){var f=d.each,c=d.DOM,b=d.isIE,e=d.isWebKit,a;d.create(\"tinymce.dom.EventUtils\",{EventUtils:function(){this.inits=[];this.events=[]},add:function(m,p,l,j){var g,h=this,i=h.events,k;if(p instanceof Array){k=[];f(p,function(o){k.push(h.add(m,o,l,j))});return k}if(m&&m.hasOwnProperty&&m instanceof Array){k=[];f(m,function(n){n=c.get(n);k.push(h.add(n,p,l,j))});return k}m=c.get(m);if(!m){return}g=function(n){if(h.disabled){return}n=n||window.event;if(n&&b){if(!n.target){n.target=n.srcElement}d.extend(n,h._stoppers)}if(!j){return l(n)}return l.call(j,n)};if(p==\"unload\"){d.unloads.unshift({func:g});return g}if(p==\"init\"){if(h.domLoaded){g()}else{h.inits.push(g)}return g}i.push({obj:m,name:p,func:l,cfunc:g,scope:j});h._add(m,p,g);return l},remove:function(l,m,k){var h=this,g=h.events,i=false,j;if(l&&l.hasOwnProperty&&l instanceof Array){j=[];f(l,function(n){n=c.get(n);j.push(h.remove(n,m,k))});return j}l=c.get(l);f(g,function(o,n){if(o.obj==l&&o.name==m&&(!k||(o.func==k||o.cfunc==k))){g.splice(n,1);h._remove(l,m,o.cfunc);i=true;return false}});return i},clear:function(l){var j=this,g=j.events,h,k;if(l){l=c.get(l);for(h=g.length-1;h>=0;h--){k=g[h];if(k.obj===l){j._remove(k.obj,k.name,k.cfunc);k.obj=k.cfunc=null;g.splice(h,1)}}}},cancel:function(g){if(!g){return false}this.stop(g);return this.prevent(g)},stop:function(g){if(g.stopPropagation){g.stopPropagation()}else{g.cancelBubble=true}return false},prevent:function(g){if(g.preventDefault){g.preventDefault()}else{g.returnValue=false}return false},destroy:function(){var g=this;f(g.events,function(j,h){g._remove(j.obj,j.name,j.cfunc);j.obj=j.cfunc=null});g.events=[];g=null},_add:function(h,i,g){if(h.attachEvent){h.attachEvent(\"on\"+i,g)}else{if(h.addEventListener){h.addEventListener(i,g,false)}else{h[\"on\"+i]=g}}},_remove:function(i,j,h){if(i){try{if(i.detachEvent){i.detachEvent(\"on\"+j,h)}else{if(i.removeEventListener){i.removeEventListener(j,h,false)}else{i[\"on\"+j]=null}}}catch(g){}}},_pageInit:function(h){var g=this;if(g.domLoaded){return}g.domLoaded=true;f(g.inits,function(i){i()});g.inits=[]},_wait:function(i){var g=this,h=i.document;if(i.tinyMCE_GZ&&tinyMCE_GZ.loaded){g.domLoaded=1;return}if(h.attachEvent){h.attachEvent(\"onreadystatechange\",function(){if(h.readyState===\"complete\"){h.detachEvent(\"onreadystatechange\",arguments.callee);g._pageInit(i)}});if(h.documentElement.doScroll&&i==i.top){(function(){if(g.domLoaded){return}try{h.documentElement.doScroll(\"left\")}catch(j){setTimeout(arguments.callee,0);return}g._pageInit(i)})()}}else{if(h.addEventListener){g._add(i,\"DOMContentLoaded\",function(){g._pageInit(i)})}}g._add(i,\"load\",function(){g._pageInit(i)})},_stoppers:{preventDefault:function(){this.returnValue=false},stopPropagation:function(){this.cancelBubble=true}}});a=d.dom.Event=new d.dom.EventUtils();a._wait(window);d.addUnload(function(){a.destroy()})})(tinymce);(function(a){var b=a.each;a.create(\"tinymce.dom.Element\",{Element:function(g,e){var c=this,f,d;e=e||{};c.id=g;c.dom=f=e.dom||a.DOM;c.settings=e;if(!a.isIE){d=c.dom.get(c.id)}b([\"getPos\",\"getRect\",\"getParent\",\"add\",\"setStyle\",\"getStyle\",\"setStyles\",\"setAttrib\",\"setAttribs\",\"getAttrib\",\"addClass\",\"removeClass\",\"hasClass\",\"getOuterHTML\",\"setOuterHTML\",\"remove\",\"show\",\"hide\",\"isHidden\",\"setHTML\",\"get\"],function(h){c[h]=function(){var j=[g],k;for(k=0;k<arguments.length;k++){j.push(arguments[k])}j=f[h].apply(f,j);c.update(h);return j}})},on:function(e,d,c){return a.dom.Event.add(this.id,e,d,c)},getXY:function(){return{x:parseInt(this.getStyle(\"left\")),y:parseInt(this.getStyle(\"top\"))}},getSize:function(){var c=this.dom.get(this.id);return{w:parseInt(this.getStyle(\"width\")||c.clientWidth),h:parseInt(this.getStyle(\"height\")||c.clientHeight)}},moveTo:function(c,d){this.setStyles({left:c,top:d})},moveBy:function(c,e){var d=this.getXY();this.moveTo(d.x+c,d.y+e)},resizeTo:function(c,d){this.setStyles({width:c,height:d})},resizeBy:function(c,e){var d=this.getSize();this.resizeTo(d.w+c,d.h+e)},update:function(d){var e=this,c,f=e.dom;if(a.isIE6&&e.settings.blocker){d=d||\"\";if(d.indexOf(\"get\")===0||d.indexOf(\"has\")===0||d.indexOf(\"is\")===0){return}if(d==\"remove\"){f.remove(e.blocker);return}if(!e.blocker){e.blocker=f.uniqueId();c=f.add(e.settings.container||f.getRoot(),\"iframe\",{id:e.blocker,style:\"position:absolute;\",frameBorder:0,src:'javascript:\"\"'});f.setStyle(c,\"opacity\",0)}else{c=f.get(e.blocker)}f.setStyle(c,\"left\",e.getStyle(\"left\",1));f.setStyle(c,\"top\",e.getStyle(\"top\",1));f.setStyle(c,\"width\",e.getStyle(\"width\",1));f.setStyle(c,\"height\",e.getStyle(\"height\",1));f.setStyle(c,\"display\",e.getStyle(\"display\",1));f.setStyle(c,\"zIndex\",parseInt(e.getStyle(\"zIndex\",1)||0)-1)}}})})(tinymce);(function(c){function e(f){return f.replace(/[\\n\\r]+/g,\"\")}var b=c.is,a=c.isIE,d=c.each;c.create(\"tinymce.dom.Selection\",{Selection:function(i,h,g){var f=this;f.dom=i;f.win=h;f.serializer=g;d([\"onBeforeSetContent\",\"onBeforeGetContent\",\"onSetContent\",\"onGetContent\"],function(j){f[j]=new c.util.Dispatcher(f)});if(!f.win.getSelection){f.tridentSel=new c.dom.TridentSelection(f)}c.addUnload(f.destroy,f)},getContent:function(g){var f=this,h=f.getRng(),l=f.dom.create(\"body\"),j=f.getSel(),i,k,m;g=g||{};i=k=\"\";g.get=true;g.format=g.format||\"html\";f.onBeforeGetContent.dispatch(f,g);if(g.format==\"text\"){return f.isCollapsed()?\"\":(h.text||(j.toString?j.toString():\"\"))}if(h.cloneContents){m=h.cloneContents();if(m){l.appendChild(m)}}else{if(b(h.item)||b(h.htmlText)){l.innerHTML=h.item?h.item(0).outerHTML:h.htmlText}else{l.innerHTML=h.toString()}}if(/^\\s/.test(l.innerHTML)){i=\" \"}if(/\\s+$/.test(l.innerHTML)){k=\" \"}g.getInner=true;g.content=f.isCollapsed()?\"\":i+f.serializer.serialize(l,g)+k;f.onGetContent.dispatch(f,g);return g.content},setContent:function(i,g){var f=this,j=f.getRng(),l,k=f.win.document;g=g||{format:\"html\"};g.set=true;i=g.content=f.dom.processHTML(i);f.onBeforeSetContent.dispatch(f,g);i=g.content;if(j.insertNode){i+='<span id=\"__caret\">_</span>';j.deleteContents();j.insertNode(f.getRng().createContextualFragment(i));l=f.dom.get(\"__caret\");j=k.createRange();j.setStartBefore(l);j.setEndAfter(l);f.setRng(j);f.dom.remove(\"__caret\")}else{if(j.item){k.execCommand(\"Delete\",false,null);j=f.getRng()}j.pasteHTML(i)}f.onSetContent.dispatch(f,g)},getStart:function(){var f=this,g=f.getRng(),h;if(a){if(g.item){return g.item(0)}g=g.duplicate();g.collapse(1);h=g.parentElement();if(h&&h.nodeName==\"BODY\"){return h.firstChild}return h}else{h=g.startContainer;if(h.nodeName==\"BODY\"){return h.firstChild}return f.dom.getParent(h,\"*\")}},getEnd:function(){var f=this,g=f.getRng(),h;if(a){if(g.item){return g.item(0)}g=g.duplicate();g.collapse(0);h=g.parentElement();if(h&&h.nodeName==\"BODY\"){return h.lastChild}return h}else{h=g.endContainer;if(h.nodeName==\"BODY\"){return h.lastChild}return f.dom.getParent(h,\"*\")}},getBookmark:function(x){var j=this,m=j.getRng(),f,n,l,u=j.dom.getViewPort(j.win),v,p,z,o,w=-16777215,k,h=j.dom.getRoot(),g=0,i=0,y;n=u.x;l=u.y;if(x){return{rng:m,scrollX:n,scrollY:l}}if(a){if(m.item){v=m.item(0);d(j.dom.select(v.nodeName),function(s,r){if(v==s){p=r;return false}});return{tag:v.nodeName,index:p,scrollX:n,scrollY:l}}f=j.dom.doc.body.createTextRange();f.moveToElementText(h);f.collapse(true);z=Math.abs(f.move(\"character\",w));f=m.duplicate();f.collapse(true);p=Math.abs(f.move(\"character\",w));f=m.duplicate();f.collapse(false);o=Math.abs(f.move(\"character\",w))-p;return{start:p-z,length:o,scrollX:n,scrollY:l}}v=j.getNode();k=j.getSel();if(!k){return null}if(v&&v.nodeName==\"IMG\"){return{scrollX:n,scrollY:l}}function q(A,D,t){var s=j.dom.doc.createTreeWalker(A,NodeFilter.SHOW_TEXT,null,false),E,B=0,C={};while((E=s.nextNode())!=null){if(E==D){C.start=B}if(E==t){C.end=B;return C}B+=e(E.nodeValue||\"\").length}return null}if(k.anchorNode==k.focusNode&&k.anchorOffset==k.focusOffset){v=q(h,k.anchorNode,k.focusNode);if(!v){return{scrollX:n,scrollY:l}}e(k.anchorNode.nodeValue||\"\").replace(/^\\s+/,function(r){g=r.length});return{start:Math.max(v.start+k.anchorOffset-g,0),end:Math.max(v.end+k.focusOffset-g,0),scrollX:n,scrollY:l,beg:k.anchorOffset-g==0}}else{v=q(h,m.startContainer,m.endContainer);if(!v){return{scrollX:n,scrollY:l}}return{start:Math.max(v.start+m.startOffset-g,0),end:Math.max(v.end+m.endOffset-i,0),scrollX:n,scrollY:l,beg:m.startOffset-g==0}}},moveToBookmark:function(n){var o=this,g=o.getRng(),p=o.getSel(),j=o.dom.getRoot(),m,h,k;function i(q,t,D){var B=o.dom.doc.createTreeWalker(q,NodeFilter.SHOW_TEXT,null,false),x,s=0,A={},u,C,z,y;while((x=B.nextNode())!=null){z=y=0;k=x.nodeValue||\"\";h=e(k).length;s+=h;if(s>=t&&!A.startNode){u=t-(s-h);if(n.beg&&u>=h){continue}A.startNode=x;A.startOffset=u+y}if(s>=D){A.endNode=x;A.endOffset=D-(s-h)+y;return A}}return null}if(!n){return false}o.win.scrollTo(n.scrollX,n.scrollY);if(a){o.tridentSel.destroy();if(g=n.rng){try{g.select()}catch(l){}return true}o.win.focus();if(n.tag){g=j.createControlRange();d(o.dom.select(n.tag),function(r,q){if(q==n.index){g.addElement(r)}})}else{try{if(n.start<0){return true}g=p.createRange();g.moveToElementText(j);g.collapse(true);g.moveStart(\"character\",n.start);g.moveEnd(\"character\",n.length)}catch(f){return true}}try{g.select()}catch(l){}return true}if(!p){return false}if(n.rng){p.removeAllRanges();p.addRange(n.rng)}else{if(b(n.start)&&b(n.end)){try{m=i(j,n.start,n.end);if(m){g=o.dom.doc.createRange();g.setStart(m.startNode,m.startOffset);g.setEnd(m.endNode,m.endOffset);p.removeAllRanges();p.addRange(g)}if(!c.isOpera){o.win.focus()}}catch(l){}}}},select:function(g,l){var p=this,f=p.getRng(),q=p.getSel(),o,m,k,j=p.win.document;function h(u,t){var s,r;if(u){s=j.createTreeWalker(u,NodeFilter.SHOW_TEXT,null,false);while(u=s.nextNode()){r=u;if(c.trim(u.nodeValue).length!=0){if(t){return u}else{r=u}}}}return r}if(a){try{o=j.body;if(/^(IMG|TABLE)$/.test(g.nodeName)){f=o.createControlRange();f.addElement(g)}else{f=o.createTextRange();f.moveToElementText(g)}f.select()}catch(i){}}else{if(l){m=h(g,1)||p.dom.select(\"br:first\",g)[0];k=h(g,0)||p.dom.select(\"br:last\",g)[0];if(m&&k){f=j.createRange();if(m.nodeName==\"BR\"){f.setStartBefore(m)}else{f.setStart(m,0)}if(k.nodeName==\"BR\"){f.setEndBefore(k)}else{f.setEnd(k,k.nodeValue.length)}}else{f.selectNode(g)}}else{f.selectNode(g)}p.setRng(f)}return g},isCollapsed:function(){var f=this,h=f.getRng(),g=f.getSel();if(!h||h.item){return false}return !g||h.boundingWidth==0||h.collapsed},collapse:function(f){var g=this,h=g.getRng(),i;if(h.item){i=h.item(0);h=this.win.document.body.createTextRange();h.moveToElementText(i)}h.collapse(!!f);g.setRng(h)},getSel:function(){var g=this,f=this.win;return f.getSelection?f.getSelection():f.document.selection},getRng:function(j){var g=this,h,i;if(j&&g.tridentSel){return g.tridentSel.getRangeAt(0)}try{if(h=g.getSel()){i=h.rangeCount>0?h.getRangeAt(0):(h.createRange?h.createRange():g.win.document.createRange())}}catch(f){}if(!i){i=a?g.win.document.body.createTextRange():g.win.document.createRange()}return i},setRng:function(i){var h,g=this;if(!g.tridentSel){h=g.getSel();if(h){h.removeAllRanges();h.addRange(i)}}else{if(i.cloneRange){g.tridentSel.addRange(i);return}try{i.select()}catch(f){}}},setNode:function(g){var f=this;f.setContent(f.dom.getOuterHTML(g));return g},getNode:function(){var f=this,h=f.getRng(),g=f.getSel(),i;if(!a){if(!h){return f.dom.getRoot()}i=h.commonAncestorContainer;if(!h.collapsed){if(c.isWebKit&&g.anchorNode&&g.anchorNode.nodeType==1){return g.anchorNode.childNodes[g.anchorOffset]}if(h.startContainer==h.endContainer){if(h.startOffset-h.endOffset<2){if(h.startContainer.hasChildNodes()){i=h.startContainer.childNodes[h.startOffset]}}}}return f.dom.getParent(i,\"*\")}return h.item?h.item(0):h.parentElement()},getSelectedBlocks:function(g,f){var i=this,j=i.dom,m,h,l,k=[];m=j.getParent(g||i.getStart(),j.isBlock);h=j.getParent(f||i.getEnd(),j.isBlock);if(m){k.push(m)}if(m&&h&&m!=h){l=m;while((l=l.nextSibling)&&l!=h){if(j.isBlock(l)){k.push(l)}}}if(h&&m!=h){k.push(h)}return k},destroy:function(g){var f=this;f.win=null;if(f.tridentSel){f.tridentSel.destroy()}if(!g){c.removeUnload(f.destroy)}}})})(tinymce);(function(a){a.create(\"tinymce.dom.XMLWriter\",{node:null,XMLWriter:function(c){function b(){var e=document.implementation;if(!e||!e.createDocument){try{return new ActiveXObject(\"MSXML2.DOMDocument\")}catch(d){}try{return new ActiveXObject(\"Microsoft.XmlDom\")}catch(d){}}else{return e.createDocument(\"\",\"\",null)}}this.doc=b();this.valid=a.isOpera||a.isWebKit;this.reset()},reset:function(){var b=this,c=b.doc;if(c.firstChild){c.removeChild(c.firstChild)}b.node=c.appendChild(c.createElement(\"html\"))},writeStartElement:function(c){var b=this;b.node=b.node.appendChild(b.doc.createElement(c))},writeAttribute:function(c,b){if(this.valid){b=b.replace(/>/g,\"%MCGT%\")}this.node.setAttribute(c,b)},writeEndElement:function(){this.node=this.node.parentNode},writeFullEndElement:function(){var b=this,c=b.node;c.appendChild(b.doc.createTextNode(\"\"));b.node=c.parentNode},writeText:function(b){if(this.valid){b=b.replace(/>/g,\"%MCGT%\")}this.node.appendChild(this.doc.createTextNode(b))},writeCDATA:function(b){this.node.appendChild(this.doc.createCDATASection(b))},writeComment:function(b){if(a.isIE){b=b.replace(/^\\-|\\-$/g,\" \")}this.node.appendChild(this.doc.createComment(b.replace(/\\-\\-/g,\" \")))},getContent:function(){var b;b=this.doc.xml||new XMLSerializer().serializeToString(this.doc);b=b.replace(/<\\?[^?]+\\?>|<html>|<\\/html>|<html\\/>|<!DOCTYPE[^>]+>/g,\"\");b=b.replace(/ ?\\/>/g,\" />\");if(this.valid){b=b.replace(/\\%MCGT%/g,\"&gt;\")}return b}})})(tinymce);(function(a){a.create(\"tinymce.dom.StringWriter\",{str:null,tags:null,count:0,settings:null,indent:null,StringWriter:function(b){this.settings=a.extend({indent_char:\" \",indentation:0},b);this.reset()},reset:function(){this.indent=\"\";this.str=\"\";this.tags=[];this.count=0},writeStartElement:function(b){this._writeAttributesEnd();this.writeRaw(\"<\"+b);this.tags.push(b);this.inAttr=true;this.count++;this.elementCount=this.count},writeAttribute:function(d,b){var c=this;c.writeRaw(\" \"+c.encode(d)+'=\"'+c.encode(b)+'\"')},writeEndElement:function(){var b;if(this.tags.length>0){b=this.tags.pop();if(this._writeAttributesEnd(1)){this.writeRaw(\"</\"+b+\">\")}if(this.settings.indentation>0){this.writeRaw(\"\\n\")}}},writeFullEndElement:function(){if(this.tags.length>0){this._writeAttributesEnd();this.writeRaw(\"</\"+this.tags.pop()+\">\");if(this.settings.indentation>0){this.writeRaw(\"\\n\")}}},writeText:function(b){this._writeAttributesEnd();this.writeRaw(this.encode(b));this.count++},writeCDATA:function(b){this._writeAttributesEnd();this.writeRaw(\"<![CDATA[\"+b+\"]]>\");this.count++},writeComment:function(b){this._writeAttributesEnd();this.writeRaw(\"<!-- \"+b+\"-->\");this.count++},writeRaw:function(b){this.str+=b},encode:function(b){return b.replace(/[<>&\"]/g,function(c){switch(c){case\"<\":return\"&lt;\";case\">\":return\"&gt;\";case\"&\":return\"&amp;\";case'\"':return\"&quot;\"}return c})},getContent:function(){return this.str},_writeAttributesEnd:function(b){if(!this.inAttr){return}this.inAttr=false;if(b&&this.elementCount==this.count){this.writeRaw(\" />\");return false}this.writeRaw(\">\");return true}})})(tinymce);(function(e){var g=e.extend,f=e.each,b=e.util.Dispatcher,d=e.isIE,a=e.isGecko;function c(h){return h.replace(/([?+*])/g,\".$1\")}e.create(\"tinymce.dom.Serializer\",{Serializer:function(j){var i=this;i.key=0;i.onPreProcess=new b(i);i.onPostProcess=new b(i);try{i.writer=new e.dom.XMLWriter()}catch(h){i.writer=new e.dom.StringWriter()}i.settings=j=g({dom:e.DOM,valid_nodes:0,node_filter:0,attr_filter:0,invalid_attrs:/^(mce_|_moz_|sizset|sizcache)/,closed:/^(br|hr|input|meta|img|link|param|area)$/,entity_encoding:\"named\",entities:\"160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro\",valid_elements:\"*[*]\",extended_valid_elements:0,valid_child_elements:0,invalid_elements:0,fix_table_elements:1,fix_list_elements:true,fix_content_duplication:true,convert_fonts_to_spans:false,font_size_classes:0,font_size_style_values:0,apply_source_formatting:0,indent_mode:\"simple\",indent_char:\"\\t\",indent_levels:1,remove_linebreaks:1,remove_redundant_brs:1,element_format:\"xhtml\"},j);i.dom=j.dom;if(j.remove_redundant_brs){i.onPostProcess.add(function(k,l){l.content=l.content.replace(/(<br \\/>\\s*)+<\\/(p|h[1-6]|div|li)>/gi,function(n,m,o){if(/^<br \\/>\\s*<\\//.test(n)){return\"</\"+o+\">\"}return n})})}if(j.element_format==\"html\"){i.onPostProcess.add(function(k,l){l.content=l.content.replace(/<([^>]+) \\/>/g,\"<$1>\")})}if(j.fix_list_elements){i.onPreProcess.add(function(v,s){var l,y,w=[\"ol\",\"ul\"],u,t,q,k=/^(OL|UL)$/,z;function m(r,x){var o=x.split(\",\"),p;while((r=r.previousSibling)!=null){for(p=0;p<o.length;p++){if(r.nodeName==o[p]){return r}}}return null}for(y=0;y<w.length;y++){l=i.dom.select(w[y],s.node);for(u=0;u<l.length;u++){t=l[u];q=t.parentNode;if(k.test(q.nodeName)){z=m(t,\"LI\");if(!z){z=i.dom.create(\"li\");z.innerHTML=\"&nbsp;\";z.appendChild(t);q.insertBefore(z,q.firstChild)}else{z.appendChild(t)}}}}})}if(j.fix_table_elements){i.onPreProcess.add(function(k,l){if(!e.isOpera||opera.buildNumber()>=1767){f(i.dom.select(\"p table\",l.node).reverse(),function(p){var o=i.dom.getParent(p.parentNode,\"table,p\");if(o.nodeName!=\"TABLE\"){try{i.dom.split(o,p)}catch(m){}}})}})}},setEntities:function(p){var n=this,j,m,h={},o=\"\",k;if(n.entityLookup){return}j=p.split(\",\");for(m=0;m<j.length;m+=2){k=j[m];if(k==34||k==38||k==60||k==62){continue}h[String.fromCharCode(j[m])]=j[m+1];k=parseInt(j[m]).toString(16);o+=\"\\\\u\"+\"0000\".substring(k.length)+k}if(!o){n.settings.entity_encoding=\"raw\";return}n.entitiesRE=new RegExp(\"[\"+o+\"]\",\"g\");n.entityLookup=h},setValidChildRules:function(h){this.childRules=null;this.addValidChildRules(h)},addValidChildRules:function(k){var j=this,l,h,i;if(!k){return}l=\"A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment\";h=\"A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment\";i=\"H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP\";f(k.split(\",\"),function(n){var o=n.split(/\\[|\\]/),m;n=\"\";f(o[1].split(\"|\"),function(p){if(n){n+=\"|\"}switch(p){case\"%itrans\":p=h;break;case\"%itrans_na\":p=h.substring(2);break;case\"%istrict\":p=l;break;case\"%istrict_na\":p=l.substring(2);break;case\"%btrans\":p=i;break;case\"%bstrict\":p=i;break}n+=p});m=new RegExp(\"^(\"+n.toLowerCase()+\")$\",\"i\");f(o[0].split(\"/\"),function(p){j.childRules=j.childRules||{};j.childRules[p]=m})});k=\"\";f(j.childRules,function(n,m){if(k){k+=\"|\"}k+=m});j.parentElementsRE=new RegExp(\"^(\"+k.toLowerCase()+\")$\",\"i\")},setRules:function(i){var h=this;h._setup();h.rules={};h.wildRules=[];h.validElements={};return h.addRules(i)},addRules:function(i){var h=this,j;if(!i){return}h._setup();f(i.split(\",\"),function(m){var q=m.split(/\\[|\\]/),l=q[0].split(\"/\"),r,k,o,n=[];if(j){k=e.extend([],j.attribs)}if(q.length>1){f(q[1].split(\"|\"),function(u){var p={},t;k=k||[];u=u.replace(/::/g,\"~\");u=/^([!\\-])?([\\w*.?~_\\-]+|)([=:<])?(.+)?$/.exec(u);u[2]=u[2].replace(/~/g,\":\");if(u[1]==\"!\"){r=r||[];r.push(u[2])}if(u[1]==\"-\"){for(t=0;t<k.length;t++){if(k[t].name==u[2]){k.splice(t,1);return}}}switch(u[3]){case\"=\":p.defaultVal=u[4]||\"\";break;case\":\":p.forcedVal=u[4];break;case\"<\":p.validVals=u[4].split(\"?\");break}if(/[*.?]/.test(u[2])){o=o||[];p.nameRE=new RegExp(\"^\"+c(u[2])+\"$\");o.push(p)}else{p.name=u[2];k.push(p)}n.push(u[2])})}f(l,function(v,u){var w=v.charAt(0),t=1,p={};if(j){if(j.noEmpty){p.noEmpty=j.noEmpty}if(j.fullEnd){p.fullEnd=j.fullEnd}if(j.padd){p.padd=j.padd}}switch(w){case\"-\":p.noEmpty=true;break;case\"+\":p.fullEnd=true;break;case\"#\":p.padd=true;break;default:t=0}l[u]=v=v.substring(t);h.validElements[v]=1;if(/[*.?]/.test(l[0])){p.nameRE=new RegExp(\"^\"+c(l[0])+\"$\");h.wildRules=h.wildRules||{};h.wildRules.push(p)}else{p.name=l[0];if(l[0]==\"@\"){j=p}h.rules[v]=p}p.attribs=k;if(r){p.requiredAttribs=r}if(o){v=\"\";f(n,function(s){if(v){v+=\"|\"}v+=\"(\"+c(s)+\")\"});p.validAttribsRE=new RegExp(\"^\"+v.toLowerCase()+\"$\");p.wildAttribs=o}})});i=\"\";f(h.validElements,function(m,l){if(i){i+=\"|\"}if(l!=\"@\"){i+=l}});h.validElementsRE=new RegExp(\"^(\"+c(i.toLowerCase())+\")$\")},findRule:function(m){var j=this,l=j.rules,h,k;j._setup();k=l[m];if(k){return k}l=j.wildRules;for(h=0;h<l.length;h++){if(l[h].nameRE.test(m)){return l[h]}}return null},findAttribRule:function(h,l){var j,k=h.wildAttribs;for(j=0;j<k.length;j++){if(k[j].nameRE.test(l)){return k[j]}}return null},serialize:function(r,q){var m,k=this,p,i,j,l;k._setup();q=q||{};q.format=q.format||\"html\";k.processObj=q;if(d){l=[];f(r.getElementsByTagName(\"option\"),function(o){var h=k.dom.getAttrib(o,\"selected\");l.push(h?h:null)})}r=r.cloneNode(true);if(d){f(r.getElementsByTagName(\"option\"),function(o,h){k.dom.setAttrib(o,\"selected\",l[h])})}j=r.ownerDocument.implementation;if(j.createHTMLDocument&&(e.isOpera&&opera.buildNumber()>=1767)){p=j.createHTMLDocument(\"\");f(r.nodeName==\"BODY\"?r.childNodes:[r],function(h){p.body.appendChild(p.importNode(h,true))});if(r.nodeName!=\"BODY\"){r=p.body.firstChild}else{r=p.body}i=k.dom.doc;k.dom.doc=p}k.key=\"\"+(parseInt(k.key)+1);if(!q.no_events){q.node=r;k.onPreProcess.dispatch(k,q)}k.writer.reset();k._serializeNode(r,q.getInner);q.content=k.writer.getContent();if(i){k.dom.doc=i}if(!q.no_events){k.onPostProcess.dispatch(k,q)}k._postProcess(q);q.node=null;return e.trim(q.content)},_postProcess:function(n){var i=this,k=i.settings,j=n.content,m=[],l;if(n.format==\"html\"){l=i._protect({content:j,patterns:[{pattern:/(<script[^>]*>)(.*?)(<\\/script>)/g},{pattern:/(<noscript[^>]*>)(.*?)(<\\/noscript>)/g},{pattern:/(<style[^>]*>)(.*?)(<\\/style>)/g},{pattern:/(<pre[^>]*>)(.*?)(<\\/pre>)/g,encode:1},{pattern:/(<!--\\[CDATA\\[)(.*?)(\\]\\]-->)/g}]});j=l.content;if(k.entity_encoding!==\"raw\"){j=i._encode(j)}if(!n.set){j=j.replace(/<p>\\s+<\\/p>|<p([^>]+)>\\s+<\\/p>/g,k.entity_encoding==\"numeric\"?\"<p$1>&#160;</p>\":\"<p$1>&nbsp;</p>\");if(k.remove_linebreaks){j=j.replace(/\\r?\\n|\\r/g,\" \");j=j.replace(/(<[^>]+>)\\s+/g,\"$1 \");j=j.replace(/\\s+(<\\/[^>]+>)/g,\" $1\");j=j.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\\s+/g,\"<$1 $2>\");j=j.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\\s+/g,\"<$1>\");j=j.replace(/\\s+<\\/(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g,\"</$1>\")}if(k.apply_source_formatting&&k.indent_mode==\"simple\"){j=j.replace(/<(\\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\\s*/g,\"\\n<$1$2$3>\\n\");j=j.replace(/\\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g,\"\\n<$1$2>\");j=j.replace(/<\\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\\s*/g,\"</$1>\\n\");j=j.replace(/\\n\\n/g,\"\\n\")}}j=i._unprotect(j,l);j=j.replace(/<!--\\[CDATA\\[([\\s\\S]+)\\]\\]-->/g,\"<![CDATA[$1]]>\");if(k.entity_encoding==\"raw\"){j=j.replace(/<p>&nbsp;<\\/p>|<p([^>]+)>&nbsp;<\\/p>/g,\"<p$1>\\u00a0</p>\")}j=j.replace(/<noscript([^>]+|)>([\\s\\S]*?)<\\/noscript>/g,function(h,p,o){return\"<noscript\"+p+\">\"+i.dom.decode(o.replace(/<!--|-->/g,\"\"))+\"</noscript>\"})}n.content=j},_serializeNode:function(D,o){var z=this,A=z.settings,x=z.writer,q,j,u,F,E,G,B,h,y,k,r,C,p,m;if(!A.node_filter||A.node_filter(D)){switch(D.nodeType){case 1:if(D.hasAttribute?D.hasAttribute(\"mce_bogus\"):D.getAttribute(\"mce_bogus\")){return}p=false;q=D.hasChildNodes();k=D.getAttribute(\"mce_name\")||D.nodeName.toLowerCase();if(d){if(D.scopeName!==\"HTML\"&&D.scopeName!==\"html\"){k=D.scopeName+\":\"+k}}if(k.indexOf(\"mce:\")===0){k=k.substring(4)}if(!z.validElementsRE||!z.validElementsRE.test(k)||(z.invalidElementsRE&&z.invalidElementsRE.test(k))||o){p=true;break}if(d){if(A.fix_content_duplication){if(D.mce_serialized==z.key){return}D.mce_serialized=z.key}if(k.charAt(0)==\"/\"){k=k.substring(1)}}else{if(a){if(D.nodeName===\"BR\"&&D.getAttribute(\"type\")==\"_moz\"){return}}}if(z.childRules){if(z.parentElementsRE.test(z.elementName)){if(!z.childRules[z.elementName].test(k)){p=true;break}}z.elementName=k}r=z.findRule(k);k=r.name||k;m=A.closed.test(k);if((!q&&r.noEmpty)||(d&&!k)){p=true;break}if(r.requiredAttribs){G=r.requiredAttribs;for(F=G.length-1;F>=0;F--){if(this.dom.getAttrib(D,G[F])!==\"\"){break}}if(F==-1){p=true;break}}x.writeStartElement(k);if(r.attribs){for(F=0,B=r.attribs,E=B.length;F<E;F++){G=B[F];y=z._getAttrib(D,G);if(y!==null){x.writeAttribute(G.name,y)}}}if(r.validAttribsRE){B=z.dom.getAttribs(D);for(F=B.length-1;F>-1;F--){h=B[F];if(h.specified){G=h.nodeName.toLowerCase();if(A.invalid_attrs.test(G)||!r.validAttribsRE.test(G)){continue}C=z.findAttribRule(r,G);y=z._getAttrib(D,C,G);if(y!==null){x.writeAttribute(G,y)}}}}if(k===\"script\"&&e.trim(D.innerHTML)){x.writeText(\"// \");x.writeCDATA(D.innerHTML.replace(/<!--|-->|<\\[CDATA\\[|\\]\\]>/g,\"\"));q=false;break}if(r.padd){if(q&&(u=D.firstChild)&&u.nodeType===1&&D.childNodes.length===1){if(u.hasAttribute?u.hasAttribute(\"mce_bogus\"):u.getAttribute(\"mce_bogus\")){x.writeText(\"\\u00a0\")}}else{if(!q){x.writeText(\"\\u00a0\")}}}break;case 3:if(z.childRules&&z.parentElementsRE.test(z.elementName)){if(!z.childRules[z.elementName].test(D.nodeName)){return}}return x.writeText(D.nodeValue);case 4:return x.writeCDATA(D.nodeValue);case 8:return x.writeComment(D.nodeValue)}}else{if(D.nodeType==1){q=D.hasChildNodes()}}if(q&&!m){u=D.firstChild;while(u){z._serializeNode(u);z.elementName=k;u=u.nextSibling}}if(!p){if(!m){x.writeFullEndElement()}else{x.writeEndElement()}}},_protect:function(j){var i=this;j.items=j.items||[];function h(l){return l.replace(/[\\r\\n\\\\]/g,function(m){if(m===\"\\n\"){return\"\\\\n\"}else{if(m===\"\\\\\"){return\"\\\\\\\\\"}}return\"\\\\r\"})}function k(l){return l.replace(/\\\\[\\\\rn]/g,function(m){if(m===\"\\\\n\"){return\"\\n\"}else{if(m===\"\\\\\\\\\"){return\"\\\\\"}}return\"\\r\"})}f(j.patterns,function(l){j.content=k(h(j.content).replace(l.pattern,function(n,o,m,p){m=k(m);if(l.encode){m=i._encode(m)}j.items.push(m);return o+\"<!--mce:\"+(j.items.length-1)+\"-->\"+p}))});return j},_unprotect:function(i,j){i=i.replace(/\\<!--mce:([0-9]+)--\\>/g,function(k,h){return j.items[parseInt(h)]});j.items=[];return i},_encode:function(m){var j=this,k=j.settings,i;if(k.entity_encoding!==\"raw\"){if(k.entity_encoding.indexOf(\"named\")!=-1){j.setEntities(k.entities);i=j.entityLookup;m=m.replace(j.entitiesRE,function(h){var l;if(l=i[h]){h=\"&\"+l+\";\"}return h})}if(k.entity_encoding.indexOf(\"numeric\")!=-1){m=m.replace(/[\\u007E-\\uFFFF]/g,function(h){return\"&#\"+h.charCodeAt(0)+\";\"})}}return m},_setup:function(){var h=this,i=this.settings;if(h.done){return}h.done=1;h.setRules(i.valid_elements);h.addRules(i.extended_valid_elements);h.addValidChildRules(i.valid_child_elements);if(i.invalid_elements){h.invalidElementsRE=new RegExp(\"^(\"+c(i.invalid_elements.replace(/,/g,\"|\").toLowerCase())+\")$\")}if(i.attrib_value_filter){h.attribValueFilter=i.attribValueFilter}},_getAttrib:function(m,j,h){var l,k;h=h||j.name;if(j.forcedVal&&(k=j.forcedVal)){if(k===\"{$uid}\"){return this.dom.uniqueId()}return k}k=this.dom.getAttrib(m,h);switch(h){case\"rowspan\":case\"colspan\":if(k==\"1\"){k=\"\"}break}if(this.attribValueFilter){k=this.attribValueFilter(h,k,m)}if(j.validVals){for(l=j.validVals.length-1;l>=0;l--){if(k==j.validVals[l]){break}}if(l==-1){return null}}if(k===\"\"&&typeof(j.defaultVal)!=\"undefined\"){k=j.defaultVal;if(k===\"{$uid}\"){return this.dom.uniqueId()}return k}else{if(h==\"class\"&&this.processObj.get){k=k.replace(/\\s?mceItem\\w+\\s?/g,\"\")}}if(k===\"\"){return null}return k}})})(tinymce);(function(tinymce){var each=tinymce.each,Event=tinymce.dom.Event;tinymce.create(\"tinymce.dom.ScriptLoader\",{ScriptLoader:function(s){this.settings=s||{};this.queue=[];this.lookup={}},isDone:function(u){return this.lookup[u]?this.lookup[u].state==2:0},markDone:function(u){this.lookup[u]={state:2,url:u}},add:function(u,cb,s,pr){var t=this,lo=t.lookup,o;if(o=lo[u]){if(cb&&o.state==2){cb.call(s||this)}return o}o={state:0,url:u,func:cb,scope:s||this};if(pr){t.queue.unshift(o)}else{t.queue.push(o)}lo[u]=o;return o},load:function(u,cb,s){var t=this,o;if(o=t.lookup[u]){if(cb&&o.state==2){cb.call(s||t)}return o}function loadScript(u){if(Event.domLoaded||t.settings.strict_mode){tinymce.util.XHR.send({url:tinymce._addVer(u),error:t.settings.error,async:false,success:function(co){t.eval(co)}})}else{document.write('<script type=\"text/javascript\" src=\"'+tinymce._addVer(u)+'\"><\\/script>')}}if(!tinymce.is(u,\"string\")){each(u,function(u){loadScript(u)});if(cb){cb.call(s||t)}}else{loadScript(u);if(cb){cb.call(s||t)}}},loadQueue:function(cb,s){var t=this;if(!t.queueLoading){t.queueLoading=1;t.queueCallbacks=[];t.loadScripts(t.queue,function(){t.queueLoading=0;if(cb){cb.call(s||t)}each(t.queueCallbacks,function(o){o.func.call(o.scope)})})}else{if(cb){t.queueCallbacks.push({func:cb,scope:s||t})}}},eval:function(co){var w=window;if(!w.execScript){try{eval.call(w,co)}catch(ex){eval(co,w)}}else{w.execScript(co)}},loadScripts:function(sc,cb,s){var t=this,lo=t.lookup;function done(o){o.state=2;if(o.func){o.func.call(o.scope||t)}}function allDone(){var l;l=sc.length;each(sc,function(o){o=lo[o.url];if(o.state===2){done(o);l--}else{load(o)}});if(l===0&&cb){cb.call(s||t);cb=0}}function load(o){if(o.state>0){return}o.state=1;tinymce.dom.ScriptLoader.loadScript(o.url,function(){done(o);allDone()})}each(sc,function(o){var u=o.url;if(!lo[u]){lo[u]=o;t.queue.push(o)}else{o=lo[u]}if(o.state>0){return}if(!Event.domLoaded&&!t.settings.strict_mode){var ix,ol=\"\";if(cb||o.func){o.state=1;ix=tinymce.dom.ScriptLoader._addOnLoad(function(){done(o);allDone()});if(tinymce.isIE){ol=' onreadystatechange=\"'}else{ol=' onload=\"'}ol+=\"tinymce.dom.ScriptLoader._onLoad(this,'\"+u+\"',\"+ix+');\"'}document.write('<script type=\"text/javascript\" src=\"'+tinymce._addVer(u)+'\"'+ol+\"><\\/script>\");if(!o.func){done(o)}}else{load(o)}});allDone()},\"static\":{_addOnLoad:function(f){var t=this;t._funcs=t._funcs||[];t._funcs.push(f);return t._funcs.length-1},_onLoad:function(e,u,ix){if(!tinymce.isIE||e.readyState==\"complete\"){this._funcs[ix].call(this)}},loadScript:function(u,cb){var id=tinymce.DOM.uniqueId(),e;function done(){Event.clear(id);tinymce.DOM.remove(id);if(cb){cb.call(document,u);cb=0}}if(tinymce.isIE){tinymce.util.XHR.send({url:tinymce._addVer(u),async:false,success:function(co){window.execScript(co);done()}})}else{e=tinymce.DOM.create(\"script\",{id:id,type:\"text/javascript\",src:tinymce._addVer(u)});Event.add(e,\"load\",done);(document.getElementsByTagName(\"head\")[0]||document.body).appendChild(e)}}}});tinymce.ScriptLoader=new tinymce.dom.ScriptLoader()})(tinymce);(function(c){var b=c.DOM,a=c.is;c.create(\"tinymce.ui.Control\",{Control:function(e,d){this.id=e;this.settings=d=d||{};this.rendered=false;this.onRender=new c.util.Dispatcher(this);this.classPrefix=\"\";this.scope=d.scope||this;this.disabled=0;this.active=0},setDisabled:function(d){var f;if(d!=this.disabled){f=b.get(this.id);if(f&&this.settings.unavailable_prefix){if(d){this.prevTitle=f.title;f.title=this.settings.unavailable_prefix+\": \"+f.title}else{f.title=this.prevTitle}}this.setState(\"Disabled\",d);this.setState(\"Enabled\",!d);this.disabled=d}},isDisabled:function(){return this.disabled},setActive:function(d){if(d!=this.active){this.setState(\"Active\",d);this.active=d}},isActive:function(){return this.active},setState:function(f,d){var e=b.get(this.id);f=this.classPrefix+f;if(d){b.addClass(e,f)}else{b.removeClass(e,f)}},isRendered:function(){return this.rendered},renderHTML:function(){},renderTo:function(d){b.setHTML(d,this.renderHTML())},postRender:function(){var e=this,d;if(a(e.disabled)){d=e.disabled;e.disabled=-1;e.setDisabled(d)}if(a(e.active)){d=e.active;e.active=-1;e.setActive(d)}},remove:function(){b.remove(this.id);this.destroy()},destroy:function(){c.dom.Event.clear(this.id)}})})(tinymce);tinymce.create(\"tinymce.ui.Container:tinymce.ui.Control\",{Container:function(b,a){this.parent(b,a);this.controls=[];this.lookup={}},add:function(a){this.lookup[a.id]=a;this.controls.push(a);return a},get:function(a){return this.lookup[a]}});tinymce.create(\"tinymce.ui.Separator:tinymce.ui.Control\",{Separator:function(b,a){this.parent(b,a);this.classPrefix=\"mceSeparator\"},renderHTML:function(){return tinymce.DOM.createHTML(\"span\",{\"class\":this.classPrefix})}});(function(d){var c=d.is,b=d.DOM,e=d.each,a=d.walk;d.create(\"tinymce.ui.MenuItem:tinymce.ui.Control\",{MenuItem:function(g,f){this.parent(g,f);this.classPrefix=\"mceMenuItem\"},setSelected:function(f){this.setState(\"Selected\",f);this.selected=f},isSelected:function(){return this.selected},postRender:function(){var f=this;f.parent();if(c(f.selected)){f.setSelected(f.selected)}}})})(tinymce);(function(d){var c=d.is,b=d.DOM,e=d.each,a=d.walk;d.create(\"tinymce.ui.Menu:tinymce.ui.MenuItem\",{Menu:function(h,g){var f=this;f.parent(h,g);f.items={};f.collapsed=false;f.menuCount=0;f.onAddItem=new d.util.Dispatcher(this)},expand:function(g){var f=this;if(g){a(f,function(h){if(h.expand){h.expand()}},\"items\",f)}f.collapsed=false},collapse:function(g){var f=this;if(g){a(f,function(h){if(h.collapse){h.collapse()}},\"items\",f)}f.collapsed=true},isCollapsed:function(){return this.collapsed},add:function(f){if(!f.settings){f=new d.ui.MenuItem(f.id||b.uniqueId(),f)}this.onAddItem.dispatch(this,f);return this.items[f.id]=f},addSeparator:function(){return this.add({separator:true})},addMenu:function(f){if(!f.collapse){f=this.createMenu(f)}this.menuCount++;return this.add(f)},hasMenus:function(){return this.menuCount!==0},remove:function(f){delete this.items[f.id]},removeAll:function(){var f=this;a(f,function(g){if(g.removeAll){g.removeAll()}else{g.remove()}g.destroy()},\"items\",f);f.items={}},createMenu:function(g){var f=new d.ui.Menu(g.id||b.uniqueId(),g);f.onAddItem.add(this.onAddItem.dispatch,this.onAddItem);return f}})})(tinymce);(function(e){var d=e.is,c=e.DOM,f=e.each,a=e.dom.Event,b=e.dom.Element;e.create(\"tinymce.ui.DropMenu:tinymce.ui.Menu\",{DropMenu:function(h,g){g=g||{};g.container=g.container||c.doc.body;g.offset_x=g.offset_x||0;g.offset_y=g.offset_y||0;g.vp_offset_x=g.vp_offset_x||0;g.vp_offset_y=g.vp_offset_y||0;if(d(g.icons)&&!g.icons){g[\"class\"]+=\" mceNoIcons\"}this.parent(h,g);this.onShowMenu=new e.util.Dispatcher(this);this.onHideMenu=new e.util.Dispatcher(this);this.classPrefix=\"mceMenu\"},createMenu:function(j){var h=this,i=h.settings,g;j.container=j.container||i.container;j.parent=h;j.constrain=j.constrain||i.constrain;j[\"class\"]=j[\"class\"]||i[\"class\"];j.vp_offset_x=j.vp_offset_x||i.vp_offset_x;j.vp_offset_y=j.vp_offset_y||i.vp_offset_y;g=new e.ui.DropMenu(j.id||c.uniqueId(),j);g.onAddItem.add(h.onAddItem.dispatch,h.onAddItem);return g},update:function(){var i=this,j=i.settings,g=c.get(\"menu_\"+i.id+\"_tbl\"),l=c.get(\"menu_\"+i.id+\"_co\"),h,k;h=j.max_width?Math.min(g.clientWidth,j.max_width):g.clientWidth;k=j.max_height?Math.min(g.clientHeight,j.max_height):g.clientHeight;if(!c.boxModel){i.element.setStyles({width:h+2,height:k+2})}else{i.element.setStyles({width:h,height:k})}if(j.max_width){c.setStyle(l,\"width\",h)}if(j.max_height){c.setStyle(l,\"height\",k);if(g.clientHeight<j.max_height){c.setStyle(l,\"overflow\",\"hidden\")}}},showMenu:function(p,n,r){var z=this,A=z.settings,o,g=c.getViewPort(),u,l,v,q,i=2,k,j,m=z.classPrefix;z.collapse(1);if(z.isMenuVisible){return}if(!z.rendered){o=c.add(z.settings.container,z.renderNode());f(z.items,function(h){h.postRender()});z.element=new b(\"menu_\"+z.id,{blocker:1,container:A.container})}else{o=c.get(\"menu_\"+z.id)}if(!e.isOpera){c.setStyles(o,{left:-65535,top:-65535})}c.show(o);z.update();p+=A.offset_x||0;n+=A.offset_y||0;g.w-=4;g.h-=4;if(A.constrain){u=o.clientWidth-i;l=o.clientHeight-i;v=g.x+g.w;q=g.y+g.h;if((p+A.vp_offset_x+u)>v){p=r?r-u:Math.max(0,(v-A.vp_offset_x)-u)}if((n+A.vp_offset_y+l)>q){n=Math.max(0,(q-A.vp_offset_y)-l)}}c.setStyles(o,{left:p,top:n});z.element.update();z.isMenuVisible=1;z.mouseClickFunc=a.add(o,\"click\",function(s){var h;s=s.target;if(s&&(s=c.getParent(s,\"tr\"))&&!c.hasClass(s,m+\"ItemSub\")){h=z.items[s.id];if(h.isDisabled()){return}k=z;while(k){if(k.hideMenu){k.hideMenu()}k=k.settings.parent}if(h.settings.onclick){h.settings.onclick(s)}return a.cancel(s)}});if(z.hasMenus()){z.mouseOverFunc=a.add(o,\"mouseover\",function(w){var h,t,s;w=w.target;if(w&&(w=c.getParent(w,\"tr\"))){h=z.items[w.id];if(z.lastMenu){z.lastMenu.collapse(1)}if(h.isDisabled()){return}if(w&&c.hasClass(w,m+\"ItemSub\")){t=c.getRect(w);h.showMenu((t.x+t.w-i),t.y-i,t.x);z.lastMenu=h;c.addClass(c.get(h.id).firstChild,m+\"ItemActive\")}}})}z.onShowMenu.dispatch(z);if(A.keyboard_focus){a.add(o,\"keydown\",z._keyHandler,z);c.select(\"a\",\"menu_\"+z.id)[0].focus();z._focusIdx=0}},hideMenu:function(j){var g=this,i=c.get(\"menu_\"+g.id),h;if(!g.isMenuVisible){return}a.remove(i,\"mouseover\",g.mouseOverFunc);a.remove(i,\"click\",g.mouseClickFunc);a.remove(i,\"keydown\",g._keyHandler);c.hide(i);g.isMenuVisible=0;if(!j){g.collapse(1)}if(g.element){g.element.hide()}if(h=c.get(g.id)){c.removeClass(h.firstChild,g.classPrefix+\"ItemActive\")}g.onHideMenu.dispatch(g)},add:function(i){var g=this,h;i=g.parent(i);if(g.isRendered&&(h=c.get(\"menu_\"+g.id))){g._add(c.select(\"tbody\",h)[0],i)}return i},collapse:function(g){this.parent(g);this.hideMenu(1)},remove:function(g){c.remove(g.id);this.destroy();return this.parent(g)},destroy:function(){var g=this,h=c.get(\"menu_\"+g.id);a.remove(h,\"mouseover\",g.mouseOverFunc);a.remove(h,\"click\",g.mouseClickFunc);if(g.element){g.element.remove()}c.remove(h)},renderNode:function(){var i=this,j=i.settings,l,h,k,g;g=c.create(\"div\",{id:\"menu_\"+i.id,\"class\":j[\"class\"],style:\"position:absolute;left:0;top:0;z-index:200000\"});k=c.add(g,\"div\",{id:\"menu_\"+i.id+\"_co\",\"class\":i.classPrefix+(j[\"class\"]?\" \"+j[\"class\"]:\"\")});i.element=new b(\"menu_\"+i.id,{blocker:1,container:j.container});if(j.menu_line){c.add(k,\"span\",{\"class\":i.classPrefix+\"Line\"})}l=c.add(k,\"table\",{id:\"menu_\"+i.id+\"_tbl\",border:0,cellPadding:0,cellSpacing:0});h=c.add(l,\"tbody\");f(i.items,function(m){i._add(h,m)});i.rendered=true;return g},_keyHandler:function(j){var i=this,h=j.keyCode;function g(m){var k=i._focusIdx+m,l=c.select(\"a\",\"menu_\"+i.id)[k];if(l){i._focusIdx=k;l.focus()}}switch(h){case 38:g(-1);return;case 40:g(1);return;case 13:return;case 27:return this.hideMenu()}},_add:function(j,h){var i,q=h.settings,p,l,k,m=this.classPrefix,g;if(q.separator){l=c.add(j,\"tr\",{id:h.id,\"class\":m+\"ItemSeparator\"});c.add(l,\"td\",{\"class\":m+\"ItemSeparator\"});if(i=l.previousSibling){c.addClass(i,\"mceLast\")}return}i=l=c.add(j,\"tr\",{id:h.id,\"class\":m+\"Item \"+m+\"ItemEnabled\"});i=k=c.add(i,\"td\");i=p=c.add(i,\"a\",{href:\"#\",onclick:\"return false;\",onmousedown:\"return false;\"});c.addClass(k,q[\"class\"]);g=c.add(i,\"span\",{\"class\":\"mceIcon\"+(q.icon?\" mce_\"+q.icon:\"\")});if(q.icon_src){c.add(g,\"img\",{src:q.icon_src})}i=c.add(i,q.element||\"span\",{\"class\":\"mceText\",title:h.settings.title},h.settings.title);if(h.settings.style){c.setAttrib(i,\"style\",h.settings.style)}if(j.childNodes.length==1){c.addClass(l,\"mceFirst\")}if((i=l.previousSibling)&&c.hasClass(i,m+\"ItemSeparator\")){c.addClass(l,\"mceFirst\")}if(h.collapse){c.addClass(l,m+\"ItemSub\")}if(i=l.previousSibling){c.removeClass(i,\"mceLast\")}c.addClass(l,\"mceLast\")}})})(tinymce);(function(b){var a=b.DOM;b.create(\"tinymce.ui.Button:tinymce.ui.Control\",{Button:function(d,c){this.parent(d,c);this.classPrefix=\"mceButton\"},renderHTML:function(){var f=this.classPrefix,e=this.settings,d,c;c=a.encode(e.label||\"\");d='<a id=\"'+this.id+'\" href=\"#\" class=\"'+f+\" \"+f+\"Enabled \"+e[\"class\"]+(c?\" \"+f+\"Labeled\":\"\")+'\" onmousedown=\"return false;\" onclick=\"return false;\" title=\"'+a.encode(e.title)+'\">';if(e.image){d+='<img class=\"mceIcon\" src=\"'+e.image+'\" />'+c+\"</a>\"}else{d+='<span class=\"mceIcon '+e[\"class\"]+'\"></span>'+(c?'<span class=\"'+f+'Label\">'+c+\"</span>\":\"\")+\"</a>\"}return d},postRender:function(){var c=this,d=c.settings;b.dom.Event.add(c.id,\"click\",function(f){if(!c.isDisabled()){return d.onclick.call(d.scope,f)}})}})})(tinymce);(function(d){var c=d.DOM,b=d.dom.Event,e=d.each,a=d.util.Dispatcher;d.create(\"tinymce.ui.ListBox:tinymce.ui.Control\",{ListBox:function(h,g){var f=this;f.parent(h,g);f.items=[];f.onChange=new a(f);f.onPostRender=new a(f);f.onAdd=new a(f);f.onRenderMenu=new d.util.Dispatcher(this);f.classPrefix=\"mceListBox\"},select:function(h){var g=this,j,i;if(h==undefined){return g.selectByIndex(-1)}if(h&&h.call){i=h}else{i=function(f){return f==h}}if(h!=g.selectedValue){e(g.items,function(k,f){if(i(k.value)){j=1;g.selectByIndex(f);return false}});if(!j){g.selectByIndex(-1)}}},selectByIndex:function(f){var g=this,h,i;if(f!=g.selectedIndex){h=c.get(g.id+\"_text\");i=g.items[f];if(i){g.selectedValue=i.value;g.selectedIndex=f;c.setHTML(h,c.encode(i.title));c.removeClass(h,\"mceTitle\")}else{c.setHTML(h,c.encode(g.settings.title));c.addClass(h,\"mceTitle\");g.selectedValue=g.selectedIndex=null}h=0}},add:function(i,f,h){var g=this;h=h||{};h=d.extend(h,{title:i,value:f});g.items.push(h);g.onAdd.dispatch(g,h)},getLength:function(){return this.items.length},renderHTML:function(){var i=\"\",f=this,g=f.settings,j=f.classPrefix;i='<table id=\"'+f.id+'\" cellpadding=\"0\" cellspacing=\"0\" class=\"'+j+\" \"+j+\"Enabled\"+(g[\"class\"]?(\" \"+g[\"class\"]):\"\")+'\"><tbody><tr>';i+=\"<td>\"+c.createHTML(\"a\",{id:f.id+\"_text\",href:\"#\",\"class\":\"mceText\",onclick:\"return false;\",onmousedown:\"return false;\"},c.encode(f.settings.title))+\"</td>\";i+=\"<td>\"+c.createHTML(\"a\",{id:f.id+\"_open\",tabindex:-1,href:\"#\",\"class\":\"mceOpen\",onclick:\"return false;\",onmousedown:\"return false;\"},\"<span></span>\")+\"</td>\";i+=\"</tr></tbody></table>\";return i},showMenu:function(){var g=this,j,i,h=c.get(this.id),f;if(g.isDisabled()||g.items.length==0){return}if(g.menu&&g.menu.isMenuVisible){return g.hideMenu()}if(!g.isMenuRendered){g.renderMenu();g.isMenuRendered=true}j=c.getPos(this.settings.menu_container);i=c.getPos(h);f=g.menu;f.settings.offset_x=i.x;f.settings.offset_y=i.y;f.settings.keyboard_focus=!d.isOpera;if(g.oldID){f.items[g.oldID].setSelected(0)}e(g.items,function(k){if(k.value===g.selectedValue){f.items[k.id].setSelected(1);g.oldID=k.id}});f.showMenu(0,h.clientHeight);b.add(c.doc,\"mousedown\",g.hideMenu,g);c.addClass(g.id,g.classPrefix+\"Selected\")},hideMenu:function(g){var f=this;if(g&&g.type==\"mousedown\"&&(g.target.id==f.id+\"_text\"||g.target.id==f.id+\"_open\")){return}if(!g||!c.getParent(g.target,\".mceMenu\")){c.removeClass(f.id,f.classPrefix+\"Selected\");b.remove(c.doc,\"mousedown\",f.hideMenu,f);if(f.menu){f.menu.hideMenu()}}},renderMenu:function(){var g=this,f;f=g.settings.control_manager.createDropMenu(g.id+\"_menu\",{menu_line:1,\"class\":g.classPrefix+\"Menu mceNoIcons\",max_width:150,max_height:150});f.onHideMenu.add(g.hideMenu,g);f.add({title:g.settings.title,\"class\":\"mceMenuItemTitle\",onclick:function(){if(g.settings.onselect(\"\")!==false){g.select(\"\")}}});e(g.items,function(h){h.id=c.uniqueId();h.onclick=function(){if(g.settings.onselect(h.value)!==false){g.select(h.value)}};f.add(h)});g.onRenderMenu.dispatch(g,f);g.menu=f},postRender:function(){var f=this,g=f.classPrefix;b.add(f.id,\"click\",f.showMenu,f);b.add(f.id+\"_text\",\"focus\",function(h){if(!f._focused){f.keyDownHandler=b.add(f.id+\"_text\",\"keydown\",function(l){var i=-1,j,k=l.keyCode;e(f.items,function(m,n){if(f.selectedValue==m.value){i=n}});if(k==38){j=f.items[i-1]}else{if(k==40){j=f.items[i+1]}else{if(k==13){j=f.selectedValue;f.selectedValue=null;f.settings.onselect(j);return b.cancel(l)}}}if(j){f.hideMenu();f.select(j.value)}})}f._focused=1});b.add(f.id+\"_text\",\"blur\",function(){b.remove(f.id+\"_text\",\"keydown\",f.keyDownHandler);f._focused=0});if(d.isIE6||!c.boxModel){b.add(f.id,\"mouseover\",function(){if(!c.hasClass(f.id,g+\"Disabled\")){c.addClass(f.id,g+\"Hover\")}});b.add(f.id,\"mouseout\",function(){if(!c.hasClass(f.id,g+\"Disabled\")){c.removeClass(f.id,g+\"Hover\")}})}f.onPostRender.dispatch(f,c.get(f.id))},destroy:function(){this.parent();b.clear(this.id+\"_text\");b.clear(this.id+\"_open\")}})})(tinymce);(function(d){var c=d.DOM,b=d.dom.Event,e=d.each,a=d.util.Dispatcher;d.create(\"tinymce.ui.NativeListBox:tinymce.ui.ListBox\",{NativeListBox:function(g,f){this.parent(g,f);this.classPrefix=\"mceNativeListBox\"},setDisabled:function(f){c.get(this.id).disabled=f},isDisabled:function(){return c.get(this.id).disabled},select:function(h){var g=this,j,i;if(h==undefined){return g.selectByIndex(-1)}if(h&&h.call){i=h}else{i=function(f){return f==h}}if(h!=g.selectedValue){e(g.items,function(k,f){if(i(k.value)){j=1;g.selectByIndex(f);return false}});if(!j){g.selectByIndex(-1)}}},selectByIndex:function(f){c.get(this.id).selectedIndex=f+1;this.selectedValue=this.items[f]?this.items[f].value:null},add:function(j,g,f){var i,h=this;f=f||{};f.value=g;if(h.isRendered()){c.add(c.get(this.id),\"option\",f,j)}i={title:j,value:g,attribs:f};h.items.push(i);h.onAdd.dispatch(h,i)},getLength:function(){return c.get(this.id).options.length-1},renderHTML:function(){var g,f=this;g=c.createHTML(\"option\",{value:\"\"},\"-- \"+f.settings.title+\" --\");e(f.items,function(h){g+=c.createHTML(\"option\",{value:h.value},h.title)});g=c.createHTML(\"select\",{id:f.id,\"class\":\"mceNativeListBox\"},g);return g},postRender:function(){var g=this,h;g.rendered=true;function f(j){var i=g.items[j.target.selectedIndex-1];if(i&&(i=i.value)){g.onChange.dispatch(g,i);if(g.settings.onselect){g.settings.onselect(i)}}}b.add(g.id,\"change\",f);b.add(g.id,\"keydown\",function(j){var i;b.remove(g.id,\"change\",h);i=b.add(g.id,\"blur\",function(){b.add(g.id,\"change\",f);b.remove(g.id,\"blur\",i)});if(j.keyCode==13||j.keyCode==32){f(j);return b.cancel(j)}});g.onPostRender.dispatch(g,c.get(g.id))}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each;c.create(\"tinymce.ui.MenuButton:tinymce.ui.Button\",{MenuButton:function(f,e){this.parent(f,e);this.onRenderMenu=new c.util.Dispatcher(this);e.menu_container=e.menu_container||b.doc.body},showMenu:function(){var g=this,j,i,h=b.get(g.id),f;if(g.isDisabled()){return}if(!g.isMenuRendered){g.renderMenu();g.isMenuRendered=true}if(g.isMenuVisible){return g.hideMenu()}j=b.getPos(g.settings.menu_container);i=b.getPos(h);f=g.menu;f.settings.offset_x=i.x;f.settings.offset_y=i.y;f.settings.vp_offset_x=i.x;f.settings.vp_offset_y=i.y;f.settings.keyboard_focus=g._focused;f.showMenu(0,h.clientHeight);a.add(b.doc,\"mousedown\",g.hideMenu,g);g.setState(\"Selected\",1);g.isMenuVisible=1},renderMenu:function(){var f=this,e;e=f.settings.control_manager.createDropMenu(f.id+\"_menu\",{menu_line:1,\"class\":this.classPrefix+\"Menu\",icons:f.settings.icons});e.onHideMenu.add(f.hideMenu,f);f.onRenderMenu.dispatch(f,e);f.menu=e},hideMenu:function(g){var f=this;if(g&&g.type==\"mousedown\"&&b.getParent(g.target,function(h){return h.id===f.id||h.id===f.id+\"_open\"})){return}if(!g||!b.getParent(g.target,\".mceMenu\")){f.setState(\"Selected\",0);a.remove(b.doc,\"mousedown\",f.hideMenu,f);if(f.menu){f.menu.hideMenu()}}f.isMenuVisible=0},postRender:function(){var e=this,f=e.settings;a.add(e.id,\"click\",function(){if(!e.isDisabled()){if(f.onclick){f.onclick(e.value)}e.showMenu()}})}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each;c.create(\"tinymce.ui.SplitButton:tinymce.ui.MenuButton\",{SplitButton:function(f,e){this.parent(f,e);this.classPrefix=\"mceSplitButton\"},renderHTML:function(){var i,f=this,g=f.settings,e;i=\"<tbody><tr>\";if(g.image){e=b.createHTML(\"img \",{src:g.image,\"class\":\"mceAction \"+g[\"class\"]})}else{e=b.createHTML(\"span\",{\"class\":\"mceAction \"+g[\"class\"]},\"\")}i+=\"<td>\"+b.createHTML(\"a\",{id:f.id+\"_action\",href:\"#\",\"class\":\"mceAction \"+g[\"class\"],onclick:\"return false;\",onmousedown:\"return false;\",title:g.title},e)+\"</td>\";e=b.createHTML(\"span\",{\"class\":\"mceOpen \"+g[\"class\"]});i+=\"<td>\"+b.createHTML(\"a\",{id:f.id+\"_open\",href:\"#\",\"class\":\"mceOpen \"+g[\"class\"],onclick:\"return false;\",onmousedown:\"return false;\",title:g.title},e)+\"</td>\";i+=\"</tr></tbody>\";return b.createHTML(\"table\",{id:f.id,\"class\":\"mceSplitButton mceSplitButtonEnabled \"+g[\"class\"],cellpadding:\"0\",cellspacing:\"0\",onmousedown:\"return false;\",title:g.title},i)},postRender:function(){var e=this,f=e.settings;if(f.onclick){a.add(e.id+\"_action\",\"click\",function(){if(!e.isDisabled()){f.onclick(e.value)}})}a.add(e.id+\"_open\",\"click\",e.showMenu,e);a.add(e.id+\"_open\",\"focus\",function(){e._focused=1});a.add(e.id+\"_open\",\"blur\",function(){e._focused=0});if(c.isIE6||!b.boxModel){a.add(e.id,\"mouseover\",function(){if(!b.hasClass(e.id,\"mceSplitButtonDisabled\")){b.addClass(e.id,\"mceSplitButtonHover\")}});a.add(e.id,\"mouseout\",function(){if(!b.hasClass(e.id,\"mceSplitButtonDisabled\")){b.removeClass(e.id,\"mceSplitButtonHover\")}})}},destroy:function(){this.parent();a.clear(this.id+\"_action\");a.clear(this.id+\"_open\")}})})(tinymce);(function(d){var c=d.DOM,a=d.dom.Event,b=d.is,e=d.each;d.create(\"tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton\",{ColorSplitButton:function(h,g){var f=this;f.parent(h,g);f.settings=g=d.extend({colors:\"000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF\",grid_width:8,default_color:\"#888888\"},f.settings);f.onShowMenu=new d.util.Dispatcher(f);f.onHideMenu=new d.util.Dispatcher(f);f.value=g.default_color},showMenu:function(){var f=this,g,j,i,h;if(f.isDisabled()){return}if(!f.isMenuRendered){f.renderMenu();f.isMenuRendered=true}if(f.isMenuVisible){return f.hideMenu()}i=c.get(f.id);c.show(f.id+\"_menu\");c.addClass(i,\"mceSplitButtonSelected\");h=c.getPos(i);c.setStyles(f.id+\"_menu\",{left:h.x,top:h.y+i.clientHeight,zIndex:200000});i=0;a.add(c.doc,\"mousedown\",f.hideMenu,f);f.onShowMenu.dispatch(f);if(f._focused){f._keyHandler=a.add(f.id+\"_menu\",\"keydown\",function(k){if(k.keyCode==27){f.hideMenu()}});c.select(\"a\",f.id+\"_menu\")[0].focus()}f.isMenuVisible=1},hideMenu:function(g){var f=this;if(g&&g.type==\"mousedown\"&&c.getParent(g.target,function(h){return h.id===f.id+\"_open\"})){return}if(!g||!c.getParent(g.target,\".mceSplitButtonMenu\")){c.removeClass(f.id,\"mceSplitButtonSelected\");a.remove(c.doc,\"mousedown\",f.hideMenu,f);a.remove(f.id+\"_menu\",\"keydown\",f._keyHandler);c.hide(f.id+\"_menu\")}f.onHideMenu.dispatch(f);f.isMenuVisible=0},renderMenu:function(){var k=this,f,j=0,l=k.settings,p,h,o,g;g=c.add(l.menu_container,\"div\",{id:k.id+\"_menu\",\"class\":l.menu_class+\" \"+l[\"class\"],style:\"position:absolute;left:0;top:-1000px;\"});f=c.add(g,\"div\",{\"class\":l[\"class\"]+\" mceSplitButtonMenu\"});c.add(f,\"span\",{\"class\":\"mceMenuLine\"});p=c.add(f,\"table\",{\"class\":\"mceColorSplitMenu\"});h=c.add(p,\"tbody\");j=0;e(b(l.colors,\"array\")?l.colors:l.colors.split(\",\"),function(i){i=i.replace(/^#/,\"\");if(!j--){o=c.add(h,\"tr\");j=l.grid_width-1}p=c.add(o,\"td\");p=c.add(p,\"a\",{href:\"#\",style:{backgroundColor:\"#\"+i},mce_color:\"#\"+i})});if(l.more_colors_func){p=c.add(h,\"tr\");p=c.add(p,\"td\",{colspan:l.grid_width,\"class\":\"mceMoreColors\"});p=c.add(p,\"a\",{id:k.id+\"_more\",href:\"#\",onclick:\"return false;\",\"class\":\"mceMoreColors\"},l.more_colors_title);a.add(p,\"click\",function(i){l.more_colors_func.call(l.more_colors_scope||this);return a.cancel(i)})}c.addClass(f,\"mceColorSplitMenu\");a.add(k.id+\"_menu\",\"click\",function(i){var m;i=i.target;if(i.nodeName==\"A\"&&(m=i.getAttribute(\"mce_color\"))){k.setColor(m)}return a.cancel(i)});return g},setColor:function(g){var f=this;c.setStyle(f.id+\"_preview\",\"backgroundColor\",g);f.value=g;f.hideMenu();f.settings.onselect(g)},postRender:function(){var f=this,g=f.id;f.parent();c.add(g+\"_action\",\"div\",{id:g+\"_preview\",\"class\":\"mceColorPreview\"});c.setStyle(f.id+\"_preview\",\"backgroundColor\",f.value)},destroy:function(){this.parent();a.clear(this.id+\"_menu\");a.clear(this.id+\"_more\");c.remove(this.id+\"_menu\")}})})(tinymce);tinymce.create(\"tinymce.ui.Toolbar:tinymce.ui.Container\",{renderHTML:function(){var l=this,e=\"\",g,j,b=tinymce.DOM,m=l.settings,d,a,f,k;k=l.controls;for(d=0;d<k.length;d++){j=k[d];a=k[d-1];f=k[d+1];if(d===0){g=\"mceToolbarStart\";if(j.Button){g+=\" mceToolbarStartButton\"}else{if(j.SplitButton){g+=\" mceToolbarStartSplitButton\"}else{if(j.ListBox){g+=\" mceToolbarStartListBox\"}}}e+=b.createHTML(\"td\",{\"class\":g},b.createHTML(\"span\",null,\"<!-- IE -->\"))}if(a&&j.ListBox){if(a.Button||a.SplitButton){e+=b.createHTML(\"td\",{\"class\":\"mceToolbarEnd\"},b.createHTML(\"span\",null,\"<!-- IE -->\"))}}if(b.stdMode){e+='<td style=\"position: relative\">'+j.renderHTML()+\"</td>\"}else{e+=\"<td>\"+j.renderHTML()+\"</td>\"}if(f&&j.ListBox){if(f.Button||f.SplitButton){e+=b.createHTML(\"td\",{\"class\":\"mceToolbarStart\"},b.createHTML(\"span\",null,\"<!-- IE -->\"))}}}g=\"mceToolbarEnd\";if(j.Button){g+=\" mceToolbarEndButton\"}else{if(j.SplitButton){g+=\" mceToolbarEndSplitButton\"}else{if(j.ListBox){g+=\" mceToolbarEndListBox\"}}}e+=b.createHTML(\"td\",{\"class\":g},b.createHTML(\"span\",null,\"<!-- IE -->\"));return b.createHTML(\"table\",{id:l.id,\"class\":\"mceToolbar\"+(m[\"class\"]?\" \"+m[\"class\"]:\"\"),cellpadding:\"0\",cellspacing:\"0\",align:l.settings.align||\"\"},\"<tbody><tr>\"+e+\"</tr></tbody>\")}});(function(b){var a=b.util.Dispatcher,c=b.each;b.create(\"tinymce.AddOnManager\",{items:[],urls:{},lookup:{},onAdd:new a(this),get:function(d){return this.lookup[d]},requireLangPack:function(f){var d,e=b.EditorManager.settings;if(e&&e.language){d=this.urls[f]+\"/langs/\"+e.language+\".js\";if(!b.dom.Event.domLoaded&&!e.strict_mode){b.ScriptLoader.load(d)}else{b.ScriptLoader.add(d)}}},add:function(e,d){this.items.push(d);this.lookup[e]=d;this.onAdd.dispatch(this,e,d);return d},load:function(h,e,d,g){var f=this;if(f.urls[h]){return}if(e.indexOf(\"/\")!=0&&e.indexOf(\"://\")==-1){e=b.baseURL+\"/\"+e}f.urls[h]=e.substring(0,e.lastIndexOf(\"/\"));b.ScriptLoader.add(e,d,g)}});b.PluginManager=new b.AddOnManager();b.ThemeManager=new b.AddOnManager()}(tinymce));(function(f){var g=f.each,h=f.extend,e=f.DOM,a=f.dom.Event,c=f.ThemeManager,b=f.PluginManager,d=f.explode;f.create(\"static tinymce.EditorManager\",{editors:{},i18n:{},activeEditor:null,preInit:function(){var i=this,j=window.location;f.documentBaseURL=j.href.replace(/[\\?#].*$/,\"\").replace(/[\\/\\\\][^\\/]+$/,\"\");if(!/[\\/\\\\]$/.test(f.documentBaseURL)){f.documentBaseURL+=\"/\"}f.baseURL=new f.util.URI(f.documentBaseURL).toAbsolute(f.baseURL);f.EditorManager.baseURI=new f.util.URI(f.baseURL);i.onBeforeUnload=new f.util.Dispatcher(i);a.add(window,\"beforeunload\",function(k){i.onBeforeUnload.dispatch(i,k)})},init:function(q){var p=this,l,k=f.ScriptLoader,o,n,i=[],m;function j(u,v,r){var t=u[v];if(!t){return}if(f.is(t,\"string\")){r=t.replace(/\\.\\w+$/,\"\");r=r?f.resolve(r):0;t=f.resolve(t)}return t.apply(r||this,Array.prototype.slice.call(arguments,2))}q=h({theme:\"simple\",language:\"en\",strict_loading_mode:document.contentType==\"application/xhtml+xml\"},q);p.settings=q;if(!a.domLoaded&&!q.strict_loading_mode){if(q.language){k.add(f.baseURL+\"/langs/\"+q.language+\".js\")}if(q.theme&&q.theme.charAt(0)!=\"-\"&&!c.urls[q.theme]){c.load(q.theme,\"themes/\"+q.theme+\"/editor_template\"+f.suffix+\".js\")}if(q.plugins){l=d(q.plugins);g(l,function(r){if(r&&r.charAt(0)!=\"-\"&&!b.urls[r]){if(!f.isWebKit&&r==\"safari\"){return}b.load(r,\"plugins/\"+r+\"/editor_plugin\"+f.suffix+\".js\")}})}k.loadQueue()}a.add(document,\"init\",function(){var r,t;j(q,\"onpageload\");if(q.browsers){r=false;g(d(q.browsers),function(u){switch(u){case\"ie\":case\"msie\":if(f.isIE){r=true}break;case\"gecko\":if(f.isGecko){r=true}break;case\"safari\":case\"webkit\":if(f.isWebKit){r=true}break;case\"opera\":if(f.isOpera){r=true}break}});if(!r){return}}switch(q.mode){case\"exact\":r=q.elements||\"\";if(r.length>0){g(d(r),function(u){if(e.get(u)){m=new f.Editor(u,q);i.push(m);m.render(1)}else{o=0;g(document.forms,function(v){g(v.elements,function(w){if(w.name===u){u=\"mce_editor_\"+o;e.setAttrib(w,\"id\",u);m=new f.Editor(u,q);i.push(m);m.render(1)}})})}})}break;case\"textareas\":case\"specific_textareas\":function s(v,u){return u.constructor===RegExp?u.test(v.className):e.hasClass(v,u)}g(e.select(\"textarea\"),function(u){if(q.editor_deselector&&s(u,q.editor_deselector)){return}if(!q.editor_selector||s(u,q.editor_selector)){n=e.get(u.name);if(!u.id&&!n){u.id=u.name}if(!u.id||p.get(u.id)){u.id=e.uniqueId()}m=new f.Editor(u.id,q);i.push(m);m.render(1)}});break}if(q.oninit){r=t=0;g(i,function(u){t++;if(!u.initialized){u.onInit.add(function(){r++;if(r==t){j(q,\"oninit\")}})}else{r++}if(r==t){j(q,\"oninit\")}})}})},get:function(i){return this.editors[i]},getInstanceById:function(i){return this.get(i)},add:function(i){this.editors[i.id]=i;this._setActive(i);return i},remove:function(j){var i=this;if(!i.editors[j.id]){return null}delete i.editors[j.id];if(i.activeEditor==j){i._setActive(null);g(i.editors,function(k){i._setActive(k);return false})}j.destroy();return j},execCommand:function(o,m,l){var n=this,k=n.get(l),i;switch(o){case\"mceFocus\":k.focus();return true;case\"mceAddEditor\":case\"mceAddControl\":if(!n.get(l)){new f.Editor(l,n.settings).render()}return true;case\"mceAddFrameControl\":i=l.window;i.tinyMCE=tinyMCE;i.tinymce=f;f.DOM.doc=i.document;f.DOM.win=i;k=new f.Editor(l.element_id,l);k.render();if(f.isIE){function j(){k.destroy();i.detachEvent(\"onunload\",j);i=i.tinyMCE=i.tinymce=null}i.attachEvent(\"onunload\",j)}l.page_window=null;return true;case\"mceRemoveEditor\":case\"mceRemoveControl\":if(k){k.remove()}return true;case\"mceToggleEditor\":if(!k){n.execCommand(\"mceAddControl\",0,l);return true}if(k.isHidden()){k.show()}else{k.hide()}return true}if(n.activeEditor){return n.activeEditor.execCommand(o,m,l)}return false},execInstanceCommand:function(m,l,k,j){var i=this.get(m);if(i){return i.execCommand(l,k,j)}return false},triggerSave:function(){g(this.editors,function(i){i.save()})},addI18n:function(k,l){var i,j=this.i18n;if(!f.is(k,\"string\")){g(k,function(n,m){g(n,function(q,p){g(q,function(s,r){if(p===\"common\"){j[m+\".\"+r]=s}else{j[m+\".\"+p+\".\"+r]=s}})})})}else{g(l,function(n,m){j[k+\".\"+m]=n})}},_setActive:function(i){this.selectedInstance=this.activeEditor=i}});f.EditorManager.preInit()})(tinymce);var tinyMCE=window.tinyMCE=tinymce.EditorManager;(function(n){var o=n.DOM,k=n.dom.Event,f=n.extend,l=n.util.Dispatcher;var j=n.each,a=n.isGecko,b=n.isIE,e=n.isWebKit;var d=n.is,h=n.ThemeManager,c=n.PluginManager,i=n.EditorManager;var p=n.inArray,m=n.grep,g=n.explode;n.create(\"tinymce.Editor\",{Editor:function(u,r){var q=this;q.id=q.editorId=u;q.execCommands={};q.queryStateCommands={};q.queryValueCommands={};q.isNotDirty=false;q.plugins={};j([\"onPreInit\",\"onBeforeRenderUI\",\"onPostRender\",\"onInit\",\"onRemove\",\"onActivate\",\"onDeactivate\",\"onClick\",\"onEvent\",\"onMouseUp\",\"onMouseDown\",\"onDblClick\",\"onKeyDown\",\"onKeyUp\",\"onKeyPress\",\"onContextMenu\",\"onSubmit\",\"onReset\",\"onPaste\",\"onPreProcess\",\"onPostProcess\",\"onBeforeSetContent\",\"onBeforeGetContent\",\"onSetContent\",\"onGetContent\",\"onLoadContent\",\"onSaveContent\",\"onNodeChange\",\"onChange\",\"onBeforeExecCommand\",\"onExecCommand\",\"onUndo\",\"onRedo\",\"onVisualAid\",\"onSetProgressState\"],function(s){q[s]=new l(q)});q.settings=r=f({id:u,language:\"en\",docs_language:\"en\",theme:\"simple\",skin:\"default\",delta_width:0,delta_height:0,popup_css:\"\",plugins:\"\",document_base_url:n.documentBaseURL,add_form_submit_trigger:1,submit_patch:1,add_unload_trigger:1,convert_urls:1,relative_urls:1,remove_script_host:1,table_inline_editing:0,object_resizing:1,cleanup:1,accessibility_focus:1,custom_shortcuts:1,custom_undo_redo_keyboard_shortcuts:1,custom_undo_redo_restore_selection:1,custom_undo_redo:1,doctype:'<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">',visual_table_class:\"mceItemTable\",visual:1,inline_styles:true,convert_fonts_to_spans:true,font_size_style_values:\"xx-small,x-small,small,medium,large,x-large,xx-large\",apply_source_formatting:1,directionality:\"ltr\",forced_root_block:\"p\",valid_elements:\"@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big\",hidden_input:1,padd_empty_editor:1,render_ui:1,init_theme:1,force_p_newlines:1,indentation:\"30px\",keep_styles:1,fix_table_elements:1,removeformat_selector:\"span,b,strong,em,i,font,u,strike\"},r);q.documentBaseURI=new n.util.URI(r.document_base_url||n.documentBaseURL,{base_uri:tinyMCE.baseURI});q.baseURI=i.baseURI;q.execCallback(\"setup\",q)},render:function(u){var v=this,w=v.settings,x=v.id,q=n.ScriptLoader;if(!k.domLoaded){k.add(document,\"init\",function(){v.render()});return}if(!u){w.strict_loading_mode=1;tinyMCE.settings=w}if(!v.getElement()){return}if(w.strict_loading_mode){q.settings.strict_mode=w.strict_loading_mode;n.DOM.settings.strict=1}if(!/TEXTAREA|INPUT/i.test(v.getElement().nodeName)&&w.hidden_input&&o.getParent(x,\"form\")){o.insertAfter(o.create(\"input\",{type:\"hidden\",name:x}),x)}if(n.WindowManager){v.windowManager=new n.WindowManager(v)}if(w.encoding==\"xml\"){v.onGetContent.add(function(s,t){if(t.save){t.content=o.encode(t.content)}})}if(w.add_form_submit_trigger){v.onSubmit.addToTop(function(){if(v.initialized){v.save();v.isNotDirty=1}})}if(w.add_unload_trigger){v._beforeUnload=tinyMCE.onBeforeUnload.add(function(){if(v.initialized&&!v.destroyed&&!v.isHidden()){v.save({format:\"raw\",no_events:true})}})}n.addUnload(v.destroy,v);if(w.submit_patch){v.onBeforeRenderUI.add(function(){var s=v.getElement().form;if(!s){return}if(s._mceOldSubmit){return}if(!s.submit.nodeType&&!s.submit.length){v.formElement=s;s._mceOldSubmit=s.submit;s.submit=function(){i.triggerSave();v.isNotDirty=1;return v.formElement._mceOldSubmit(v.formElement)}}s=null})}function r(){if(w.language){q.add(n.baseURL+\"/langs/\"+w.language+\".js\")}if(w.theme&&w.theme.charAt(0)!=\"-\"&&!h.urls[w.theme]){h.load(w.theme,\"themes/\"+w.theme+\"/editor_template\"+n.suffix+\".js\")}j(g(w.plugins),function(s){if(s&&s.charAt(0)!=\"-\"&&!c.urls[s]){if(!e&&s==\"safari\"){return}c.load(s,\"plugins/\"+s+\"/editor_plugin\"+n.suffix+\".js\")}});q.loadQueue(function(){if(!v.removed){v.init()}})}r()},init:function(){var v,F=this,G=F.settings,C,z,B=F.getElement(),r,q,D,y,A,E;i.add(F);if(G.theme){G.theme=G.theme.replace(/-/,\"\");r=h.get(G.theme);F.theme=new r();if(F.theme.init&&G.init_theme){F.theme.init(F,h.urls[G.theme]||n.documentBaseURL.replace(/\\/$/,\"\"))}}j(g(G.plugins.replace(/\\-/g,\"\")),function(w){var H=c.get(w),t=c.urls[w]||n.documentBaseURL.replace(/\\/$/,\"\"),s;if(H){s=new H(F,t);F.plugins[w]=s;if(s.init){s.init(F,t)}}});if(G.popup_css!==false){if(G.popup_css){G.popup_css=F.documentBaseURI.toAbsolute(G.popup_css)}else{G.popup_css=F.baseURI.toAbsolute(\"themes/\"+G.theme+\"/skins/\"+G.skin+\"/dialog.css\")}}if(G.popup_css_add){G.popup_css+=\",\"+F.documentBaseURI.toAbsolute(G.popup_css_add)}F.controlManager=new n.ControlManager(F);F.undoManager=new n.UndoManager(F);F.undoManager.onAdd.add(function(t,s){if(!s.initial){return F.onChange.dispatch(F,s,t)}});F.undoManager.onUndo.add(function(t,s){return F.onUndo.dispatch(F,s,t)});F.undoManager.onRedo.add(function(t,s){return F.onRedo.dispatch(F,s,t)});if(G.custom_undo_redo){F.onExecCommand.add(function(t,w,u,H,s){if(w!=\"Undo\"&&w!=\"Redo\"&&w!=\"mceRepaint\"&&(!s||!s.skip_undo)){F.undoManager.add()}})}F.onExecCommand.add(function(s,t){if(!/^(FontName|FontSize)$/.test(t)){F.nodeChanged()}});if(a){function x(s,t){if(!t||!t.initial){F.execCommand(\"mceRepaint\")}}F.onUndo.add(x);F.onRedo.add(x);F.onSetContent.add(x)}F.onBeforeRenderUI.dispatch(F,F.controlManager);if(G.render_ui){C=G.width||B.style.width||B.offsetWidth;z=G.height||B.style.height||B.offsetHeight;F.orgDisplay=B.style.display;E=/^[0-9\\.]+(|px)$/i;if(E.test(\"\"+C)){C=Math.max(parseInt(C)+(r.deltaWidth||0),100)}if(E.test(\"\"+z)){z=Math.max(parseInt(z)+(r.deltaHeight||0),100)}r=F.theme.renderUI({targetNode:B,width:C,height:z,deltaWidth:G.delta_width,deltaHeight:G.delta_height});F.editorContainer=r.editorContainer}if(document.domain&&location.hostname!=document.domain){n.relaxedDomain=document.domain}o.setStyles(r.sizeContainer||r.editorContainer,{width:C,height:z});z=(r.iframeHeight||z)+(typeof(z)==\"number\"?(r.deltaHeight||0):\"\");if(z<100){z=100}F.iframeHTML=G.doctype+'<html><head xmlns=\"http://www.w3.org/1999/xhtml\">';if(G.document_base_url!=n.documentBaseURL){F.iframeHTML+='<base href=\"'+F.documentBaseURI.getURI()+'\" />'}F.iframeHTML+='<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />';if(n.relaxedDomain){F.iframeHTML+='<script type=\"text/javascript\">document.domain = \"'+n.relaxedDomain+'\";<\\/script>'}y=G.body_id||\"tinymce\";if(y.indexOf(\"=\")!=-1){y=F.getParam(\"body_id\",\"\",\"hash\");y=y[F.id]||y}A=G.body_class||\"\";if(A.indexOf(\"=\")!=-1){A=F.getParam(\"body_class\",\"\",\"hash\");A=A[F.id]||\"\"}F.iframeHTML+='</head><body id=\"'+y+'\" class=\"mceContentBody '+A+'\"></body></html>';if(n.relaxedDomain){if(b||(n.isOpera&&parseFloat(opera.version())>=9.5)){D='javascript:(function(){document.open();document.domain=\"'+document.domain+'\";var ed = window.parent.tinyMCE.get(\"'+F.id+'\");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()'}else{if(n.isOpera){D='javascript:(function(){document.open();document.domain=\"'+document.domain+'\";document.close();ed.setupIframe();})()'}}}v=o.add(r.iframeContainer,\"iframe\",{id:F.id+\"_ifr\",src:D||'javascript:\"\"',frameBorder:\"0\",style:{width:\"100%\",height:z}});F.contentAreaContainer=r.iframeContainer;o.get(r.editorContainer).style.display=F.orgDisplay;o.get(F.id).style.display=\"none\";if(!b||!n.relaxedDomain){F.setupIframe()}B=v=r=null},setupIframe:function(){var z=this,A=z.settings,u=o.get(z.id),v=z.getDoc(),r,x;if(!b||!n.relaxedDomain){v.open();v.write(z.iframeHTML);v.close()}if(!b){try{if(!A.readonly){v.designMode=\"On\"}}catch(w){}}if(b){x=z.getBody();o.hide(x);if(!A.readonly){x.contentEditable=true}o.show(x)}z.dom=new n.dom.DOMUtils(z.getDoc(),{keep_values:true,url_converter:z.convertURL,url_converter_scope:z,hex_colors:A.force_hex_style_colors,class_filter:A.class_filter,update_styles:1,fix_ie_paragraphs:1});z.serializer=new n.dom.Serializer(f(A,{valid_elements:A.verify_html===false?\"*[*]\":A.valid_elements,dom:z.dom}));z.selection=new n.dom.Selection(z.dom,z.getWin(),z.serializer);z.forceBlocks=new n.ForceBlocks(z,{forced_root_block:A.forced_root_block});z.editorCommands=new n.EditorCommands(z);z.serializer.onPreProcess.add(function(s,t){return z.onPreProcess.dispatch(z,t,s)});z.serializer.onPostProcess.add(function(s,t){return z.onPostProcess.dispatch(z,t,s)});z.onPreInit.dispatch(z);if(!A.gecko_spellcheck){z.getBody().spellcheck=0}if(!A.readonly){z._addEvents()}z.controlManager.onPostRender.dispatch(z,z.controlManager);z.onPostRender.dispatch(z);if(A.directionality){z.getBody().dir=A.directionality}if(A.nowrap){z.getBody().style.whiteSpace=\"nowrap\"}if(A.custom_elements){function y(s,t){j(g(A.custom_elements),function(B){var C;if(B.indexOf(\"~\")===0){B=B.substring(1);C=\"span\"}else{C=\"div\"}t.content=t.content.replace(new RegExp(\"<(\"+B+\")([^>]*)>\",\"g\"),\"<\"+C+' mce_name=\"$1\"$2>');t.content=t.content.replace(new RegExp(\"</(\"+B+\")>\",\"g\"),\"</\"+C+\">\")})}z.onBeforeSetContent.add(y);z.onPostProcess.add(function(s,t){if(t.set){y(s,t)}})}if(A.handle_node_change_callback){z.onNodeChange.add(function(t,s,B){z.execCallback(\"handle_node_change_callback\",z.id,B,-1,-1,true,z.selection.isCollapsed())})}if(A.save_callback){z.onSaveContent.add(function(s,B){var t=z.execCallback(\"save_callback\",z.id,B.content,z.getBody());if(t){B.content=t}})}if(A.onchange_callback){z.onChange.add(function(t,s){z.execCallback(\"onchange_callback\",z,s)})}if(A.convert_newlines_to_brs){z.onBeforeSetContent.add(function(s,t){if(t.initial){t.content=t.content.replace(/\\r?\\n/g,\"<br />\")}})}if(A.fix_nesting&&b){z.onBeforeSetContent.add(function(s,t){t.content=z._fixNesting(t.content)})}if(A.preformatted){z.onPostProcess.add(function(s,t){t.content=t.content.replace(/^\\s*<pre.*?>/,\"\");t.content=t.content.replace(/<\\/pre>\\s*$/,\"\");if(t.set){t.content='<pre class=\"mceItemHidden\">'+t.content+\"</pre>\"}})}if(A.verify_css_classes){z.serializer.attribValueFilter=function(D,B){var C,t;if(D==\"class\"){if(!z.classesRE){t=z.dom.getClasses();if(t.length>0){C=\"\";j(t,function(s){C+=(C?\"|\":\"\")+s[\"class\"]});z.classesRE=new RegExp(\"(\"+C+\")\",\"gi\")}}return !z.classesRE||/(\\bmceItem\\w+\\b|\\bmceTemp\\w+\\b)/g.test(B)||z.classesRE.test(B)?B:\"\"}return B}}if(A.convert_fonts_to_spans){z._convertFonts()}if(A.inline_styles){z._convertInlineElements()}if(A.cleanup_callback){z.onBeforeSetContent.add(function(s,t){t.content=z.execCallback(\"cleanup_callback\",\"insert_to_editor\",t.content,t)});z.onPreProcess.add(function(s,t){if(t.set){z.execCallback(\"cleanup_callback\",\"insert_to_editor_dom\",t.node,t)}if(t.get){z.execCallback(\"cleanup_callback\",\"get_from_editor_dom\",t.node,t)}});z.onPostProcess.add(function(s,t){if(t.set){t.content=z.execCallback(\"cleanup_callback\",\"insert_to_editor\",t.content,t)}if(t.get){t.content=z.execCallback(\"cleanup_callback\",\"get_from_editor\",t.content,t)}})}if(A.save_callback){z.onGetContent.add(function(s,t){if(t.save){t.content=z.execCallback(\"save_callback\",z.id,t.content,z.getBody())}})}if(A.handle_event_callback){z.onEvent.add(function(s,t,B){if(z.execCallback(\"handle_event_callback\",t,s,B)===false){k.cancel(t)}})}z.onSetContent.add(function(){z.addVisual(z.getBody())});if(A.padd_empty_editor){z.onPostProcess.add(function(s,t){t.content=t.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\\s|\\u00a0|)<\\/p>[\\r\\n]*|<br \\/>[\\r\\n]*)$/,\"\")})}if(a){function q(s,t){j(s.dom.select(\"a\"),function(C){var B=C.parentNode;if(s.dom.isBlock(B)&&B.lastChild===C){s.dom.add(B,\"br\",{mce_bogus:1})}})}z.onExecCommand.add(function(s,t){if(t===\"CreateLink\"){q(s)}});z.onSetContent.add(z.selection.onSetContent.add(q));if(!A.readonly){try{v.designMode=\"Off\";v.designMode=\"On\"}catch(w){}}}setTimeout(function(){if(z.removed){return}z.load({initial:true,format:(A.cleanup_on_startup?\"html\":\"raw\")});z.startContent=z.getContent({format:\"raw\"});z.undoManager.add({initial:true});z.initialized=true;z.onInit.dispatch(z);z.execCallback(\"setupcontent_callback\",z.id,z.getBody(),z.getDoc());z.execCallback(\"init_instance_callback\",z);z.focus(true);z.nodeChanged({initial:1});if(A.content_css){n.each(g(A.content_css),function(s){z.dom.loadCSS(z.documentBaseURI.toAbsolute(s))})}if(A.auto_focus){setTimeout(function(){var s=i.get(A.auto_focus);s.selection.select(s.getBody(),1);s.selection.collapse(1);s.getWin().focus()},100)}},1);u=null},focus:function(r){var u,q=this,s=q.settings.content_editable;if(!r){if(!s&&(!b||q.selection.getNode().ownerDocument!=q.getDoc())){q.getWin().focus()}}if(i.activeEditor!=q){if((u=i.activeEditor)!=null){u.onDeactivate.dispatch(u,q)}q.onActivate.dispatch(q,u)}i._setActive(q)},execCallback:function(v){var q=this,u=q.settings[v],r;if(!u){return}if(q.callbackLookup&&(r=q.callbackLookup[v])){u=r.func;r=r.scope}if(d(u,\"string\")){r=u.replace(/\\.\\w+$/,\"\");r=r?n.resolve(r):0;u=n.resolve(u);q.callbackLookup=q.callbackLookup||{};q.callbackLookup[v]={func:u,scope:r}}return u.apply(r||q,Array.prototype.slice.call(arguments,1))},translate:function(q){var t=this.settings.language||\"en\",r=i.i18n;if(!q){return\"\"}return r[t+\".\"+q]||q.replace(/{\\#([^}]+)\\}/g,function(u,s){return r[t+\".\"+s]||\"{#\"+s+\"}\"})},getLang:function(r,q){return i.i18n[(this.settings.language||\"en\")+\".\"+r]||(d(q)?q:\"{#\"+r+\"}\")},getParam:function(w,s,q){var t=n.trim,r=d(this.settings[w])?this.settings[w]:s,u;if(q===\"hash\"){u={};if(d(r,\"string\")){j(r.indexOf(\"=\")>0?r.split(/[;,](?![^=;,]*(?:[;,]|$))/):r.split(\",\"),function(x){x=x.split(\"=\");if(x.length>1){u[t(x[0])]=t(x[1])}else{u[t(x[0])]=t(x)}})}else{u=r}return u}return r},nodeChanged:function(u){var q=this,r=q.selection,v=r.getNode()||q.getBody();if(q.initialized){q.onNodeChange.dispatch(q,u?u.controlManager||q.controlManager:q.controlManager,b&&v.ownerDocument!=q.getDoc()?q.getBody():v,r.isCollapsed(),u)}},addButton:function(u,r){var q=this;q.buttons=q.buttons||{};q.buttons[u]=r},addCommand:function(t,r,q){this.execCommands[t]={func:r,scope:q||this}},addQueryStateHandler:function(t,r,q){this.queryStateCommands[t]={func:r,scope:q||this}},addQueryValueHandler:function(t,r,q){this.queryValueCommands[t]={func:r,scope:q||this}},addShortcut:function(s,v,q,u){var r=this,w;if(!r.settings.custom_shortcuts){return false}r.shortcuts=r.shortcuts||{};if(d(q,\"string\")){w=q;q=function(){r.execCommand(w,false,null)}}if(d(q,\"object\")){w=q;q=function(){r.execCommand(w[0],w[1],w[2])}}j(g(s),function(t){var x={func:q,scope:u||this,desc:v,alt:false,ctrl:false,shift:false};j(g(t,\"+\"),function(y){switch(y){case\"alt\":case\"ctrl\":case\"shift\":x[y]=true;break;default:x.charCode=y.charCodeAt(0);x.keyCode=y.toUpperCase().charCodeAt(0)}});r.shortcuts[(x.ctrl?\"ctrl\":\"\")+\",\"+(x.alt?\"alt\":\"\")+\",\"+(x.shift?\"shift\":\"\")+\",\"+x.keyCode]=x});return true},execCommand:function(x,w,z,q){var u=this,v=0,y,r;if(!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(x)&&(!q||!q.skip_focus)){u.focus()}y={};u.onBeforeExecCommand.dispatch(u,x,w,z,y);if(y.terminate){return false}if(u.execCallback(\"execcommand_callback\",u.id,u.selection.getNode(),x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);return true}if(y=u.execCommands[x]){r=y.func.call(y.scope,w,z);if(r!==true){u.onExecCommand.dispatch(u,x,w,z,q);return r}}j(u.plugins,function(s){if(s.execCommand&&s.execCommand(x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);v=1;return false}});if(v){return true}if(u.theme&&u.theme.execCommand&&u.theme.execCommand(x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);return true}if(n.GlobalCommands.execCommand(u,x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);return true}if(u.editorCommands.execCommand(x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);return true}u.getDoc().execCommand(x,w,z);u.onExecCommand.dispatch(u,x,w,z,q)},queryCommandState:function(w){var r=this,v,u;if(r._isHidden()){return}if(v=r.queryStateCommands[w]){u=v.func.call(v.scope);if(u!==true){return u}}v=r.editorCommands.queryCommandState(w);if(v!==-1){return v}try{return this.getDoc().queryCommandState(w)}catch(q){}},queryCommandValue:function(w){var r=this,v,u;if(r._isHidden()){return}if(v=r.queryValueCommands[w]){u=v.func.call(v.scope);if(u!==true){return u}}v=r.editorCommands.queryCommandValue(w);if(d(v)){return v}try{return this.getDoc().queryCommandValue(w)}catch(q){}},show:function(){var q=this;o.show(q.getContainer());o.hide(q.id);q.load()},hide:function(){var q=this,r=q.getDoc();if(b&&r){r.execCommand(\"SelectAll\")}q.save();o.hide(q.getContainer());o.setStyle(q.id,\"display\",q.orgDisplay)},isHidden:function(){return !o.isHidden(this.id)},setProgressState:function(q,r,s){this.onSetProgressState.dispatch(this,q,r,s);return q},load:function(u){var q=this,s=q.getElement(),r;if(s){u=u||{};u.load=true;r=q.setContent(d(s.value)?s.value:s.innerHTML,u);u.element=s;if(!u.no_events){q.onLoadContent.dispatch(q,u)}u.element=s=null;return r}},save:function(v){var q=this,u=q.getElement(),r,s;if(!u||!q.initialized){return}v=v||{};v.save=true;if(!v.no_events){q.undoManager.typing=0;q.undoManager.add()}v.element=u;r=v.content=q.getContent(v);if(!v.no_events){q.onSaveContent.dispatch(q,v)}r=v.content;if(!/TEXTAREA|INPUT/i.test(u.nodeName)){u.innerHTML=r;if(s=o.getParent(q.id,\"form\")){j(s.elements,function(t){if(t.name==q.id){t.value=r;return false}})}}else{u.value=r}v.element=u=null;return r},setContent:function(r,s){var q=this;s=s||{};s.format=s.format||\"html\";s.set=true;s.content=r;if(!s.no_events){q.onBeforeSetContent.dispatch(q,s)}if(!n.isIE&&(r.length===0||/^\\s+$/.test(r))){s.content=q.dom.setHTML(q.getBody(),'<br mce_bogus=\"1\" />');s.format=\"raw\"}s.content=q.dom.setHTML(q.getBody(),n.trim(s.content));if(s.format!=\"raw\"&&q.settings.cleanup){s.getInner=true;s.content=q.dom.setHTML(q.getBody(),q.serializer.serialize(q.getBody(),s))}if(!s.no_events){q.onSetContent.dispatch(q,s)}return s.content},getContent:function(s){var q=this,r;s=s||{};s.format=s.format||\"html\";s.get=true;if(!s.no_events){q.onBeforeGetContent.dispatch(q,s)}if(s.format!=\"raw\"&&q.settings.cleanup){s.getInner=true;r=q.serializer.serialize(q.getBody(),s)}else{r=q.getBody().innerHTML}r=r.replace(/^\\s*|\\s*$/g,\"\");s.content=r;if(!s.no_events){q.onGetContent.dispatch(q,s)}return s.content},isDirty:function(){var q=this;return n.trim(q.startContent)!=n.trim(q.getContent({format:\"raw\",no_events:1}))&&!q.isNotDirty},getContainer:function(){var q=this;if(!q.container){q.container=o.get(q.editorContainer||q.id+\"_parent\")}return q.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return o.get(this.settings.content_element||this.id)},getWin:function(){var q=this,r;if(!q.contentWindow){r=o.get(q.id+\"_ifr\");if(r){q.contentWindow=r.contentWindow}}return q.contentWindow},getDoc:function(){var r=this,q;if(!r.contentDocument){q=r.getWin();if(q){r.contentDocument=q.document}}return r.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(q,x,w){var r=this,v=r.settings;if(v.urlconverter_callback){return r.execCallback(\"urlconverter_callback\",q,w,true,x)}if(!v.convert_urls||(w&&w.nodeName==\"LINK\")||q.indexOf(\"file:\")===0){return q}if(v.relative_urls){return r.documentBaseURI.toRelative(q)}q=r.documentBaseURI.toAbsolute(q,v.remove_script_host);return q},addVisual:function(u){var q=this,r=q.settings;u=u||q.getBody();if(!d(q.hasVisual)){q.hasVisual=r.visual}j(q.dom.select(\"table,a\",u),function(t){var s;switch(t.nodeName){case\"TABLE\":s=q.dom.getAttrib(t,\"border\");if(!s||s==\"0\"){if(q.hasVisual){q.dom.addClass(t,r.visual_table_class)}else{q.dom.removeClass(t,r.visual_table_class)}}return;case\"A\":s=q.dom.getAttrib(t,\"name\");if(s){if(q.hasVisual){q.dom.addClass(t,\"mceItemAnchor\")}else{q.dom.removeClass(t,\"mceItemAnchor\")}}return}});q.onVisualAid.dispatch(q,u,q.hasVisual)},remove:function(){var q=this,r=q.getContainer();q.removed=1;q.hide();q.execCallback(\"remove_instance_callback\",q);q.onRemove.dispatch(q);q.onExecCommand.listeners=[];i.remove(q);o.remove(r)},destroy:function(r){var q=this;if(q.destroyed){return}if(!r){n.removeUnload(q.destroy);tinyMCE.onBeforeUnload.remove(q._beforeUnload);if(q.theme&&q.theme.destroy){q.theme.destroy()}q.controlManager.destroy();q.selection.destroy();q.dom.destroy();if(!q.settings.content_editable){k.clear(q.getWin());k.clear(q.getDoc())}k.clear(q.getBody());k.clear(q.formElement)}if(q.formElement){q.formElement.submit=q.formElement._mceOldSubmit;q.formElement._mceOldSubmit=null}q.contentAreaContainer=q.formElement=q.container=q.settings.content_element=q.bodyElement=q.contentDocument=q.contentWindow=null;if(q.selection){q.selection=q.selection.win=q.selection.dom=q.selection.dom.doc=null}q.destroyed=1},_addEvents:function(){var w=this,v,y=w.settings,x={mouseup:\"onMouseUp\",mousedown:\"onMouseDown\",click:\"onClick\",keyup:\"onKeyUp\",keydown:\"onKeyDown\",keypress:\"onKeyPress\",submit:\"onSubmit\",reset:\"onReset\",contextmenu:\"onContextMenu\",dblclick:\"onDblClick\",paste:\"onPaste\"};function u(t,A){var s=t.type;if(w.removed){return}if(w.onEvent.dispatch(w,t,A)!==false){w[x[t.fakeType||t.type]].dispatch(w,t,A)}}j(x,function(t,s){switch(s){case\"contextmenu\":if(n.isOpera){w.dom.bind(w.getBody(),\"mousedown\",function(A){if(A.ctrlKey){A.fakeType=\"contextmenu\";u(A)}})}else{w.dom.bind(w.getBody(),s,u)}break;case\"paste\":w.dom.bind(w.getBody(),s,function(A){u(A)});break;case\"submit\":case\"reset\":w.dom.bind(w.getElement().form||o.getParent(w.id,\"form\"),s,u);break;default:w.dom.bind(y.content_editable?w.getBody():w.getDoc(),s,u)}});w.dom.bind(y.content_editable?w.getBody():(a?w.getDoc():w.getWin()),\"focus\",function(s){w.focus(true)});if(n.isGecko){w.dom.bind(w.getDoc(),\"DOMNodeInserted\",function(t){var s;t=t.target;if(t.nodeType===1&&t.nodeName===\"IMG\"&&(s=t.getAttribute(\"mce_src\"))){t.src=w.documentBaseURI.toAbsolute(s)}})}if(a){function q(){var B=this,D=B.getDoc(),C=B.settings;if(a&&!C.readonly){if(B._isHidden()){try{if(!C.content_editable){D.designMode=\"On\"}}catch(A){}}try{D.execCommand(\"styleWithCSS\",0,false)}catch(A){if(!B._isHidden()){try{D.execCommand(\"useCSS\",0,true)}catch(A){}}}if(!C.table_inline_editing){try{D.execCommand(\"enableInlineTableEditing\",false,false)}catch(A){}}if(!C.object_resizing){try{D.execCommand(\"enableObjectResizing\",false,false)}catch(A){}}}}w.onBeforeExecCommand.add(q);w.onMouseDown.add(q)}w.onMouseUp.add(w.nodeChanged);w.onClick.add(w.nodeChanged);w.onKeyUp.add(function(s,t){var A=t.keyCode;if((A>=33&&A<=36)||(A>=37&&A<=40)||A==13||A==45||A==46||A==8||(n.isMac&&(A==91||A==93))||t.ctrlKey){w.nodeChanged()}});w.onReset.add(function(){w.setContent(w.startContent,{format:\"raw\"})});if(y.custom_shortcuts){if(y.custom_undo_redo_keyboard_shortcuts){w.addShortcut(\"ctrl+z\",w.getLang(\"undo_desc\"),\"Undo\");w.addShortcut(\"ctrl+y\",w.getLang(\"redo_desc\"),\"Redo\")}if(a){w.addShortcut(\"ctrl+b\",w.getLang(\"bold_desc\"),\"Bold\");w.addShortcut(\"ctrl+i\",w.getLang(\"italic_desc\"),\"Italic\");w.addShortcut(\"ctrl+u\",w.getLang(\"underline_desc\"),\"Underline\")}for(v=1;v<=6;v++){w.addShortcut(\"ctrl+\"+v,\"\",[\"FormatBlock\",false,\"<h\"+v+\">\"])}w.addShortcut(\"ctrl+7\",\"\",[\"FormatBlock\",false,\"<p>\"]);w.addShortcut(\"ctrl+8\",\"\",[\"FormatBlock\",false,\"<div>\"]);w.addShortcut(\"ctrl+9\",\"\",[\"FormatBlock\",false,\"<address>\"]);function z(t){var s=null;if(!t.altKey&&!t.ctrlKey&&!t.metaKey){return s}j(w.shortcuts,function(A){if(n.isMac&&A.ctrl!=t.metaKey){return}else{if(!n.isMac&&A.ctrl!=t.ctrlKey){return}}if(A.alt!=t.altKey){return}if(A.shift!=t.shiftKey){return}if(t.keyCode==A.keyCode||(t.charCode&&t.charCode==A.charCode)){s=A;return false}});return s}w.onKeyUp.add(function(s,t){var A=z(t);if(A){return k.cancel(t)}});w.onKeyPress.add(function(s,t){var A=z(t);if(A){return k.cancel(t)}});w.onKeyDown.add(function(s,t){var A=z(t);if(A){A.func.call(A.scope);return k.cancel(t)}})}if(n.isIE){w.dom.bind(w.getDoc(),\"controlselect\",function(A){var t=w.resizeInfo,s;A=A.target;if(A.nodeName!==\"IMG\"){return}if(t){w.dom.unbind(t.node,t.ev,t.cb)}if(!w.dom.hasClass(A,\"mceItemNoResize\")){ev=\"resizeend\";s=w.dom.bind(A,ev,function(C){var B;C=C.target;if(B=w.dom.getStyle(C,\"width\")){w.dom.setAttrib(C,\"width\",B.replace(/[^0-9%]+/g,\"\"));w.dom.setStyle(C,\"width\",\"\")}if(B=w.dom.getStyle(C,\"height\")){w.dom.setAttrib(C,\"height\",B.replace(/[^0-9%]+/g,\"\"));w.dom.setStyle(C,\"height\",\"\")}})}else{ev=\"resizestart\";s=w.dom.bind(A,\"resizestart\",k.cancel,k)}t=w.resizeInfo={node:A,ev:ev,cb:s}});w.onKeyDown.add(function(s,t){switch(t.keyCode){case 8:if(w.selection.getRng().item){w.selection.getRng().item(0).removeNode();return k.cancel(t)}}})}if(n.isOpera){w.onClick.add(function(s,t){k.prevent(t)})}if(y.custom_undo_redo){function r(){w.undoManager.typing=0;w.undoManager.add()}if(n.isIE){w.dom.bind(w.getWin(),\"blur\",function(s){var t;if(w.selection){t=w.selection.getNode();if(!w.removed&&t.ownerDocument&&t.ownerDocument!=w.getDoc()){r()}}})}else{w.dom.bind(w.getDoc(),\"blur\",function(){if(w.selection&&!w.removed){r()}})}w.onMouseDown.add(r);w.onKeyUp.add(function(s,t){if((t.keyCode>=33&&t.keyCode<=36)||(t.keyCode>=37&&t.keyCode<=40)||t.keyCode==13||t.keyCode==45||t.ctrlKey){w.undoManager.typing=0;w.undoManager.add()}});w.onKeyDown.add(function(s,t){if((t.keyCode>=33&&t.keyCode<=36)||(t.keyCode>=37&&t.keyCode<=40)||t.keyCode==13||t.keyCode==45){if(w.undoManager.typing){w.undoManager.add();w.undoManager.typing=0}return}if(!w.undoManager.typing){w.undoManager.add();w.undoManager.typing=1}})}},_convertInlineElements:function(){var z=this,B=z.settings,r=z.dom,y,w,u,A,q;function x(s,t){if(!B.inline_styles){return}if(t.get){j(z.dom.select(\"table,u,strike\",t.node),function(v){switch(v.nodeName){case\"TABLE\":if(y=r.getAttrib(v,\"height\")){r.setStyle(v,\"height\",y);r.setAttrib(v,\"height\",\"\")}break;case\"U\":case\"STRIKE\":v.style.textDecoration=v.nodeName==\"U\"?\"underline\":\"line-through\";r.setAttrib(v,\"mce_style\",\"\");r.setAttrib(v,\"mce_name\",\"span\");break}})}else{if(t.set){j(z.dom.select(\"table,span\",t.node).reverse(),function(v){if(v.nodeName==\"TABLE\"){if(y=r.getStyle(v,\"height\")){r.setAttrib(v,\"height\",y.replace(/[^0-9%]+/g,\"\"))}}else{if(v.style.textDecoration==\"underline\"){u=\"u\"}else{if(v.style.textDecoration==\"line-through\"){u=\"strike\"}else{u=\"\"}}if(u){v.style.textDecoration=\"\";r.setAttrib(v,\"mce_style\",\"\");w=r.create(u,{style:r.getAttrib(v,\"style\")});r.replace(w,v,1)}}})}}}z.onPreProcess.add(x);if(!B.cleanup_on_startup){z.onSetContent.add(function(s,t){if(t.initial){x(z,{node:z.getBody(),set:1})}})}},_convertFonts:function(){var w=this,x=w.settings,z=w.dom,v,r,q,u;if(!x.inline_styles){return}v=[8,10,12,14,18,24,36];r=[\"xx-small\",\"x-small\",\"small\",\"medium\",\"large\",\"x-large\",\"xx-large\"];if(q=x.font_size_style_values){q=g(q)}if(u=x.font_size_classes){u=g(u)}function y(B){var C,A,t,s;if(!x.inline_styles){return}t=w.dom.select(\"font\",B);for(s=t.length-1;s>=0;s--){C=t[s];A=z.create(\"span\",{style:z.getAttrib(C,\"style\"),\"class\":z.getAttrib(C,\"class\")});z.setStyles(A,{fontFamily:z.getAttrib(C,\"face\"),color:z.getAttrib(C,\"color\"),backgroundColor:C.style.backgroundColor});if(C.size){if(q){z.setStyle(A,\"fontSize\",q[parseInt(C.size)-1])}else{z.setAttrib(A,\"class\",u[parseInt(C.size)-1])}}z.setAttrib(A,\"mce_style\",\"\");z.replace(A,C,1)}}w.onPreProcess.add(function(s,t){if(t.get){y(t.node)}});w.onSetContent.add(function(s,t){if(t.initial){y(t.node)}})},_isHidden:function(){var q;if(!a){return 0}q=this.selection.getSel();return(!q||!q.rangeCount||q.rangeCount==0)},_fixNesting:function(r){var t=[],q;r=r.replace(/<(\\/)?([^\\s>]+)[^>]*?>/g,function(u,s,w){var v;if(s===\"/\"){if(!t.length){return\"\"}if(w!==t[t.length-1].tag){for(q=t.length-1;q>=0;q--){if(t[q].tag===w){t[q].close=1;break}}return\"\"}else{t.pop();if(t.length&&t[t.length-1].close){u=u+\"</\"+t[t.length-1].tag+\">\";t.pop()}}}else{if(/^(br|hr|input|meta|img|link|param)$/i.test(w)){return u}if(/\\/>$/.test(u)){return u}t.push({tag:w})}return u});for(q=t.length-1;q>=0;q--){r+=\"</\"+t[q].tag+\">\"}return r}})})(tinymce);(function(d){var f=d.each,c=d.isIE,a=d.isGecko,b=d.isOpera,e=d.isWebKit;d.create(\"tinymce.EditorCommands\",{EditorCommands:function(g){this.editor=g},execCommand:function(k,j,l){var h=this,g=h.editor,i;switch(k){case\"mceResetDesignMode\":case\"mceBeginUndoLevel\":return true;case\"unlink\":h.UnLink();return true;case\"JustifyLeft\":case\"JustifyCenter\":case\"JustifyRight\":case\"JustifyFull\":h.mceJustify(k,k.substring(7).toLowerCase());return true;default:i=this[k];if(i){i.call(this,j,l);return true}}return false},Indent:function(){var g=this.editor,l=g.dom,j=g.selection,k,h,i;h=g.settings.indentation;i=/[a-z%]+$/i.exec(h);h=parseInt(h);if(g.settings.inline_styles&&(!this.queryStateInsertUnorderedList()&&!this.queryStateInsertOrderedList())){f(j.getSelectedBlocks(),function(m){l.setStyle(m,\"paddingLeft\",(parseInt(m.style.paddingLeft||0)+h)+i)});return}g.getDoc().execCommand(\"Indent\",false,null);if(c){l.getParent(j.getNode(),function(m){if(m.nodeName==\"BLOCKQUOTE\"){m.dir=m.style.cssText=\"\"}})}},Outdent:function(){var h=this.editor,m=h.dom,k=h.selection,l,g,i,j;i=h.settings.indentation;j=/[a-z%]+$/i.exec(i);i=parseInt(i);if(h.settings.inline_styles&&(!this.queryStateInsertUnorderedList()&&!this.queryStateInsertOrderedList())){f(k.getSelectedBlocks(),function(n){g=Math.max(0,parseInt(n.style.paddingLeft||0)-i);m.setStyle(n,\"paddingLeft\",g?g+j:\"\")});return}h.getDoc().execCommand(\"Outdent\",false,null)},mceSetContent:function(h,g){this.editor.setContent(g)},mceToggleVisualAid:function(){var g=this.editor;g.hasVisual=!g.hasVisual;g.addVisual()},mceReplaceContent:function(h,g){var i=this.editor.selection;i.setContent(g.replace(/\\{\\$selection\\}/g,i.getContent({format:\"text\"})))},mceInsertLink:function(i,h){var g=this.editor,j=g.selection,k=g.dom.getParent(j.getNode(),\"a\");if(d.is(h,\"string\")){h={href:h}}function l(m){f(h,function(o,n){g.dom.setAttrib(m,n,o)})}if(!k){g.execCommand(\"CreateLink\",false,\"javascript:mctmp(0);\");f(g.dom.select(\"a[href=javascript:mctmp(0);]\"),function(m){l(m)})}else{if(h.href){l(k)}else{g.dom.remove(k,1)}}},UnLink:function(){var g=this.editor,h=g.selection;if(h.isCollapsed()){h.select(h.getNode())}g.getDoc().execCommand(\"unlink\",false,null);h.collapse(0)},FontName:function(i,h){var j=this,g=j.editor,k=g.selection,l;if(!h){if(k.isCollapsed()){k.select(k.getNode())}}else{if(g.settings.convert_fonts_to_spans){j._applyInlineStyle(\"span\",{style:{fontFamily:h}})}else{g.getDoc().execCommand(\"FontName\",false,h)}}},FontSize:function(j,i){var h=this.editor,l=h.settings,k,g;if(l.convert_fonts_to_spans&&i>=1&&i<=7){g=d.explode(l.font_size_style_values);k=d.explode(l.font_size_classes);if(k){i=k[i-1]||i}else{i=g[i-1]||i}}if(i>=1&&i<=7){h.getDoc().execCommand(\"FontSize\",false,i)}else{this._applyInlineStyle(\"span\",{style:{fontSize:i}})}},queryCommandValue:function(h){var g=this[\"queryValue\"+h];if(g){return g.call(this,h)}return false},queryCommandState:function(h){var g;switch(h){case\"JustifyLeft\":case\"JustifyCenter\":case\"JustifyRight\":case\"JustifyFull\":return this.queryStateJustify(h,h.substring(7).toLowerCase());default:if(g=this[\"queryState\"+h]){return g.call(this,h)}}return -1},_queryState:function(h){try{return this.editor.getDoc().queryCommandState(h)}catch(g){}},_queryVal:function(h){try{return this.editor.getDoc().queryCommandValue(h)}catch(g){}},queryValueFontSize:function(){var h=this.editor,g=0,i;if(i=h.dom.getParent(h.selection.getNode(),\"span\")){g=i.style.fontSize}if(!g&&(b||e)){if(i=h.dom.getParent(h.selection.getNode(),\"font\")){g=i.size}return g}return g||this._queryVal(\"FontSize\")},queryValueFontName:function(){var h=this.editor,g=0,i;if(i=h.dom.getParent(h.selection.getNode(),\"font\")){g=i.face}if(i=h.dom.getParent(h.selection.getNode(),\"span\")){g=i.style.fontFamily.replace(/, /g,\",\").replace(/[\\'\\\"]/g,\"\").toLowerCase()}if(!g){g=this._queryVal(\"FontName\")}return g},mceJustify:function(o,p){var k=this.editor,m=k.selection,g=m.getNode(),q=g.nodeName,h,j,i=k.dom,l;if(k.settings.inline_styles&&this.queryStateJustify(o,p)){l=1}h=i.getParent(g,k.dom.isBlock);if(q==\"IMG\"){if(p==\"full\"){return}if(l){if(p==\"center\"){i.setStyle(h||g.parentNode,\"textAlign\",\"\")}i.setStyle(g,\"float\",\"\");this.mceRepaint();return}if(p==\"center\"){if(h&&/^(TD|TH)$/.test(h.nodeName)){h=0}if(!h||h.childNodes.length>1){j=i.create(\"p\");j.appendChild(g.cloneNode(false));if(h){i.insertAfter(j,h)}else{i.insertAfter(j,g)}i.remove(g);g=j.firstChild;h=j}i.setStyle(h,\"textAlign\",p);i.setStyle(g,\"float\",\"\")}else{i.setStyle(g,\"float\",p);i.setStyle(h||g.parentNode,\"textAlign\",\"\")}this.mceRepaint();return}if(k.settings.inline_styles&&k.settings.forced_root_block){if(l){p=\"\"}f(m.getSelectedBlocks(i.getParent(m.getStart(),i.isBlock),i.getParent(m.getEnd(),i.isBlock)),function(n){i.setAttrib(n,\"align\",\"\");i.setStyle(n,\"textAlign\",p==\"full\"?\"justify\":p)});return}else{if(!l){k.getDoc().execCommand(o,false,null)}}if(k.settings.inline_styles){if(l){i.getParent(k.selection.getNode(),function(r){if(r.style&&r.style.textAlign){i.setStyle(r,\"textAlign\",\"\")}});return}f(i.select(\"*\"),function(s){var r=s.align;if(r){if(r==\"full\"){r=\"justify\"}i.setStyle(s,\"textAlign\",r);i.setAttrib(s,\"align\",\"\")}})}},mceSetCSSClass:function(h,g){this.mceSetStyleInfo(0,{command:\"setattrib\",name:\"class\",value:g})},getSelectedElement:function(){var w=this,o=w.editor,n=o.dom,s=o.selection,h=s.getRng(),l,k,u,p,j,g,q,i,x,v;if(s.isCollapsed()||h.item){return s.getNode()}v=o.settings.merge_styles_invalid_parents;if(d.is(v,\"string\")){v=new RegExp(v,\"i\")}if(c){l=h.duplicate();l.collapse(true);u=l.parentElement();k=h.duplicate();k.collapse(false);p=k.parentElement();if(u!=p){l.move(\"character\",1);u=l.parentElement()}if(u==p){l=h.duplicate();l.moveToElementText(u);if(l.compareEndPoints(\"StartToStart\",h)==0&&l.compareEndPoints(\"EndToEnd\",h)==0){return v&&v.test(u.nodeName)?null:u}}}else{function m(r){return n.getParent(r,\"*\")}u=h.startContainer;p=h.endContainer;j=h.startOffset;g=h.endOffset;if(!h.collapsed){if(u==p){if(j-g<2){if(u.hasChildNodes()){i=u.childNodes[j];return v&&v.test(i.nodeName)?null:i}}}}if(u.nodeType!=3||p.nodeType!=3){return null}if(j==0){i=m(u);if(i&&i.firstChild!=u){i=null}}if(j==u.nodeValue.length){q=u.nextSibling;if(q&&q.nodeType==1){i=u.nextSibling}}if(g==0){q=p.previousSibling;if(q&&q.nodeType==1){x=q}}if(g==p.nodeValue.length){x=m(p);if(x&&x.lastChild!=p){x=null}}if(i==x){return v&&i&&v.test(i.nodeName)?null:i}}return null},mceSetStyleInfo:function(n,m){var q=this,h=q.editor,j=h.getDoc(),g=h.dom,i,k,r=h.selection,p=m.wrapper||\"span\",k=r.getBookmark(),o;function l(t,s){if(t.nodeType==1){switch(m.command){case\"setattrib\":return g.setAttrib(t,m.name,m.value);case\"setstyle\":return g.setStyle(t,m.name,m.value);case\"removeformat\":return g.setAttrib(t,\"class\",\"\")}}}o=h.settings.merge_styles_invalid_parents;if(d.is(o,\"string\")){o=new RegExp(o,\"i\")}if((i=q.getSelectedElement())&&!h.settings.force_span_wrappers){l(i,1)}else{j.execCommand(\"FontName\",false,\"__\");f(g.select(\"span,font\"),function(u){var s,t;if(g.getAttrib(u,\"face\")==\"__\"||u.style.fontFamily===\"__\"){s=g.create(p,{mce_new:\"1\"});l(s);f(u.childNodes,function(v){s.appendChild(v.cloneNode(true))});g.replace(s,u)}})}f(g.select(p).reverse(),function(t){var s=t.parentNode;if(!g.getAttrib(t,\"mce_new\")){s=g.getParent(t,\"*[mce_new]\");if(s){g.remove(t,1)}}});f(g.select(p).reverse(),function(t){var s=t.parentNode;if(!s||!g.getAttrib(t,\"mce_new\")){return}if(h.settings.force_span_wrappers&&s.nodeName!=\"SPAN\"){return}if(s.nodeName==p.toUpperCase()&&s.childNodes.length==1){return g.remove(s,1)}if(t.nodeType==1&&(!o||!o.test(s.nodeName))&&s.childNodes.length==1){l(s);g.setAttrib(t,\"class\",\"\")}});f(g.select(p).reverse(),function(s){if(g.getAttrib(s,\"mce_new\")||(g.getAttribs(s).length<=1&&s.className===\"\")){if(!g.getAttrib(s,\"class\")&&!g.getAttrib(s,\"style\")){return g.remove(s,1)}g.setAttrib(s,\"mce_new\",\"\")}});r.moveToBookmark(k)},queryStateJustify:function(k,h){var g=this.editor,j=g.selection.getNode(),i=g.dom;if(j&&j.nodeName==\"IMG\"){if(i.getStyle(j,\"float\")==h){return 1}return j.parentNode.style.textAlign==h}j=i.getParent(g.selection.getStart(),function(l){return l.nodeType==1&&l.style.textAlign});if(h==\"full\"){h=\"justify\"}if(g.settings.inline_styles){return(j&&j.style.textAlign==h)}return this._queryState(k)},ForeColor:function(i,h){var g=this.editor;if(g.settings.convert_fonts_to_spans){this._applyInlineStyle(\"span\",{style:{color:h}});return}else{g.getDoc().execCommand(\"ForeColor\",false,h)}},HiliteColor:function(i,k){var h=this,g=h.editor,j=g.getDoc();if(g.settings.convert_fonts_to_spans){this._applyInlineStyle(\"span\",{style:{backgroundColor:k}});return}function l(n){if(!a){return}try{j.execCommand(\"styleWithCSS\",0,n)}catch(m){j.execCommand(\"useCSS\",0,!n)}}if(a||b){l(true);j.execCommand(\"hilitecolor\",false,k);l(false)}else{j.execCommand(\"BackColor\",false,k)}},FormatBlock:function(n,h){var o=this,l=o.editor,p=l.selection,j=l.dom,g,k,m;function i(q){return/^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(q.nodeName)}g=j.getParent(p.getNode(),function(q){return i(q)});if(g){if((c&&i(g.parentNode))||g.nodeName==\"DIV\"){k=l.dom.create(h);f(j.getAttribs(g),function(q){j.setAttrib(k,q.nodeName,j.getAttrib(g,q.nodeName))});m=p.getBookmark();j.replace(k,g,1);p.moveToBookmark(m);l.nodeChanged();return}}h=l.settings.forced_root_block?(h||\"<p>\"):h;if(h.indexOf(\"<\")==-1){h=\"<\"+h+\">\"}if(d.isGecko){h=h.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi,\"$1\")}l.getDoc().execCommand(\"FormatBlock\",false,h)},mceCleanup:function(){var h=this.editor,i=h.selection,g=i.getBookmark();h.setContent(h.getContent());i.moveToBookmark(g)},mceRemoveNode:function(j,k){var h=this.editor,i=h.selection,g,l=k||i.getNode();if(l==h.getBody()){return}g=i.getBookmark();h.dom.remove(l,1);i.moveToBookmark(g);h.nodeChanged()},mceSelectNodeDepth:function(i,j){var g=this.editor,h=g.selection,k=0;g.dom.getParent(h.getNode(),function(l){if(l.nodeType==1&&k++==j){h.select(l);g.nodeChanged();return false}},g.getBody())},mceSelectNode:function(h,g){this.editor.selection.select(g)},mceInsertContent:function(g,h){this.editor.selection.setContent(h)},mceInsertRawHTML:function(h,i){var g=this.editor;g.selection.setContent(\"tiny_mce_marker\");g.setContent(g.getContent().replace(/tiny_mce_marker/g,i))},mceRepaint:function(){var i,g,j=this.editor;if(d.isGecko){try{i=j.selection;g=i.getBookmark(true);if(i.getSel()){i.getSel().selectAllChildren(j.getBody())}i.collapse(true);i.moveToBookmark(g)}catch(h){}}},queryStateUnderline:function(){var g=this.editor,h=g.selection.getNode();if(h&&h.nodeName==\"A\"){return false}return this._queryState(\"Underline\")},queryStateOutdent:function(){var g=this.editor,h;if(g.settings.inline_styles){if((h=g.dom.getParent(g.selection.getStart(),g.dom.isBlock))&&parseInt(h.style.paddingLeft)>0){return true}if((h=g.dom.getParent(g.selection.getEnd(),g.dom.isBlock))&&parseInt(h.style.paddingLeft)>0){return true}}return this.queryStateInsertUnorderedList()||this.queryStateInsertOrderedList()||(!g.settings.inline_styles&&!!g.dom.getParent(g.selection.getNode(),\"BLOCKQUOTE\"))},queryStateInsertUnorderedList:function(){return this.editor.dom.getParent(this.editor.selection.getNode(),\"UL\")},queryStateInsertOrderedList:function(){return this.editor.dom.getParent(this.editor.selection.getNode(),\"OL\")},queryStatemceBlockQuote:function(){return !!this.editor.dom.getParent(this.editor.selection.getStart(),function(g){return g.nodeName===\"BLOCKQUOTE\"})},_applyInlineStyle:function(o,j,m){var q=this,n=q.editor,l=n.dom,i,p={},k,r;o=o.toUpperCase();if(m&&m.check_classes&&j[\"class\"]){m.check_classes.push(j[\"class\"])}function h(){f(l.select(o).reverse(),function(t){var s=0;f(l.getAttribs(t),function(u){if(u.nodeName.substring(0,1)!=\"_\"&&l.getAttrib(t,u.nodeName)!=\"\"){s++}});if(s==0){l.remove(t,1)}})}function g(){var s;f(l.select(\"span,font\"),function(t){if(t.style.fontFamily==\"mceinline\"||t.face==\"mceinline\"){if(!s){s=n.selection.getBookmark()}j._mce_new=\"1\";l.replace(l.create(o,j),t,1)}});f(l.select(o+\"[_mce_new]\"),function(u){function t(v){if(v.nodeType==1){f(j.style,function(x,w){l.setStyle(v,w,\"\")});if(j[\"class\"]&&v.className&&m){f(m.check_classes,function(w){if(l.hasClass(v,w)){l.removeClass(v,w)}})}}}f(l.select(o,u),t);if(u.parentNode&&u.parentNode.nodeType==1&&u.parentNode.childNodes.length==1){t(u.parentNode)}l.getParent(u.parentNode,function(v){if(v.nodeType==1){if(j.style){f(j.style,function(y,x){var w;if(!p[x]&&(w=l.getStyle(v,x))){if(w===y){l.setStyle(u,x,\"\")}p[x]=1}})}if(j[\"class\"]&&v.className&&m){f(m.check_classes,function(w){if(l.hasClass(v,w)){l.removeClass(u,w)}})}}return false});u.removeAttribute(\"_mce_new\")});h();n.selection.moveToBookmark(s);return !!s}n.focus();n.getDoc().execCommand(\"FontName\",false,\"mceinline\");g();if(k=q._applyInlineStyle.keyhandler){n.onKeyUp.remove(k);n.onKeyPress.remove(k);n.onKeyDown.remove(k);n.onSetContent.remove(q._applyInlineStyle.chandler)}if(n.selection.isCollapsed()){if(!c){f(l.getParents(n.selection.getNode(),\"span\"),function(s){f(j.style,function(u,t){var w;if(w=l.getStyle(s,t)){if(w==u){l.setStyle(s,t,\"\");r=2;return false}r=1;return false}});if(r){return false}});if(r==2){i=n.selection.getBookmark();h();n.selection.moveToBookmark(i);window.setTimeout(function(){n.nodeChanged()},1);return}}q._pendingStyles=d.extend(q._pendingStyles||{},j.style);q._applyInlineStyle.chandler=n.onSetContent.add(function(){delete q._pendingStyles});q._applyInlineStyle.keyhandler=k=function(s){if(q._pendingStyles){j.style=q._pendingStyles;delete q._pendingStyles}if(g()){n.onKeyDown.remove(q._applyInlineStyle.keyhandler);n.onKeyPress.remove(q._applyInlineStyle.keyhandler)}if(s.type==\"keyup\"){n.onKeyUp.remove(q._applyInlineStyle.keyhandler)}};n.onKeyDown.add(k);n.onKeyPress.add(k);n.onKeyUp.add(k)}else{q._pendingStyles=0}}})})(tinymce);(function(a){a.create(\"tinymce.UndoManager\",{index:0,data:null,typing:0,UndoManager:function(c){var d=this,b=a.util.Dispatcher;d.editor=c;d.data=[];d.onAdd=new b(this);d.onUndo=new b(this);d.onRedo=new b(this)},add:function(d){var g=this,f,e=g.editor,c,h=e.settings,j;d=d||{};d.content=d.content||e.getContent({format:\"raw\",no_events:1});d.content=d.content.replace(/^\\s*|\\s*$/g,\"\");j=g.data[g.index>0&&(g.index==0||g.index==g.data.length)?g.index-1:g.index];if(!d.initial&&j&&d.content==j.content){return null}if(h.custom_undo_redo_levels){if(g.data.length>h.custom_undo_redo_levels){for(f=0;f<g.data.length-1;f++){g.data[f]=g.data[f+1]}g.data.length--;g.index=g.data.length}}if(h.custom_undo_redo_restore_selection&&!d.initial){d.bookmark=c=d.bookmark||e.selection.getBookmark()}if(g.index<g.data.length){g.index++}if(g.data.length===0&&!d.initial){return null}g.data.length=g.index+1;g.data[g.index++]=d;if(d.initial){g.index=0}if(g.data.length==2&&g.data[0].initial){g.data[0].bookmark=c}g.onAdd.dispatch(g,d);e.isNotDirty=0;return d},undo:function(){var e=this,c=e.editor,b=b,d;if(e.typing){e.add();e.typing=0}if(e.index>0){if(e.index==e.data.length&&e.index>1){d=e.index;e.typing=0;if(!e.add()){e.index=d}--e.index}b=e.data[--e.index];c.setContent(b.content,{format:\"raw\"});c.selection.moveToBookmark(b.bookmark);e.onUndo.dispatch(e,b)}return b},redo:function(){var d=this,c=d.editor,b=null;if(d.index<d.data.length-1){b=d.data[++d.index];c.setContent(b.content,{format:\"raw\"});c.selection.moveToBookmark(b.bookmark);d.onRedo.dispatch(d,b)}return b},clear:function(){var b=this;b.data=[];b.index=0;b.typing=0;b.add({initial:true})},hasUndo:function(){return this.index!=0||this.typing},hasRedo:function(){return this.index<this.data.length-1}})})(tinymce);(function(i){var h,c,a,b,g,f;h=i.dom.Event;c=i.isIE;a=i.isGecko;b=i.isOpera;g=i.each;f=i.extend;function e(k,l){var j=l.ownerDocument.createRange();j.setStart(k.endContainer,k.endOffset);j.setEndAfter(l);return j.cloneContents().textContent.length==0}function d(j){j=j.innerHTML;j=j.replace(/<(img|hr|table|input|select|textarea)[ \\>]/gi,\"-\");j=j.replace(/<[^>]+>/g,\"\");return j.replace(/[ \\t\\r\\n]+/g,\"\")==\"\"}i.create(\"tinymce.ForceBlocks\",{ForceBlocks:function(k){var l=this,m=k.settings,n;l.editor=k;l.dom=k.dom;n=(m.forced_root_block||\"p\").toLowerCase();m.element=n.toUpperCase();k.onPreInit.add(l.setup,l);l.reOpera=new RegExp(\"(\\\\u00a0|&#160;|&nbsp;)</\"+n+\">\",\"gi\");l.rePadd=new RegExp(\"<p( )([^>]+)><\\\\/p>|<p( )([^>]+)\\\\/>|<p( )([^>]+)>\\\\s+<\\\\/p>|<p><\\\\/p>|<p\\\\/>|<p>\\\\s+<\\\\/p>\".replace(/p/g,n),\"gi\");l.reNbsp2BR1=new RegExp(\"<p( )([^>]+)>[\\\\s\\\\u00a0]+<\\\\/p>|<p>[\\\\s\\\\u00a0]+<\\\\/p>\".replace(/p/g,n),\"gi\");l.reNbsp2BR2=new RegExp(\"<%p()([^>]+)>(&nbsp;|&#160;)<\\\\/%p>|<%p>(&nbsp;|&#160;)<\\\\/%p>\".replace(/%p/g,n),\"gi\");l.reBR2Nbsp=new RegExp(\"<p( )([^>]+)>\\\\s*<br \\\\/>\\\\s*<\\\\/p>|<p>\\\\s*<br \\\\/>\\\\s*<\\\\/p>\".replace(/p/g,n),\"gi\");function j(p,q){if(b){q.content=q.content.replace(l.reOpera,\"</\"+n+\">\")}q.content=q.content.replace(l.rePadd,\"<\"+n+\"$1$2$3$4$5$6>\\u00a0</\"+n+\">\");if(!c&&!b&&q.set){q.content=q.content.replace(l.reNbsp2BR1,\"<\"+n+\"$1$2><br /></\"+n+\">\");q.content=q.content.replace(l.reNbsp2BR2,\"<\"+n+\"$1$2><br /></\"+n+\">\")}else{q.content=q.content.replace(l.reBR2Nbsp,\"<\"+n+\"$1$2>\\u00a0</\"+n+\">\")}}k.onBeforeSetContent.add(j);k.onPostProcess.add(j);if(m.forced_root_block){k.onInit.add(l.forceRoots,l);k.onSetContent.add(l.forceRoots,l);k.onBeforeGetContent.add(l.forceRoots,l)}},setup:function(){var k=this,j=k.editor,l=j.settings;if(l.forced_root_block){j.onKeyUp.add(k.forceRoots,k);j.onPreProcess.add(k.forceRoots,k)}if(l.force_br_newlines){if(c){j.onKeyPress.add(function(o,q){var r,p=o.selection;if(q.keyCode==13&&p.getNode().nodeName!=\"LI\"){p.setContent('<br id=\"__\" /> ',{format:\"raw\"});r=o.dom.get(\"__\");r.removeAttribute(\"id\");p.select(r);p.collapse();return h.cancel(q)}})}return}if(!c&&l.force_p_newlines){j.onKeyPress.add(function(n,o){if(o.keyCode==13&&!o.shiftKey){if(!k.insertPara(o)){h.cancel(o)}}});if(a){j.onKeyDown.add(function(n,o){if((o.keyCode==8||o.keyCode==46)&&!o.shiftKey){k.backspaceDelete(o,o.keyCode==8)}})}}function m(o,n){var p=j.dom.create(n);g(o.attributes,function(q){if(q.specified&&q.nodeValue){p.setAttribute(q.nodeName.toLowerCase(),q.nodeValue)}});g(o.childNodes,function(q){p.appendChild(q.cloneNode(true))});o.parentNode.replaceChild(p,o);return p}j.onPreProcess.add(function(n,p){g(n.dom.select(\"p,h1,h2,h3,h4,h5,h6,div\",p.node),function(o){if(d(o)){g(n.dom.select(\"span,em,strong,b,i\",p.node),function(q){if(!q.hasChildNodes()){q.appendChild(n.getDoc().createTextNode(\"\\u00a0\"));return false}})}})});if(c){if(l.element!=\"P\"){j.onKeyPress.add(function(n,o){k.lastElm=n.selection.getNode().nodeName});j.onKeyUp.add(function(p,r){var t,q=p.selection,s=q.getNode(),o=p.getBody();if(o.childNodes.length===1&&s.nodeName==\"P\"){s=m(s,l.element);q.select(s);q.collapse();p.nodeChanged()}else{if(r.keyCode==13&&!r.shiftKey&&k.lastElm!=\"P\"){t=p.dom.getParent(s,\"p\");if(t){m(t,l.element);p.nodeChanged()}}}})}}},find:function(p,l,m){var k=this.editor,j=k.getDoc().createTreeWalker(p,4,null,false),o=-1;while(p=j.nextNode()){o++;if(l==0&&p==m){return o}if(l==1&&o==m){return p}}return -1},forceRoots:function(p,D){var u=this,p=u.editor,H=p.getBody(),E=p.getDoc(),K=p.selection,v=K.getSel(),w=K.getRng(),I=-2,o,B,j,k,F=-16777215;var G,l,J,A,x,m=H.childNodes,z,y,q;for(z=m.length-1;z>=0;z--){G=m[z];if(G.nodeType===3||(!u.dom.isBlock(G)&&G.nodeType!==8&&!/^(script|mce:script|style|mce:style)$/i.test(G.nodeName))){if(!l){if(G.nodeType!=3||/[^\\s]/g.test(G.nodeValue)){if(I==-2&&w){if(!c){if(w.startContainer.nodeType==1&&(y=w.startContainer.childNodes[w.startOffset])&&y.nodeType==1){q=y.getAttribute(\"id\");y.setAttribute(\"id\",\"__mce\")}else{if(p.dom.getParent(w.startContainer,function(n){return n===H})){B=w.startOffset;j=w.endOffset;I=u.find(H,0,w.startContainer);o=u.find(H,0,w.endContainer)}}}else{k=E.body.createTextRange();k.moveToElementText(H);k.collapse(1);J=k.move(\"character\",F)*-1;k=w.duplicate();k.collapse(1);A=k.move(\"character\",F)*-1;k=w.duplicate();k.collapse(0);x=(k.move(\"character\",F)*-1)-A;I=A-J;o=x}}l=p.dom.create(p.settings.forced_root_block);G.parentNode.replaceChild(l,G);l.appendChild(G)}}else{if(l.hasChildNodes()){l.insertBefore(G,l.firstChild)}else{l.appendChild(G)}}}else{l=null}}if(I!=-2){if(!c){l=H.getElementsByTagName(p.settings.element)[0];w=E.createRange();if(I!=-1){w.setStart(u.find(H,1,I),B)}else{w.setStart(l,0)}if(o!=-1){w.setEnd(u.find(H,1,o),j)}else{w.setEnd(l,0)}if(v){v.removeAllRanges();v.addRange(w)}}else{try{w=v.createRange();w.moveToElementText(H);w.collapse(1);w.moveStart(\"character\",I);w.moveEnd(\"character\",o);w.select()}catch(C){}}}else{if(!c&&(y=p.dom.get(\"__mce\"))){if(q){y.setAttribute(\"id\",q)}else{y.removeAttribute(\"id\")}w=E.createRange();w.setStartBefore(y);w.setEndBefore(y);K.setRng(w)}}},getParentBlock:function(k){var j=this.dom;return j.getParent(k,j.isBlock)},insertPara:function(N){var B=this,p=B.editor,J=p.dom,O=p.getDoc(),S=p.settings,C=p.selection.getSel(),D=C.getRangeAt(0),R=O.body;var G,H,E,L,K,m,k,o,u,j,z,Q,l,q,F,I=J.getViewPort(p.getWin()),x,A,w;G=O.createRange();G.setStart(C.anchorNode,C.anchorOffset);G.collapse(true);H=O.createRange();H.setStart(C.focusNode,C.focusOffset);H.collapse(true);E=G.compareBoundaryPoints(G.START_TO_END,H)<0;L=E?C.anchorNode:C.focusNode;K=E?C.anchorOffset:C.focusOffset;m=E?C.focusNode:C.anchorNode;k=E?C.focusOffset:C.anchorOffset;if(L===m&&/^(TD|TH)$/.test(L.nodeName)){if(L.firstChild.nodeName==\"BR\"){J.remove(L.firstChild)}if(L.childNodes.length==0){p.dom.add(L,S.element,null,\"<br />\");Q=p.dom.add(L,S.element,null,\"<br />\")}else{F=L.innerHTML;L.innerHTML=\"\";p.dom.add(L,S.element,null,F);Q=p.dom.add(L,S.element,null,\"<br />\")}D=O.createRange();D.selectNodeContents(Q);D.collapse(1);p.selection.setRng(D);return false}if(L==R&&m==R&&R.firstChild&&p.dom.isBlock(R.firstChild)){L=m=L.firstChild;K=k=0;G=O.createRange();G.setStart(L,0);H=O.createRange();H.setStart(m,0)}L=L.nodeName==\"HTML\"?O.body:L;L=L.nodeName==\"BODY\"?L.firstChild:L;m=m.nodeName==\"HTML\"?O.body:m;m=m.nodeName==\"BODY\"?m.firstChild:m;o=B.getParentBlock(L);u=B.getParentBlock(m);j=o?o.nodeName:S.element;if(B.dom.getParent(o,\"ol,ul,pre\")){return true}if(o&&(o.nodeName==\"CAPTION\"||/absolute|relative|fixed/gi.test(J.getStyle(o,\"position\",1)))){j=S.element;o=null}if(u&&(u.nodeName==\"CAPTION\"||/absolute|relative|fixed/gi.test(J.getStyle(o,\"position\",1)))){j=S.element;u=null}if(/(TD|TABLE|TH|CAPTION)/.test(j)||(o&&j==\"DIV\"&&/left|right/gi.test(J.getStyle(o,\"float\",1)))){j=S.element;o=u=null}z=(o&&o.nodeName==j)?o.cloneNode(0):p.dom.create(j);Q=(u&&u.nodeName==j)?u.cloneNode(0):p.dom.create(j);Q.removeAttribute(\"id\");if(/^(H[1-6])$/.test(j)&&e(D,o)){Q=p.dom.create(S.element)}F=l=L;do{if(F==R||F.nodeType==9||B.dom.isBlock(F)||/(TD|TABLE|TH|CAPTION)/.test(F.nodeName)){break}l=F}while((F=F.previousSibling?F.previousSibling:F.parentNode));F=q=m;do{if(F==R||F.nodeType==9||B.dom.isBlock(F)||/(TD|TABLE|TH|CAPTION)/.test(F.nodeName)){break}q=F}while((F=F.nextSibling?F.nextSibling:F.parentNode));if(l.nodeName==j){G.setStart(l,0)}else{G.setStartBefore(l)}G.setEnd(L,K);z.appendChild(G.cloneContents()||O.createTextNode(\"\"));try{H.setEndAfter(q)}catch(M){}H.setStart(m,k);Q.appendChild(H.cloneContents()||O.createTextNode(\"\"));D=O.createRange();if(!l.previousSibling&&l.parentNode.nodeName==j){D.setStartBefore(l.parentNode)}else{if(G.startContainer.nodeName==j&&G.startOffset==0){D.setStartBefore(G.startContainer)}else{D.setStart(G.startContainer,G.startOffset)}}if(!q.nextSibling&&q.parentNode.nodeName==j){D.setEndAfter(q.parentNode)}else{D.setEnd(H.endContainer,H.endOffset)}D.deleteContents();if(b){p.getWin().scrollTo(0,I.y)}if(z.firstChild&&z.firstChild.nodeName==j){z.innerHTML=z.firstChild.innerHTML}if(Q.firstChild&&Q.firstChild.nodeName==j){Q.innerHTML=Q.firstChild.innerHTML}if(d(z)){z.innerHTML=\"<br />\"}function P(y,s){var r=[],U,T,t;y.innerHTML=\"\";if(S.keep_styles){T=s;do{if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(T.nodeName)){U=T.cloneNode(false);J.setAttrib(U,\"id\",\"\");r.push(U)}}while(T=T.parentNode)}if(r.length>0){for(t=r.length-1,U=y;t>=0;t--){U=U.appendChild(r[t])}r[0].innerHTML=b?\"&nbsp;\":\"<br />\";return r[0]}else{y.innerHTML=b?\"&nbsp;\":\"<br />\"}}if(d(Q)){w=P(Q,m)}if(b&&parseFloat(opera.version())<9.5){D.insertNode(z);D.insertNode(Q)}else{D.insertNode(Q);D.insertNode(z)}Q.normalize();z.normalize();function v(r){return O.createTreeWalker(r,NodeFilter.SHOW_TEXT,null,false).nextNode()||r}D=O.createRange();D.selectNodeContents(a?v(w||Q):w||Q);D.collapse(1);C.removeAllRanges();C.addRange(D);x=p.dom.getPos(Q).y;A=Q.clientHeight;if(x<I.y||x+A>I.y+I.h){p.getWin().scrollTo(0,x<I.y?x:x-I.h+25)}return false},backspaceDelete:function(o,x){var z=this,m=z.editor,s=m.getBody(),l=m.dom,k,p=m.selection,j=p.getRng(),q=j.startContainer,k,u,v;if(q&&m.dom.isBlock(q)&&!/^(TD|TH)$/.test(q.nodeName)&&x){if(q.childNodes.length==0||(q.childNodes.length==1&&q.firstChild.nodeName==\"BR\")){k=q;while((k=k.previousSibling)&&!m.dom.isBlock(k)){}if(k){if(q!=s.firstChild){u=m.dom.doc.createTreeWalker(k,NodeFilter.SHOW_TEXT,null,false);while(v=u.nextNode()){k=v}j=m.getDoc().createRange();j.setStart(k,k.nodeValue?k.nodeValue.length:0);j.setEnd(k,k.nodeValue?k.nodeValue.length:0);p.setRng(j);m.dom.remove(q)}return h.cancel(o)}}}function y(n){var r;n=n.target;if(n&&n.parentNode&&n.nodeName==\"BR\"&&(k=z.getParentBlock(n))){r=n.previousSibling;h.remove(s,\"DOMNodeInserted\",y);if(r&&r.nodeType==3&&/\\s+$/.test(r.nodeValue)){return}if(n.previousSibling||n.nextSibling){m.dom.remove(n)}}}h._add(s,\"DOMNodeInserted\",y);window.setTimeout(function(){h._remove(s,\"DOMNodeInserted\",y)},1)}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each,e=c.extend;c.create(\"tinymce.ControlManager\",{ControlManager:function(f,j){var h=this,g;j=j||{};h.editor=f;h.controls={};h.onAdd=new c.util.Dispatcher(h);h.onPostRender=new c.util.Dispatcher(h);h.prefix=j.prefix||f.id+\"_\";h._cls={};h.onPostRender.add(function(){d(h.controls,function(i){i.postRender()})})},get:function(f){return this.controls[this.prefix+f]||this.controls[f]},setActive:function(h,f){var g=null;if(g=this.get(h)){g.setActive(f)}return g},setDisabled:function(h,f){var g=null;if(g=this.get(h)){g.setDisabled(f)}return g},add:function(g){var f=this;if(g){f.controls[g.id]=g;f.onAdd.dispatch(g,f)}return g},createControl:function(i){var h,g=this,f=g.editor;d(f.plugins,function(j){if(j.createControl){h=j.createControl(i,g);if(h){return false}}});switch(i){case\"|\":case\"separator\":return g.createSeparator()}if(!h&&f.buttons&&(h=f.buttons[i])){return g.createButton(i,h)}return g.add(h)},createDropMenu:function(f,n,h){var m=this,i=m.editor,j,g,k,l;n=e({\"class\":\"mceDropDown\",constrain:i.settings.constrain_menus},n);n[\"class\"]=n[\"class\"]+\" \"+i.getParam(\"skin\")+\"Skin\";if(k=i.getParam(\"skin_variant\")){n[\"class\"]+=\" \"+i.getParam(\"skin\")+\"Skin\"+k.substring(0,1).toUpperCase()+k.substring(1)}f=m.prefix+f;l=h||m._cls.dropmenu||c.ui.DropMenu;j=m.controls[f]=new l(f,n);j.onAddItem.add(function(r,q){var p=q.settings;p.title=i.getLang(p.title,p.title);if(!p.onclick){p.onclick=function(o){i.execCommand(p.cmd,p.ui||false,p.value)}}});i.onRemove.add(function(){j.destroy()});if(c.isIE){j.onShowMenu.add(function(){i.focus();g=i.selection.getBookmark(1)});j.onHideMenu.add(function(){if(g){i.selection.moveToBookmark(g);g=0}})}return m.add(j)},createListBox:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.scope=i.scope||g;if(!i.onselect){i.onselect=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}i=e({title:i.title,\"class\":\"mce_\"+m,scope:i.scope,control_manager:h},i);m=h.prefix+m;if(g.settings.use_native_selects){k=new c.ui.NativeListBox(m,i)}else{f=l||h._cls.listbox||c.ui.ListBox;k=new f(m,i)}h.controls[m]=k;if(c.isWebKit){k.onPostRender.add(function(p,o){a.add(o,\"mousedown\",function(){g.bookmark=g.selection.getBookmark(1)});a.add(o,\"focus\",function(){g.selection.moveToBookmark(g.bookmark);g.bookmark=null})})}if(k.hideMenu){g.onMouseDown.add(k.hideMenu,k)}return h.add(k)},createButton:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.label=g.translate(i.label);i.scope=i.scope||g;if(!i.onclick&&!i.menu_button){i.onclick=function(){g.execCommand(i.cmd,i.ui||false,i.value)}}i=e({title:i.title,\"class\":\"mce_\"+m,unavailable_prefix:g.getLang(\"unavailable\",\"\"),scope:i.scope,control_manager:h},i);m=h.prefix+m;if(i.menu_button){f=l||h._cls.menubutton||c.ui.MenuButton;k=new f(m,i);g.onMouseDown.add(k.hideMenu,k)}else{f=h._cls.button||c.ui.Button;k=new f(m,i)}return h.add(k)},createMenuButton:function(h,f,g){f=f||{};f.menu_button=1;return this.createButton(h,f,g)},createSplitButton:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.scope=i.scope||g;if(!i.onclick){i.onclick=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}if(!i.onselect){i.onselect=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}i=e({title:i.title,\"class\":\"mce_\"+m,scope:i.scope,control_manager:h},i);m=h.prefix+m;f=l||h._cls.splitbutton||c.ui.SplitButton;k=h.add(new f(m,i));g.onMouseDown.add(k.hideMenu,k);return k},createColorSplitButton:function(f,n,h){var l=this,j=l.editor,i,k,m,g;if(l.get(f)){return null}n.title=j.translate(n.title);n.scope=n.scope||j;if(!n.onclick){n.onclick=function(o){if(c.isIE){g=j.selection.getBookmark(1)}j.execCommand(n.cmd,n.ui||false,o||n.value)}}if(!n.onselect){n.onselect=function(o){j.execCommand(n.cmd,n.ui||false,o||n.value)}}n=e({title:n.title,\"class\":\"mce_\"+f,menu_class:j.getParam(\"skin\")+\"Skin\",scope:n.scope,more_colors_title:j.getLang(\"more_colors\")},n);f=l.prefix+f;m=h||l._cls.colorsplitbutton||c.ui.ColorSplitButton;k=new m(f,n);j.onMouseDown.add(k.hideMenu,k);j.onRemove.add(function(){k.destroy()});if(c.isIE){k.onShowMenu.add(function(){j.focus();g=j.selection.getBookmark(1)});k.onHideMenu.add(function(){if(g){j.selection.moveToBookmark(g);g=0}})}return l.add(k)},createToolbar:function(k,h,j){var i,g=this,f;k=g.prefix+k;f=j||g._cls.toolbar||c.ui.Toolbar;i=new f(k,h);if(g.get(k)){return null}return g.add(i)},createSeparator:function(g){var f=g||this._cls.separator||c.ui.Separator;return new f()},setControlType:function(g,f){return this._cls[g.toLowerCase()]=f},destroy:function(){d(this.controls,function(f){f.destroy()});this.controls=null}})})(tinymce);(function(d){var a=d.util.Dispatcher,e=d.each,c=d.isIE,b=d.isOpera;d.create(\"tinymce.WindowManager\",{WindowManager:function(f){var g=this;g.editor=f;g.onOpen=new a(g);g.onClose=new a(g);g.params={};g.features={}},open:function(z,h){var v=this,k=\"\",n,m,i=v.editor.settings.dialog_type==\"modal\",q,o,j,g=d.DOM.getViewPort(),r;z=z||{};h=h||{};o=b?g.w:screen.width;j=b?g.h:screen.height;z.name=z.name||\"mc_\"+new Date().getTime();z.width=parseInt(z.width||320);z.height=parseInt(z.height||240);z.resizable=true;z.left=z.left||parseInt(o/2)-(z.width/2);z.top=z.top||parseInt(j/2)-(z.height/2);h.inline=false;h.mce_width=z.width;h.mce_height=z.height;h.mce_auto_focus=z.auto_focus;if(i){if(c){z.center=true;z.help=false;z.dialogWidth=z.width+\"px\";z.dialogHeight=z.height+\"px\";z.scroll=z.scrollbars||false}}e(z,function(p,f){if(d.is(p,\"boolean\")){p=p?\"yes\":\"no\"}if(!/^(name|url)$/.test(f)){if(c&&i){k+=(k?\";\":\"\")+f+\":\"+p}else{k+=(k?\",\":\"\")+f+\"=\"+p}}});v.features=z;v.params=h;v.onOpen.dispatch(v,z,h);r=z.url||z.file;r=d._addVer(r);try{if(c&&i){q=1;window.showModalDialog(r,window,k)}else{q=window.open(r,z.name,k)}}catch(l){}if(!q){alert(v.editor.getLang(\"popup_blocked\"))}},close:function(f){f.close();this.onClose.dispatch(this)},createInstance:function(i,h,g,m,l,k){var j=d.resolve(i);return new j(h,g,m,l,k)},confirm:function(h,f,i,g){g=g||window;f.call(i||this,g.confirm(this._decode(this.editor.getLang(h,h))))},alert:function(h,f,j,g){var i=this;g=g||window;g.alert(i._decode(i.editor.getLang(h,h)));if(f){f.call(j||i)}},_decode:function(f){return d.DOM.decode(f).replace(/\\\\n/g,\"\\n\")}})}(tinymce));(function(a){a.CommandManager=function(){var c={},b={},d={};function e(i,h,g,f){if(typeof(h)==\"string\"){h=[h]}a.each(h,function(j){i[j.toLowerCase()]={func:g,scope:f}})}a.extend(this,{add:function(h,g,f){e(c,h,g,f)},addQueryStateHandler:function(h,g,f){e(b,h,g,f)},addQueryValueHandler:function(h,g,f){e(d,h,g,f)},execCommand:function(g,j,i,h,f){if(j=c[j.toLowerCase()]){if(j.func.call(g||j.scope,i,h,f)!==false){return true}}},queryCommandValue:function(){if(cmd=d[cmd.toLowerCase()]){return cmd.func.call(scope||cmd.scope,ui,value,args)}},queryCommandState:function(){if(cmd=b[cmd.toLowerCase()]){return cmd.func.call(scope||cmd.scope,ui,value,args)}}})};a.GlobalCommands=new a.CommandManager()})(tinymce);(function(b){function a(i,d,h,m){var j,g,e,l,f;function k(p,o){do{if(p.parentNode==o){return p}p=p.parentNode}while(p)}function c(o){m(o);b.walk(o,m,\"childNodes\")}j=i.findCommonAncestor(d,h);e=k(d,j)||d;l=k(h,j)||h;for(g=d;g&&g!=e;g=g.parentNode){for(f=g.nextSibling;f;f=f.nextSibling){c(f)}}if(e!=l){for(g=e.nextSibling;g&&g!=l;g=g.nextSibling){c(g)}}else{c(e)}for(g=h;g&&g!=l;g=g.parentNode){for(f=g.previousSibling;f;f=f.previousSibling){c(f)}}}b.GlobalCommands.add(\"RemoveFormat\",function(){var m=this,l=m.dom,u=m.selection,d=u.getRng(1),e=[],h,f,j,q,g,o,c,i;function k(s){var r;l.getParent(s,function(v){if(l.is(v,m.getParam(\"removeformat_selector\"))){r=v}return l.isBlock(v)},m.getBody());return r}function p(r){if(l.is(r,m.getParam(\"removeformat_selector\"))){e.push(r)}}function t(r){p(r);b.walk(r,p,\"childNodes\")}h=u.getBookmark();q=d.startContainer;o=d.endContainer;g=d.startOffset;c=d.endOffset;q=q.nodeType==1?q.childNodes[Math.min(g,q.childNodes.length-1)]:q;o=o.nodeType==1?o.childNodes[Math.min(g==c?c:c-1,o.childNodes.length-1)]:o;if(q==o){f=k(q);if(q.nodeType==3){if(f&&f.nodeType==1){i=q.splitText(g);i.splitText(c-g);l.split(f,i);u.moveToBookmark(h)}return}t(l.split(f,q)||q)}else{f=k(q);j=k(o);if(f){if(q.nodeType==3){if(g==q.nodeValue.length){q.nodeValue+=\"\\uFEFF\"}q=q.splitText(g)}}if(j){if(o.nodeType==3){o.splitText(c)}}if(f&&f==j){l.replace(l.create(\"span\",{id:\"__end\"},o.cloneNode(true)),o)}if(f){f=l.split(f,q)}else{f=q}if(i=l.get(\"__end\")){o=i;j=k(o)}if(j){j=l.split(j,o)}else{j=o}a(l,f,j,p);if(q.nodeValue==\"\\uFEFF\"){q.nodeValue=\"\"}t(o);t(q)}b.each(e,function(r){l.remove(r,1)});l.remove(\"__end\",1);u.moveToBookmark(h)})})(tinymce);(function(a){a.GlobalCommands.add(\"mceBlockQuote\",function(){var j=this,o=j.selection,f=j.dom,l,k,e,d,p,c,m,h,b;function g(i){return f.getParent(i,function(q){return q.nodeName===\"BLOCKQUOTE\"})}l=f.getParent(o.getStart(),f.isBlock);k=f.getParent(o.getEnd(),f.isBlock);if(p=g(l)){if(l!=k||l.childNodes.length>1||(l.childNodes.length==1&&l.firstChild.nodeName!=\"BR\")){d=o.getBookmark()}if(g(k)){m=p.cloneNode(false);while(e=k.nextSibling){m.appendChild(e.parentNode.removeChild(e))}}if(m){f.insertAfter(m,p)}b=o.getSelectedBlocks(l,k);for(h=b.length-1;h>=0;h--){f.insertAfter(b[h],p)}if(/^\\s*$/.test(p.innerHTML)){f.remove(p,1)}if(m&&/^\\s*$/.test(m.innerHTML)){f.remove(m,1)}if(!d){if(!a.isIE){c=j.getDoc().createRange();c.setStart(l,0);c.setEnd(l,0);o.setRng(c)}else{o.select(l);o.collapse(0);if(f.getParent(o.getStart(),f.isBlock)!=l){c=o.getRng();c.move(\"character\",-1);c.select()}}}else{j.selection.moveToBookmark(d)}return}if(a.isIE&&!l&&!k){j.getDoc().execCommand(\"Indent\");e=g(o.getNode());e.style.margin=e.dir=\"\";return}if(!l||!k){return}if(l!=k||l.childNodes.length>1||(l.childNodes.length==1&&l.firstChild.nodeName!=\"BR\")){d=o.getBookmark()}a.each(o.getSelectedBlocks(g(o.getStart()),g(o.getEnd())),function(i){if(i.nodeName==\"BLOCKQUOTE\"&&!p){p=i;return}if(!p){p=f.create(\"blockquote\");i.parentNode.insertBefore(p,i)}if(i.nodeName==\"BLOCKQUOTE\"&&p){e=i.firstChild;while(e){p.appendChild(e.cloneNode(true));e=e.nextSibling}f.remove(i);return}p.appendChild(f.remove(i))});if(!d){if(!a.isIE){c=j.getDoc().createRange();c.setStart(l,0);c.setEnd(l,0);o.setRng(c)}else{o.select(l);o.collapse(1)}}else{o.moveToBookmark(d)}})})(tinymce);(function(a){a.each([\"Cut\",\"Copy\",\"Paste\"],function(b){a.GlobalCommands.add(b,function(){var c=this,e=c.getDoc();try{e.execCommand(b,false,null);if(!e.queryCommandEnabled(b)){throw\"Error\"}}catch(d){if(a.isGecko){c.windowManager.confirm(c.getLang(\"clipboard_msg\"),function(f){if(f){open(\"http://www.mozilla.org/editor/midasdemo/securityprefs.html\",\"_blank\")}})}else{c.windowManager.alert(c.getLang(\"clipboard_no_support\"))}}})})})(tinymce);(function(a){a.GlobalCommands.add(\"InsertHorizontalRule\",function(){if(a.isOpera){return this.getDoc().execCommand(\"InsertHorizontalRule\",false,\"\")}this.selection.setContent(\"<hr />\")})})(tinymce);(function(){var a=tinymce.GlobalCommands;a.add([\"mceEndUndoLevel\",\"mceAddUndoLevel\"],function(){this.undoManager.add()});a.add(\"Undo\",function(){var b=this;if(b.settings.custom_undo_redo){b.undoManager.undo();b.nodeChanged();return true}return false});a.add(\"Redo\",function(){var b=this;if(b.settings.custom_undo_redo){b.undoManager.redo();b.nodeChanged();return true}return false})})();"
  },
  {
    "path": "TinyMCE/tiny_mce/tiny_mce_popup.js",
    "content": "\n// Uncomment and change this document.domain value if you are loading the script cross subdomains\n// document.domain = 'moxiecode.com';\n\nvar tinymce=null,tinyMCEPopup,tinyMCE;tinyMCEPopup={init:function(){var b=this,a,c;a=b.getWin();tinymce=a.tinymce;tinyMCE=a.tinyMCE;b.editor=tinymce.EditorManager.activeEditor;b.params=b.editor.windowManager.params;b.features=b.editor.windowManager.features;b.dom=b.editor.windowManager.createInstance(\"tinymce.dom.DOMUtils\",document);if(b.features.popup_css!==false){b.dom.loadCSS(b.features.popup_css||b.editor.settings.popup_css)}b.listeners=[];b.onInit={add:function(e,d){b.listeners.push({func:e,scope:d})}};b.isWindow=!b.getWindowArg(\"mce_inline\");b.id=b.getWindowArg(\"mce_window_id\");b.editor.windowManager.onOpen.dispatch(b.editor.windowManager,window)},getWin:function(){return(!window.frameElement&&window.dialogArguments)||opener||parent||top},getWindowArg:function(c,b){var a=this.params[c];return tinymce.is(a)?a:b},getParam:function(b,a){return this.editor.getParam(b,a)},getLang:function(b,a){return this.editor.getLang(b,a)},execCommand:function(d,c,e,b){b=b||{};b.skip_focus=1;this.restoreSelection();return this.editor.execCommand(d,c,e,b)},resizeToInnerSize:function(){var e=this,g,a=document.body,c=e.dom.getViewPort(window),d,f;d=e.getWindowArg(\"mce_width\")-c.w;f=e.getWindowArg(\"mce_height\")-c.h;if(e.isWindow){window.resizeBy(d,f)}else{e.editor.windowManager.resizeBy(d,f,e.id)}},executeOnLoad:function(s){this.onInit.add(function(){eval(s)})},storeSelection:function(){this.editor.windowManager.bookmark=tinyMCEPopup.editor.selection.getBookmark(1)},restoreSelection:function(){var a=tinyMCEPopup;if(!a.isWindow&&tinymce.isIE){a.editor.selection.moveToBookmark(a.editor.windowManager.bookmark)}},requireLangPack:function(){var b=this,a=b.getWindowArg(\"plugin_url\")||b.getWindowArg(\"theme_url\");if(a&&b.editor.settings.language&&b.features.translate_i18n!==false){a+=\"/langs/\"+b.editor.settings.language+\"_dlg.js\";if(!tinymce.ScriptLoader.isDone(a)){document.write('<script type=\"text/javascript\" src=\"'+tinymce._addVer(a)+'\"><\\/script>');tinymce.ScriptLoader.markDone(a)}}},pickColor:function(b,a){this.execCommand(\"mceColorPicker\",true,{color:document.getElementById(a).value,func:function(e){document.getElementById(a).value=e;try{document.getElementById(a).onchange()}catch(d){}}})},openBrowser:function(a,c,b){tinyMCEPopup.restoreSelection();this.editor.execCallback(\"file_browser_callback\",a,document.getElementById(a).value,c,window)},confirm:function(b,a,c){this.editor.windowManager.confirm(b,a,c,window)},alert:function(b,a,c){this.editor.windowManager.alert(b,a,c,window)},close:function(){var a=this;function b(){a.editor.windowManager.close(window);tinymce=tinyMCE=a.editor=a.params=a.dom=a.dom.doc=null}if(tinymce.isOpera){a.getWin().setTimeout(b,0)}else{b()}},_restoreSelection:function(){var a=window.event.srcElement;if(a.nodeName==\"INPUT\"&&(a.type==\"submit\"||a.type==\"button\")){tinyMCEPopup.restoreSelection()}},_onDOMLoaded:function(){var b=tinyMCEPopup,d=document.title,e,c,a;if(b.domLoaded){return}b.domLoaded=1;if(b.features.translate_i18n!==false){c=document.body.innerHTML;if(tinymce.isIE){c=c.replace(/ (value|title|alt)=([^\"][^\\s>]+)/gi,' $1=\"$2\"')}document.dir=b.editor.getParam(\"directionality\",\"\");if((a=b.editor.translate(c))&&a!=c){document.body.innerHTML=a}if((a=b.editor.translate(d))&&a!=d){document.title=d=a}}document.body.style.display=\"\";if(tinymce.isIE){document.attachEvent(\"onmouseup\",tinyMCEPopup._restoreSelection);b.dom.add(b.dom.select(\"head\")[0],\"base\",{target:\"_self\"})}b.restoreSelection();b.resizeToInnerSize();if(!b.isWindow){b.editor.windowManager.setTitle(window,d)}else{window.focus()}if(!tinymce.isIE&&!b.isWindow){tinymce.dom.Event._add(document,\"focus\",function(){b.editor.windowManager.focus(b.id)})}tinymce.each(b.dom.select(\"select\"),function(f){f.onkeydown=tinyMCEPopup._accessHandler});tinymce.each(b.listeners,function(f){f.func.call(f.scope,b.editor)});if(b.getWindowArg(\"mce_auto_focus\",true)){window.focus();tinymce.each(document.forms,function(g){tinymce.each(g.elements,function(f){if(b.dom.hasClass(f,\"mceFocus\")&&!f.disabled){f.focus();return false}})})}document.onkeyup=tinyMCEPopup._closeWinKeyHandler},_accessHandler:function(a){a=a||window.event;if(a.keyCode==13||a.keyCode==32){a=a.target||a.srcElement;if(a.onchange){a.onchange()}return tinymce.dom.Event.cancel(a)}},_closeWinKeyHandler:function(a){a=a||window.event;if(a.keyCode==27){tinyMCEPopup.close()}},_wait:function(){if(document.attachEvent){document.attachEvent(\"onreadystatechange\",function(){if(document.readyState===\"complete\"){document.detachEvent(\"onreadystatechange\",arguments.callee);tinyMCEPopup._onDOMLoaded()}});if(document.documentElement.doScroll&&window==window.top){(function(){if(tinyMCEPopup.domLoaded){return}try{document.documentElement.doScroll(\"left\")}catch(a){setTimeout(arguments.callee,0);return}tinyMCEPopup._onDOMLoaded()})()}document.attachEvent(\"onload\",tinyMCEPopup._onDOMLoaded)}else{if(document.addEventListener){window.addEventListener(\"DOMContentLoaded\",tinyMCEPopup._onDOMLoaded,false);window.addEventListener(\"load\",tinyMCEPopup._onDOMLoaded,false)}}}};tinyMCEPopup.init();tinyMCEPopup._wait();"
  },
  {
    "path": "TinyMCE/tiny_mce/utils/editable_selects.js",
    "content": "/**\n * $Id: editable_selects.js 867 2008-06-09 20:33:40Z spocke $\n *\n * Makes select boxes editable.\n *\n * @author Moxiecode\n * @copyright Copyright  2004-2008, Moxiecode Systems AB, All rights reserved.\n */\n\nvar TinyMCE_EditableSelects = {\n\teditSelectElm : null,\n\n\tinit : function() {\n\t\tvar nl = document.getElementsByTagName(\"select\"), i, d = document, o;\n\n\t\tfor (i=0; i<nl.length; i++) {\n\t\t\tif (nl[i].className.indexOf('mceEditableSelect') != -1) {\n\t\t\t\to = new Option('(value)', '__mce_add_custom__');\n\n\t\t\t\to.className = 'mceAddSelectValue';\n\n\t\t\t\tnl[i].options[nl[i].options.length] = o;\n\t\t\t\tnl[i].onchange = TinyMCE_EditableSelects.onChangeEditableSelect;\n\t\t\t}\n\t\t}\n\t},\n\n\tonChangeEditableSelect : function(e) {\n\t\tvar d = document, ne, se = window.event ? window.event.srcElement : e.target;\n\n\t\tif (se.options[se.selectedIndex].value == '__mce_add_custom__') {\n\t\t\tne = d.createElement(\"input\");\n\t\t\tne.id = se.id + \"_custom\";\n\t\t\tne.name = se.name + \"_custom\";\n\t\t\tne.type = \"text\";\n\n\t\t\tne.style.width = se.offsetWidth + 'px';\n\t\t\tse.parentNode.insertBefore(ne, se);\n\t\t\tse.style.display = 'none';\n\t\t\tne.focus();\n\t\t\tne.onblur = TinyMCE_EditableSelects.onBlurEditableSelectInput;\n\t\t\tne.onkeydown = TinyMCE_EditableSelects.onKeyDown;\n\t\t\tTinyMCE_EditableSelects.editSelectElm = se;\n\t\t}\n\t},\n\n\tonBlurEditableSelectInput : function() {\n\t\tvar se = TinyMCE_EditableSelects.editSelectElm;\n\n\t\tif (se) {\n\t\t\tif (se.previousSibling.value != '') {\n\t\t\t\taddSelectValue(document.forms[0], se.id, se.previousSibling.value, se.previousSibling.value);\n\t\t\t\tselectByValue(document.forms[0], se.id, se.previousSibling.value);\n\t\t\t} else\n\t\t\t\tselectByValue(document.forms[0], se.id, '');\n\n\t\t\tse.style.display = 'inline';\n\t\t\tse.parentNode.removeChild(se.previousSibling);\n\t\t\tTinyMCE_EditableSelects.editSelectElm = null;\n\t\t}\n\t},\n\n\tonKeyDown : function(e) {\n\t\te = e || window.event;\n\n\t\tif (e.keyCode == 13)\n\t\t\tTinyMCE_EditableSelects.onBlurEditableSelectInput();\n\t}\n};\n"
  },
  {
    "path": "TinyMCE/tiny_mce/utils/form_utils.js",
    "content": "/**\n * $Id: form_utils.js 1184 2009-08-11 11:47:27Z spocke $\n *\n * Various form utilitiy functions.\n *\n * @author Moxiecode\n * @copyright Copyright  2004-2008, Moxiecode Systems AB, All rights reserved.\n */\n\nvar themeBaseURL = tinyMCEPopup.editor.baseURI.toAbsolute('themes/' + tinyMCEPopup.getParam(\"theme\"));\n\nfunction getColorPickerHTML(id, target_form_element) {\n\tvar h = \"\";\n\n\th += '<a id=\"' + id + '_link\" href=\"javascript:;\" onclick=\"tinyMCEPopup.pickColor(event,\\'' + target_form_element +'\\');\" onmousedown=\"return false;\" class=\"pickcolor\">';\n\th += '<span id=\"' + id + '\" title=\"' + tinyMCEPopup.getLang('browse') + '\">&nbsp;</span></a>';\n\n\treturn h;\n}\n\nfunction updateColor(img_id, form_element_id) {\n\tdocument.getElementById(img_id).style.backgroundColor = document.forms[0].elements[form_element_id].value;\n}\n\nfunction setBrowserDisabled(id, state) {\n\tvar img = document.getElementById(id);\n\tvar lnk = document.getElementById(id + \"_link\");\n\n\tif (lnk) {\n\t\tif (state) {\n\t\t\tlnk.setAttribute(\"realhref\", lnk.getAttribute(\"href\"));\n\t\t\tlnk.removeAttribute(\"href\");\n\t\t\ttinyMCEPopup.dom.addClass(img, 'disabled');\n\t\t} else {\n\t\t\tif (lnk.getAttribute(\"realhref\"))\n\t\t\t\tlnk.setAttribute(\"href\", lnk.getAttribute(\"realhref\"));\n\n\t\t\ttinyMCEPopup.dom.removeClass(img, 'disabled');\n\t\t}\n\t}\n}\n\nfunction getBrowserHTML(id, target_form_element, type, prefix) {\n\tvar option = prefix + \"_\" + type + \"_browser_callback\", cb, html;\n\n\tcb = tinyMCEPopup.getParam(option, tinyMCEPopup.getParam(\"file_browser_callback\"));\n\n\tif (!cb)\n\t\treturn \"\";\n\n\thtml = \"\";\n\thtml += '<a id=\"' + id + '_link\" href=\"javascript:openBrowser(\\'' + id + '\\',\\'' + target_form_element + '\\', \\'' + type + '\\',\\'' + option + '\\');\" onmousedown=\"return false;\" class=\"browse\">';\n\thtml += '<span id=\"' + id + '\" title=\"' + tinyMCEPopup.getLang('browse') + '\">&nbsp;</span></a>';\n\n\treturn html;\n}\n\nfunction openBrowser(img_id, target_form_element, type, option) {\n\tvar img = document.getElementById(img_id);\n\n\tif (img.className != \"mceButtonDisabled\")\n\t\ttinyMCEPopup.openBrowser(target_form_element, type, option);\n}\n\nfunction selectByValue(form_obj, field_name, value, add_custom, ignore_case) {\n\tif (!form_obj || !form_obj.elements[field_name])\n\t\treturn;\n\n\tvar sel = form_obj.elements[field_name];\n\n\tvar found = false;\n\tfor (var i=0; i<sel.options.length; i++) {\n\t\tvar option = sel.options[i];\n\n\t\tif (option.value == value || (ignore_case && option.value.toLowerCase() == value.toLowerCase())) {\n\t\t\toption.selected = true;\n\t\t\tfound = true;\n\t\t} else\n\t\t\toption.selected = false;\n\t}\n\n\tif (!found && add_custom && value != '') {\n\t\tvar option = new Option(value, value);\n\t\toption.selected = true;\n\t\tsel.options[sel.options.length] = option;\n\t\tsel.selectedIndex = sel.options.length - 1;\n\t}\n\n\treturn found;\n}\n\nfunction getSelectValue(form_obj, field_name) {\n\tvar elm = form_obj.elements[field_name];\n\n\tif (elm == null || elm.options == null || elm.selectedIndex === -1)\n\t\treturn \"\";\n\n\treturn elm.options[elm.selectedIndex].value;\n}\n\nfunction addSelectValue(form_obj, field_name, name, value) {\n\tvar s = form_obj.elements[field_name];\n\tvar o = new Option(name, value);\n\ts.options[s.options.length] = o;\n}\n\nfunction addClassesToList(list_id, specific_option) {\n\t// Setup class droplist\n\tvar styleSelectElm = document.getElementById(list_id);\n\tvar styles = tinyMCEPopup.getParam('theme_advanced_styles', false);\n\tstyles = tinyMCEPopup.getParam(specific_option, styles);\n\n\tif (styles) {\n\t\tvar stylesAr = styles.split(';');\n\n\t\tfor (var i=0; i<stylesAr.length; i++) {\n\t\t\tif (stylesAr != \"\") {\n\t\t\t\tvar key, value;\n\n\t\t\t\tkey = stylesAr[i].split('=')[0];\n\t\t\t\tvalue = stylesAr[i].split('=')[1];\n\n\t\t\t\tstyleSelectElm.options[styleSelectElm.length] = new Option(key, value);\n\t\t\t}\n\t\t}\n\t} else {\n\t\ttinymce.each(tinyMCEPopup.editor.dom.getClasses(), function(o) {\n\t\t\tstyleSelectElm.options[styleSelectElm.length] = new Option(o.title || o['class'], o['class']);\n\t\t});\n\t}\n}\n\nfunction isVisible(element_id) {\n\tvar elm = document.getElementById(element_id);\n\n\treturn elm && elm.style.display != \"none\";\n}\n\nfunction convertRGBToHex(col) {\n\tvar re = new RegExp(\"rgb\\\\s*\\\\(\\\\s*([0-9]+).*,\\\\s*([0-9]+).*,\\\\s*([0-9]+).*\\\\)\", \"gi\");\n\n\tvar rgb = col.replace(re, \"$1,$2,$3\").split(',');\n\tif (rgb.length == 3) {\n\t\tr = parseInt(rgb[0]).toString(16);\n\t\tg = parseInt(rgb[1]).toString(16);\n\t\tb = parseInt(rgb[2]).toString(16);\n\n\t\tr = r.length == 1 ? '0' + r : r;\n\t\tg = g.length == 1 ? '0' + g : g;\n\t\tb = b.length == 1 ? '0' + b : b;\n\n\t\treturn \"#\" + r + g + b;\n\t}\n\n\treturn col;\n}\n\nfunction convertHexToRGB(col) {\n\tif (col.indexOf('#') != -1) {\n\t\tcol = col.replace(new RegExp('[^0-9A-F]', 'gi'), '');\n\n\t\tr = parseInt(col.substring(0, 2), 16);\n\t\tg = parseInt(col.substring(2, 4), 16);\n\t\tb = parseInt(col.substring(4, 6), 16);\n\n\t\treturn \"rgb(\" + r + \",\" + g + \",\" + b + \")\";\n\t}\n\n\treturn col;\n}\n\nfunction trimSize(size) {\n\treturn size.replace(/([0-9\\.]+)px|(%|in|cm|mm|em|ex|pt|pc)/, '$1$2');\n}\n\nfunction getCSSSize(size) {\n\tsize = trimSize(size);\n\n\tif (size == \"\")\n\t\treturn \"\";\n\n\t// Add px\n\tif (/^[0-9]+$/.test(size))\n\t\tsize += 'px';\n\n\treturn size;\n}\n\nfunction getStyle(elm, attrib, style) {\n\tvar val = tinyMCEPopup.dom.getAttrib(elm, attrib);\n\n\tif (val != '')\n\t\treturn '' + val;\n\n\tif (typeof(style) == 'undefined')\n\t\tstyle = attrib;\n\n\treturn tinyMCEPopup.dom.getStyle(elm, style);\n}\n"
  },
  {
    "path": "TinyMCE/tiny_mce/utils/mctabs.js",
    "content": "/**\n * $Id: mctabs.js 758 2008-03-30 13:53:29Z spocke $\n *\n * Moxiecode DHTML Tabs script.\n *\n * @author Moxiecode\n * @copyright Copyright  2004-2008, Moxiecode Systems AB, All rights reserved.\n */\n\nfunction MCTabs() {\n\tthis.settings = [];\n};\n\nMCTabs.prototype.init = function(settings) {\n\tthis.settings = settings;\n};\n\nMCTabs.prototype.getParam = function(name, default_value) {\n\tvar value = null;\n\n\tvalue = (typeof(this.settings[name]) == \"undefined\") ? default_value : this.settings[name];\n\n\t// Fix bool values\n\tif (value == \"true\" || value == \"false\")\n\t\treturn (value == \"true\");\n\n\treturn value;\n};\n\nMCTabs.prototype.displayTab = function(tab_id, panel_id) {\n\tvar panelElm, panelContainerElm, tabElm, tabContainerElm, selectionClass, nodes, i;\n\n\tpanelElm= document.getElementById(panel_id);\n\tpanelContainerElm = panelElm ? panelElm.parentNode : null;\n\ttabElm = document.getElementById(tab_id);\n\ttabContainerElm = tabElm ? tabElm.parentNode : null;\n\tselectionClass = this.getParam('selection_class', 'current');\n\n\tif (tabElm && tabContainerElm) {\n\t\tnodes = tabContainerElm.childNodes;\n\n\t\t// Hide all other tabs\n\t\tfor (i = 0; i < nodes.length; i++) {\n\t\t\tif (nodes[i].nodeName == \"LI\")\n\t\t\t\tnodes[i].className = '';\n\t\t}\n\n\t\t// Show selected tab\n\t\ttabElm.className = 'current';\n\t}\n\n\tif (panelElm && panelContainerElm) {\n\t\tnodes = panelContainerElm.childNodes;\n\n\t\t// Hide all other panels\n\t\tfor (i = 0; i < nodes.length; i++) {\n\t\t\tif (nodes[i].nodeName == \"DIV\")\n\t\t\t\tnodes[i].className = 'panel';\n\t\t}\n\n\t\t// Show selected panel\n\t\tpanelElm.className = 'current';\n\t}\n};\n\nMCTabs.prototype.getAnchor = function() {\n\tvar pos, url = document.location.href;\n\n\tif ((pos = url.lastIndexOf('#')) != -1)\n\t\treturn url.substring(pos + 1);\n\n\treturn \"\";\n};\n\n// Global instance\nvar mcTabs = new MCTabs();\n"
  },
  {
    "path": "TinyMCE/tiny_mce/utils/validate.js",
    "content": "/**\n * $Id: validate.js 758 2008-03-30 13:53:29Z spocke $\n *\n * Various form validation methods.\n *\n * @author Moxiecode\n * @copyright Copyright  2004-2008, Moxiecode Systems AB, All rights reserved.\n */\n\n/**\n\t// String validation:\n\n\tif (!Validator.isEmail('myemail'))\n\t\talert('Invalid email.');\n\n\t// Form validation:\n\n\tvar f = document.forms['myform'];\n\n\tif (!Validator.isEmail(f.myemail))\n\t\talert('Invalid email.');\n*/\n\nvar Validator = {\n\tisEmail : function(s) {\n\t\treturn this.test(s, '^[-!#$%&\\'*+\\\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\\'*+\\\\/0-9=?A-Z^_`a-z{|}~]+\\.[-!#$%&\\'*+\\\\./0-9=?A-Z^_`a-z{|}~]+$');\n\t},\n\n\tisAbsUrl : function(s) {\n\t\treturn this.test(s, '^(news|telnet|nttp|file|http|ftp|https)://[-A-Za-z0-9\\\\.]+\\\\/?.*$');\n\t},\n\n\tisSize : function(s) {\n\t\treturn this.test(s, '^[0-9]+(%|in|cm|mm|em|ex|pt|pc|px)?$');\n\t},\n\n\tisId : function(s) {\n\t\treturn this.test(s, '^[A-Za-z_]([A-Za-z0-9_])*$');\n\t},\n\n\tisEmpty : function(s) {\n\t\tvar nl, i;\n\n\t\tif (s.nodeName == 'SELECT' && s.selectedIndex < 1)\n\t\t\treturn true;\n\n\t\tif (s.type == 'checkbox' && !s.checked)\n\t\t\treturn true;\n\n\t\tif (s.type == 'radio') {\n\t\t\tfor (i=0, nl = s.form.elements; i<nl.length; i++) {\n\t\t\t\tif (nl[i].type == \"radio\" && nl[i].name == s.name && nl[i].checked)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn new RegExp('^\\\\s*$').test(s.nodeType == 1 ? s.value : s);\n\t},\n\n\tisNumber : function(s, d) {\n\t\treturn !isNaN(s.nodeType == 1 ? s.value : s) && (!d || !this.test(s, '^-?[0-9]*\\\\.[0-9]*$'));\n\t},\n\n\ttest : function(s, p) {\n\t\ts = s.nodeType == 1 ? s.value : s;\n\n\t\treturn s == '' || new RegExp(p).test(s);\n\t}\n};\n\nvar AutoValidator = {\n\tsettings : {\n\t\tid_cls : 'id',\n\t\tint_cls : 'int',\n\t\turl_cls : 'url',\n\t\tnumber_cls : 'number',\n\t\temail_cls : 'email',\n\t\tsize_cls : 'size',\n\t\trequired_cls : 'required',\n\t\tinvalid_cls : 'invalid',\n\t\tmin_cls : 'min',\n\t\tmax_cls : 'max'\n\t},\n\n\tinit : function(s) {\n\t\tvar n;\n\n\t\tfor (n in s)\n\t\t\tthis.settings[n] = s[n];\n\t},\n\n\tvalidate : function(f) {\n\t\tvar i, nl, s = this.settings, c = 0;\n\n\t\tnl = this.tags(f, 'label');\n\t\tfor (i=0; i<nl.length; i++)\n\t\t\tthis.removeClass(nl[i], s.invalid_cls);\n\n\t\tc += this.validateElms(f, 'input');\n\t\tc += this.validateElms(f, 'select');\n\t\tc += this.validateElms(f, 'textarea');\n\n\t\treturn c == 3;\n\t},\n\n\tinvalidate : function(n) {\n\t\tthis.mark(n.form, n);\n\t},\n\n\treset : function(e) {\n\t\tvar t = ['label', 'input', 'select', 'textarea'];\n\t\tvar i, j, nl, s = this.settings;\n\n\t\tif (e == null)\n\t\t\treturn;\n\n\t\tfor (i=0; i<t.length; i++) {\n\t\t\tnl = this.tags(e.form ? e.form : e, t[i]);\n\t\t\tfor (j=0; j<nl.length; j++)\n\t\t\t\tthis.removeClass(nl[j], s.invalid_cls);\n\t\t}\n\t},\n\n\tvalidateElms : function(f, e) {\n\t\tvar nl, i, n, s = this.settings, st = true, va = Validator, v;\n\n\t\tnl = this.tags(f, e);\n\t\tfor (i=0; i<nl.length; i++) {\n\t\t\tn = nl[i];\n\n\t\t\tthis.removeClass(n, s.invalid_cls);\n\n\t\t\tif (this.hasClass(n, s.required_cls) && va.isEmpty(n))\n\t\t\t\tst = this.mark(f, n);\n\n\t\t\tif (this.hasClass(n, s.number_cls) && !va.isNumber(n))\n\t\t\t\tst = this.mark(f, n);\n\n\t\t\tif (this.hasClass(n, s.int_cls) && !va.isNumber(n, true))\n\t\t\t\tst = this.mark(f, n);\n\n\t\t\tif (this.hasClass(n, s.url_cls) && !va.isAbsUrl(n))\n\t\t\t\tst = this.mark(f, n);\n\n\t\t\tif (this.hasClass(n, s.email_cls) && !va.isEmail(n))\n\t\t\t\tst = this.mark(f, n);\n\n\t\t\tif (this.hasClass(n, s.size_cls) && !va.isSize(n))\n\t\t\t\tst = this.mark(f, n);\n\n\t\t\tif (this.hasClass(n, s.id_cls) && !va.isId(n))\n\t\t\t\tst = this.mark(f, n);\n\n\t\t\tif (this.hasClass(n, s.min_cls, true)) {\n\t\t\t\tv = this.getNum(n, s.min_cls);\n\n\t\t\t\tif (isNaN(v) || parseInt(n.value) < parseInt(v))\n\t\t\t\t\tst = this.mark(f, n);\n\t\t\t}\n\n\t\t\tif (this.hasClass(n, s.max_cls, true)) {\n\t\t\t\tv = this.getNum(n, s.max_cls);\n\n\t\t\t\tif (isNaN(v) || parseInt(n.value) > parseInt(v))\n\t\t\t\t\tst = this.mark(f, n);\n\t\t\t}\n\t\t}\n\n\t\treturn st;\n\t},\n\n\thasClass : function(n, c, d) {\n\t\treturn new RegExp('\\\\b' + c + (d ? '[0-9]+' : '') + '\\\\b', 'g').test(n.className);\n\t},\n\n\tgetNum : function(n, c) {\n\t\tc = n.className.match(new RegExp('\\\\b' + c + '([0-9]+)\\\\b', 'g'))[0];\n\t\tc = c.replace(/[^0-9]/g, '');\n\n\t\treturn c;\n\t},\n\n\taddClass : function(n, c, b) {\n\t\tvar o = this.removeClass(n, c);\n\t\tn.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;\n\t},\n\n\tremoveClass : function(n, c) {\n\t\tc = n.className.replace(new RegExp(\"(^|\\\\s+)\" + c + \"(\\\\s+|$)\"), ' ');\n\t\treturn n.className = c != ' ' ? c : '';\n\t},\n\n\ttags : function(f, s) {\n\t\treturn f.getElementsByTagName(s);\n\t},\n\n\tmark : function(f, n) {\n\t\tvar s = this.settings;\n\n\t\tthis.addClass(n, s.invalid_cls);\n\t\tthis.markLabels(f, n, s.invalid_cls);\n\n\t\treturn false;\n\t},\n\n\tmarkLabels : function(f, n, ic) {\n\t\tvar nl, i;\n\n\t\tnl = this.tags(f, \"label\");\n\t\tfor (i=0; i<nl.length; i++) {\n\t\t\tif (nl[i].getAttribute(\"for\") == n.id || nl[i].htmlFor == n.id)\n\t\t\t\tthis.addClass(nl[i], ic);\n\t\t}\n\n\t\treturn null;\n\t}\n};\n"
  },
  {
    "path": "WordpressToTypecho/Action.php",
    "content": "<?php\n\nclass WordpressToTypecho_Action extends Typecho_Widget implements Widget_Interface_Do\n{\n    public function doImport()\n    {\n        $options = $this->widget('Widget_Options');\n        $dbConfig = $options->plugin('WordpressToTypecho');\n\n        /** 初始化一个db */\n        if (Typecho_Db_Adapter_Mysql::isAvailable()) {\n            $db = new Typecho_Db('Mysql', $dbConfig->prefix);\n        } else {\n            $db = new Typecho_Db('Pdo_Mysql', $dbConfig->prefix);\n        }\n        \n        /** 只读即可 */\n        $db->addServer(array (\n          'host' => $dbConfig->host,\n          'user' => $dbConfig->user,\n          'password' => $dbConfig->password,\n          'charset' => 'utf8',\n          'port' => $dbConfig->port,\n          'database' => $dbConfig->database\n        ), Typecho_Db::READ);\n        \n        /** 删除当前内容 */\n        $masterDb = Typecho_Db::get();\n        $this->widget('Widget_Abstract_Contents')->to($contents)->delete($masterDb->sql()->where('1 = 1'));\n        $this->widget('Widget_Abstract_Comments')->to($comments)->delete($masterDb->sql()->where('1 = 1'));\n        $this->widget('Widget_Abstract_Metas')->to($metas)->delete($masterDb->sql()->where('1 = 1'));\n        $this->widget('Widget_Contents_Post_Edit')->to($edit);\n        $masterDb->query($masterDb->delete('table.relationships')->where('1 = 1'));\n        $userId = $this->widget('Widget_User')->uid;\n        \n        /** 获取时区偏移 */\n        $gmtOffset = idate('Z');\n        \n        /** 转换全局变量 */\n\t\t/** \n        $rows = $db->fetchAll($db->select()->from('table.statics'));\n        $static = array();\n        foreach ($rows as $row) {\n            $static[$row['static_name']] = $row['static_value'];\n        }*/\n        \n        /** 转换文件 */\n        /**$files = $db->fetchAll($db->select()->from('table.files'));\n        if (!is_dir(__TYPECHO_ROOT_DIR__ . '/usr/uploads/')) {\n            mkdir(__TYPECHO_ROOT_DIR__ . '/usr/uploads/', 0766);\n        }\n        \n        $pattern = array();\n        $replace = array();\n        foreach ($files as $file) {\n            $path = __TYPECHO_ROOT_DIR__ . '/data/upload/' . substr($file['file_guid'], 0, 2) . '/' .\n            substr($file['file_guid'], 2, 2) . '/' . $file['file_guid'];\n            \n            if (is_file($path)) {\n                $file['file_time'] = empty($file['file_time']) ? $options->gmtTime : $file['file_time'];\n                $year = idate('Y', $file['file_time']);\n                $month = idate('m', $file['file_time']);\n                $day = idate('d', $file['file_time']);\n                \n                if (!is_dir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}\")) {\n                    mkdir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}\", 0766);\n                }\n                \n                if (!is_dir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}\")) {\n                    mkdir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}\", 0766);\n                }\n                \n                if (!is_dir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}/{$day}\")) {\n                    mkdir(__TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}/{$day}\", 0766);\n                }\n                \n                $parts = explode('.', $file['file_name']);\n                $ext = array_pop($parts);\n                copy($path, __TYPECHO_ROOT_DIR__ . \"/usr/uploads/{$year}/{$month}/{$day}/{$file['file_id']}.{$ext}\");\n                \n                $new = Typecho_Common::url(\"/usr/uploads/{$year}/{$month}/{$day}/{$file['file_id']}.{$ext}\", $options->siteUrl);\n                $old = Typecho_Common::url(\"/res/{$file['file_id']}/{$file['file_name']}\", $static['siteurl'] . '/index.php');\n                $pattern[] = '/' . str_replace('\\/index\\.php', '(\\/index\\.php)?', preg_quote($old, '/')) . '/is';\n                $replace[] = $new;\n            }\n        }\n        */\n        /** 转换评论 */\n        $i = 1;\n        \n        while (true) {\n            $result = $db->query($db->select()->from('table.comments')\n            ->order('comment_ID', Typecho_Db::SORT_ASC)->page($i, 100));\n            $j = 0;\n            \n            while ($row = $db->fetchRow($result)) {\n                $status = $row['comment_approved'];\n                if ('spam' == $row['comment_approved']) {\n                    $status = 'spam';\n                } else if ('0' == $row['comment_approved']) {\n                    $status = 'waiting';\n                } else {\n                    $status = 'approved';\n                }\n                \n                $row['comment_content'] = preg_replace(\n                array(\"/\\s*<p>/is\", \"/\\s*<\\/p>\\s*/is\", \"/\\s*<br\\s*\\/>\\s*/is\",\n                \"/\\s*<(div|blockquote|pre|table|ol|ul)>/is\", \"/<\\/(div|blockquote|pre|table|ol|ul)>\\s*/is\"),\n                array('', \"\\n\\n\", \"\\n\", \"\\n\\n<\\\\1>\", \"</\\\\1>\\n\\n\"), \n                $row['comment_content']);\n            \n                $comments->insert(array(\n                    'coid'      =>  $row['comment_ID'],\n                    'cid'       =>  $row['comment_post_ID'],\n                    'created'   =>  strtotime($row['comment_date_gmt']) + $gmtOffset,\n                    'author'    =>  $row['comment_author'],\n                    'authorId'  =>  $row['user_id'],\n                    'ownerId'   =>  1,\n                    'mail'      =>  $row['comment_author_email'],\n                    'url'       =>  $row['comment_author_url'],\n                    'ip'        =>  $row['comment_author_IP'],\n                    'agent'     =>  $row['comment_agent'],\n                    'text'      =>  $row['comment_content'],\n                    'type'      =>  empty($row['comment_type']) ? 'comment' : $row['comment_type'],\n                    'status'    =>  $status,\n                    'parent'    =>  $row['comment_parent']\n                ));\n                $j ++;\n                unset($row);\n            }\n            \n            if ($j < 100) {\n                break;\n            }\n            \n            $i ++;\n            unset($result);\n        }\n\t\t\n\t\t/** 转换Wordpress的term_taxonomy表 */\n\t\t$terms = $db->fetchAll($db->select()->from('table.term_taxonomy')\n        ->join('table.terms', 'table.term_taxonomy.term_id = table.terms.term_id')\n        ->where('taxonomy = ? OR taxonomy = ?', 'category', 'post_tag'));\n        foreach ($terms as $term) {\n            $metas->insert(array(\n                'mid'           =>  $term['term_taxonomy_id'],\n                'name'          =>  $term['name'],\n                'slug'          =>  'post_tag' == $term['taxonomy'] ? Typecho_Common::slugName($term['name']) : $term['slug'],\n                'type'      \t=>  'post_tag' == $term['taxonomy'] ? 'tag' : 'category',\n                'description'   =>  $term['description'],\n                'count'      \t=>  $term['count'],\n            ));\n            \n            /** 转换关系表 */\n            $relationships = $db->fetchAll($db->select()->from('table.term_relationships')\n            ->where('term_taxonomy_id = ?', $term['term_taxonomy_id']));\n            foreach ($relationships as $relationship) {\n                $masterDb->query($masterDb->insert('table.relationships')->rows(array(\n                    'cid'      \t=>  $relationship['object_id'],\n                    'mid'   \t=>  $relationship['term_taxonomy_id'],\n                )));\n            }\n        }\n\t\t\n        /** 转换内容 */\n        $i = 1;\n        \n        while (true) {\n            $result = $db->query($db->select()->from('table.posts')\n            ->where('post_type = ? OR post_type = ?', 'post', 'page')\n            ->order('ID', Typecho_Db::SORT_ASC)->page($i, 100));\n            $j = 0;\n            \n            while ($row = $db->fetchRow($result)) {\n                $contents->insert(array(\n                    'cid'           =>  $row['ID'],\n                    'title'         =>  $row['post_title'],\n                    'slug'          =>  Typecho_Common::slugName(urldecode($row['post_name']), $row['ID'], 128),\n                    'created'       =>  strtotime($row['post_date_gmt']) + $gmtOffset > 0 ? strtotime($row['post_date_gmt']) + $gmtOffset : 0,\n                    'modified'      =>  strtotime($row['post_modified_gmt']) + $gmtOffset,\n                    'text'          =>  $row['post_content'],\n                    'order'         =>  $row['menu_order'],\n                    'authorId'      =>  $row['post_author'],\n                    'template'      =>  NULL,\n                    'type'          =>  'page' == $row['post_type'] ? 'page' : 'post',\n                    'status'        =>  'publish' == $row['post_status'] ? 'publish' : 'draft',\n                    'password'      =>  $row['post_password'],\n                    'commentsNum'   =>  $row['comment_count'],\n                    'allowComment'  =>  'open' == $row['comment_status']? '1' : '0',\n                    'allowFeed'     =>  '1',\n                    'allowPing'     =>  'open' == $row['ping_status']? '1' : '0',\n                ));\n                \n                $j ++;\n                unset($row);\n            }\n            \n            if ($j < 100) {\n                break;\n            }\n            \n            $i ++;\n            unset($result);\n        }\n        \n        $this->widget('Widget_Notice')->set(_t(\"数据已经转换完成\"), NULL, 'success');\n        $this->response->goBack();\n    }\n\n    public function action()\n    {\n        $this->widget('Widget_User')->pass('administrator');\n        $this->on($this->request->isPost())->doImport();\n    }\n}\n"
  },
  {
    "path": "WordpressToTypecho/Plugin.php",
    "content": "<?php\n/**\n * 将 WordPress 数据库中的数据转换为 Typecho\n * \n * @package WordPress to Typecho\n * @author qining\n * @version 1.0.3 Beta\n * @link http://typecho.org\n */\nclass WordpressToTypecho_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        if (!Typecho_Db_Adapter_Mysql::isAvailable() && !Typecho_Db_Adapter_Pdo_Mysql::isAvailable()) {\n            throw new Typecho_Plugin_Exception(_t('没有找到任何可用的 Mysql 适配器'));\n        }\n        \n        /**$error = NULL;\n        if ((!is_dir(__TYPECHO_ROOT_DIR__ . '/usr/uploads/') || !is_writeable(__TYPECHO_ROOT_DIR__ . '/usr/uploads/'))\n        && !is_writeable(__TYPECHO_ROOT_DIR__ . '/usr/')) {\n            $error = '<br /><strong>' . _t('%s 目录不可写, 可能会导致附件转换不成功', __TYPECHO_ROOT_DIR__ . '/usr/uploads/') . '</strong>';\n        }\n\t\t*/\n    \n        Helper::addPanel(1, 'WordpressToTypecho/panel.php', _t('从 WordPress 导入数据'), _t('从 WordPress 导入数据'), 'administrator');\n        Helper::addAction('wordpress-to-typecho', 'WordpressToTypecho_Action');\n        return _t('请在插件设置里设置 WordPress 所在的数据库参数') . $error;\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate()\n    {\n        Helper::removeAction('wordpress-to-typecho');\n        Helper::removePanel(1, 'WordpressToTypecho/panel.php');\n    }\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form)\n    {\n        $host = new Typecho_Widget_Helper_Form_Element_Text('host', NULL, 'localhost',\n        _t('数据库地址'), _t('请填写 WordPress 所在的数据库地址'));\n        $form->addInput($host->addRule('required', _t('必须填写一个数据库地址')));\n        \n        $port = new Typecho_Widget_Helper_Form_Element_Text('port', NULL, '3306',\n        _t('数据库端口'), _t('WordPress 所在的数据库服务器端口'));\n        $port->input->setAttribute('class', 'mini');\n        $form->addInput($port->addRule('required', _t('必须填写数据库端口'))\n        ->addRule('isInteger', _t('端口号必须是纯数字')));\n        \n        $user = new Typecho_Widget_Helper_Form_Element_Text('user', NULL, 'root',\n        _t('数据库用户名'));\n        $form->addInput($user->addRule('required', _t('必须填写数据库用户名')));\n        \n        $password = new Typecho_Widget_Helper_Form_Element_Password('password', NULL, NULL,\n        _t('数据库密码'));\n        $form->addInput($password);\n        \n        $database = new Typecho_Widget_Helper_Form_Element_Text('database', NULL, 'wordpress',\n        _t('数据库名称'), _t('WordPress 所在的数据库名称'));\n        $form->addInput($database->addRule('required', _t('您必须填写数据库名称')));\n    \n        $prefix = new Typecho_Widget_Helper_Form_Element_Text('prefix', NULL, 'wp_',\n        _t('表前缀'), _t('所有 WordPress 数据表的前缀'));\n        $form->addInput($prefix->addRule('required', _t('您必须填写表前缀')));\n    }\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n}\n"
  },
  {
    "path": "WordpressToTypecho/panel.php",
    "content": "<?php\nif (!defined('__TYPECHO_ROOT_DIR__')) {\n    exit;\n}\n\n$success = true;\ntry {\n    $dbConfig = $options->plugin('WordpressToTypecho');\n\n    /** 初始化一个db */\n    if (Typecho_Db_Adapter_Mysql::isAvailable()) {\n        $wordpressDb = new Typecho_Db('Mysql', $dbConfig->prefix);\n    } else {\n        $wordpressDb = new Typecho_Db('Pdo_Mysql', $dbConfig->prefix);\n    }\n\n    /** 只读即可 */\n    $wordpressDb->addServer(array (\n      'host' => $dbConfig->host,\n      'user' => $dbConfig->user,\n      'password' => $dbConfig->password,\n      'charset' => 'utf8',\n      'port' => $dbConfig->port,\n      'database' => $dbConfig->database\n    ), Typecho_Db::READ);\n    \n    $rows = $wordpressDb->fetchAll($wordpressDb->select()->from('table.options'));\n    $static = array();\n    foreach ($rows as $row) {\n        $static[$row['option_name']] = $row['option_value'];\n    }\n} catch (Typecho_Db_Exception $e) {\n    $success = false;\n}\n\ninclude 'header.php';\ninclude 'menu.php';\n?>\n<div class=\"main\">\n    <div class=\"body container\">\n        <div class=\"colgroup\">\n            <?php include 'page-title.php'; ?>\n        </div>\n        <div class=\"colgroup typecho-page-main\" role=\"main\">\n            <div class=\"com-mb-12\">\n                <?php if ($success): ?>\n                <div class=\"message notice\">\n                <form action=\"<?php $options->index('/action/wordpress-to-typecho'); ?>\" method=\"post\">\n                    <?php _e('我们检测到了 WordPress 系统信息, 点击下方的按钮开始数据转换, 数据转换可能会耗时较长.'); ?>\n                    <ul>\n                        <li><strong><?php echo $static['blogname']; ?></strong></li>\n                        <li><?php echo $static['blogdescription']; ?></li>\n                        <li><code><?php echo $static['siteurl']; ?></code></li>\n                    </ul>\n                    <button type=\"submit\" class=\"primary\"><?php _e('开始数据转换 &raquo;'); ?></button>\n                </form>\n                </div>\n                <?php else: ?>\n                <div class=\"message error\">\n                    <?php _e('我们在连接到 WordPress 的数据库时发生了错误, 请<a href=\"%s\">重新设置</a>你的信息.', \n                    Typecho_Common::url('options-plugin.php?config=WordpressToTypecho', $options->adminUrl)); ?>\n                </div>\n                <?php endif; ?>\n            </div>\n        </div>\n    </div>\n</div>\n<?php\ninclude 'copyright.php';\ninclude 'common-js.php';\ninclude 'footer.php';\n?>\n"
  },
  {
    "path": "ZenCoding/Plugin.php",
    "content": "<?php\n/**\n * Set of plugins for HTML and CSS hi-speed coding\n * \n * @package Zen Coding\n * @author qining\n * @version 1.0.0\n * @link http://code.google.com/p/zen-coding/\n */\nclass ZenCoding_Plugin implements Typecho_Plugin_Interface\n{\n    /**\n     * 激活插件方法,如果激活失败,直接抛出异常\n     * \n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function activate()\n    {\n        Typecho_Plugin::factory('admin/write-post.php')->bottom = array('ZenCoding_Plugin', 'writeBottom');\n        Typecho_Plugin::factory('admin/write-page.php')->bottom = array('ZenCoding_Plugin', 'writeBottom');\n        Typecho_Plugin::factory('admin/theme-editor.php')->bottom = array('ZenCoding_Plugin', 'themeBottom');\n    }\n    \n    /**\n     * 禁用插件方法,如果禁用失败,直接抛出异常\n     * \n     * @static\n     * @access public\n     * @return void\n     * @throws Typecho_Plugin_Exception\n     */\n    public static function deactivate()\n    {}\n    \n    /**\n     * 获取插件配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form 配置面板\n     * @return void\n     */\n    public static function config(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 个人用户的配置面板\n     * \n     * @access public\n     * @param Typecho_Widget_Helper_Form $form\n     * @return void\n     */\n    public static function personalConfig(Typecho_Widget_Helper_Form $form){}\n    \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function themeBottom($files)\n    {\n        $options = Helper::options();\n        $js = Typecho_Common::url('ZenCoding/zen_textarea.js', $options->pluginUrl);\n        echo \"<script type=\\\"text/javascript\\\" src=\\\"{$js}\\\"></script>\n<script type=\\\"text/javascript\\\">\n    $(document).getElement('#content').addClass('zc-use_tab-true zc-syntax-xsl zc-profile-xml');\n    zen_textarea.setup({pretty_break: true});\n</script>\";\n    }\n    \n    /**\n     * 插件实现方法\n     * \n     * @access public\n     * @return void\n     */\n    public static function writeBottom($post)\n    {\n        $options = Helper::options();\n        $js = Typecho_Common::url('ZenCoding/zen_textarea.js', $options->pluginUrl);\n        echo \"<script type=\\\"text/javascript\\\" src=\\\"{$js}\\\"></script>\n<script type=\\\"text/javascript\\\">\n    $(document).getElement('#text').addClass('zc-use_tab-true zc-syntax-xsl zc-profile-xml');\n    zen_textarea.setup({pretty_break: true});\n</script>\";\n    }\n}\n"
  },
  {
    "path": "ZenCoding/zen_textarea.js",
    "content": "(function(){\n/**\n * Zen Coding settings\n * @author Sergey Chikuyonok (serge.che@gmail.com)\n * @link http://chikuyonok.ru\n */\nvar zen_settings = {\n\t/** \n\t * Variables that can be placed inside snippets or abbreviations as ${variable}\n\t * ${child} variable is reserved, don't use it \n\t */\n\t'variables': {\n\t\t'lang': 'en',\n\t\t'locale': 'en-US',\n\t\t'charset': 'UTF-8',\n\t\t'profile': 'xhtml',\n\t\t\n\t\t/** Inner element indentation */\n\t\t'indentation': '\\t'     // TODO take from Aptana settings\n\t},\n\t\n\t'css': {\n\t\t'snippets': {\n\t\t\t\"@i\": \"@import url(|);\",\n\t\t\t\"@m\": \"@media print {\\n\\t|\\n}\",\n\t\t\t\"@f\": \"@font-face {\\n\\tfont-family:|;\\n\\tsrc:url(|);\\n}\",\n\t\t\t\"!\": \"!important\",\n\t\t\t\"pos\": \"position:|;\",\n\t\t\t\"pos:s\": \"position:static;\",\n\t\t\t\"pos:a\": \"position:absolute;\",\n\t\t\t\"pos:r\": \"position:relative;\",\n\t\t\t\"pos:f\": \"position:fixed;\",\n\t\t\t\"t\": \"top:|;\",\n\t\t\t\"t:a\": \"top:auto;\",\n\t\t\t\"r\": \"right:|;\",\n\t\t\t\"r:a\": \"right:auto;\",\n\t\t\t\"b\": \"bottom:|;\",\n\t\t\t\"b:a\": \"bottom:auto;\",\n\t\t\t\"l\": \"left:|;\",\n\t\t\t\"l:a\": \"left:auto;\",\n\t\t\t\"z\": \"z-index:|;\",\n\t\t\t\"z:a\": \"z-index:auto;\",\n\t\t\t\"fl\": \"float:|;\",\n\t\t\t\"fl:n\": \"float:none;\",\n\t\t\t\"fl:l\": \"float:left;\",\n\t\t\t\"fl:r\": \"float:right;\",\n\t\t\t\"cl\": \"clear:|;\",\n\t\t\t\"cl:n\": \"clear:none;\",\n\t\t\t\"cl:l\": \"clear:left;\",\n\t\t\t\"cl:r\": \"clear:right;\",\n\t\t\t\"cl:b\": \"clear:both;\",\n\t\t\t\"d\": \"display:|;\",\n\t\t\t\"d:n\": \"display:none;\",\n\t\t\t\"d:b\": \"display:block;\",\n\t\t\t\"d:ib\": \"display:inline;\",\n\t\t\t\"d:li\": \"display:list-item;\",\n\t\t\t\"d:ri\": \"display:run-in;\",\n\t\t\t\"d:cp\": \"display:compact;\",\n\t\t\t\"d:tb\": \"display:table;\",\n\t\t\t\"d:itb\": \"display:inline-table;\",\n\t\t\t\"d:tbcp\": \"display:table-caption;\",\n\t\t\t\"d:tbcl\": \"display:table-column;\",\n\t\t\t\"d:tbclg\": \"display:table-column-group;\",\n\t\t\t\"d:tbhg\": \"display:table-header-group;\",\n\t\t\t\"d:tbfg\": \"display:table-footer-group;\",\n\t\t\t\"d:tbr\": \"display:table-row;\",\n\t\t\t\"d:tbrg\": \"display:table-row-group;\",\n\t\t\t\"d:tbc\": \"display:table-cell;\",\n\t\t\t\"d:rb\": \"display:ruby;\",\n\t\t\t\"d:rbb\": \"display:ruby-base;\",\n\t\t\t\"d:rbbg\": \"display:ruby-base-group;\",\n\t\t\t\"d:rbt\": \"display:ruby-text;\",\n\t\t\t\"d:rbtg\": \"display:ruby-text-group;\",\n\t\t\t\"v\": \"visibility:|;\",\n\t\t\t\"v:v\": \"visibility:visible;\",\n\t\t\t\"v:h\": \"visibility:hidden;\",\n\t\t\t\"v:c\": \"visibility:collapse;\",\n\t\t\t\"ov\": \"overflow:|;\",\n\t\t\t\"ov:v\": \"overflow:visible;\",\n\t\t\t\"ov:h\": \"overflow:hidden;\",\n\t\t\t\"ov:s\": \"overflow:scroll;\",\n\t\t\t\"ov:a\": \"overflow:auto;\",\n\t\t\t\"ovx\": \"overflow-x:|;\",\n\t\t\t\"ovx:v\": \"overflow-x:visible;\",\n\t\t\t\"ovx:h\": \"overflow-x:hidden;\",\n\t\t\t\"ovx:s\": \"overflow-x:scroll;\",\n\t\t\t\"ovx:a\": \"overflow-x:auto;\",\n\t\t\t\"ovy\": \"overflow-y:|;\",\n\t\t\t\"ovy:v\": \"overflow-y:visible;\",\n\t\t\t\"ovy:h\": \"overflow-y:hidden;\",\n\t\t\t\"ovy:s\": \"overflow-y:scroll;\",\n\t\t\t\"ovy:a\": \"overflow-y:auto;\",\n\t\t\t\"ovs\": \"overflow-style:|;\",\n\t\t\t\"ovs:a\": \"overflow-style:auto;\",\n\t\t\t\"ovs:s\": \"overflow-style:scrollbar;\",\n\t\t\t\"ovs:p\": \"overflow-style:panner;\",\n\t\t\t\"ovs:m\": \"overflow-style:move;\",\n\t\t\t\"ovs:mq\": \"overflow-style:marquee;\",\n\t\t\t\"zoo\": \"zoom:1;\",\n\t\t\t\"cp\": \"clip:|;\",\n\t\t\t\"cp:a\": \"clip:auto;\",\n\t\t\t\"cp:r\": \"clip:rect(|);\",\n\t\t\t\"bxz\": \"box-sizing:|;\",\n\t\t\t\"bxz:cb\": \"box-sizing:content-box;\",\n\t\t\t\"bxz:bb\": \"box-sizing:border-box;\",\n\t\t\t\"bxsh\": \"box-shadow:|;\",\n\t\t\t\"bxsh:n\": \"box-shadow:none;\",\n\t\t\t\"bxsh:w\": \"-webkit-box-shadow:0 0 0 #000;\",\n\t\t\t\"bxsh:m\": \"-moz-box-shadow:0 0 0 0 #000;\",\n\t\t\t\"m\": \"margin:|;\",\n\t\t\t\"m:a\": \"margin:auto;\",\n\t\t\t\"m:0\": \"margin:0;\",\n\t\t\t\"m:2\": \"margin:0 0;\",\n\t\t\t\"m:3\": \"margin:0 0 0;\",\n\t\t\t\"m:4\": \"margin:0 0 0 0;\",\n\t\t\t\"mt\": \"margin-top:|;\",\n\t\t\t\"mt:a\": \"margin-top:auto;\",\n\t\t\t\"mr\": \"margin-right:|;\",\n\t\t\t\"mr:a\": \"margin-right:auto;\",\n\t\t\t\"mb\": \"margin-bottom:|;\",\n\t\t\t\"mb:a\": \"margin-bottom:auto;\",\n\t\t\t\"ml\": \"margin-left:|;\",\n\t\t\t\"ml:a\": \"margin-left:auto;\",\n\t\t\t\"p\": \"padding:|;\",\n\t\t\t\"p:0\": \"padding:0;\",\n\t\t\t\"p:2\": \"padding:0 0;\",\n\t\t\t\"p:3\": \"padding:0 0 0;\",\n\t\t\t\"p:4\": \"padding:0 0 0 0;\",\n\t\t\t\"pt\": \"padding-top:|;\",\n\t\t\t\"pr\": \"padding-right:|;\",\n\t\t\t\"pb\": \"padding-bottom:|;\",\n\t\t\t\"pl\": \"padding-left:|;\",\n\t\t\t\"w\": \"width:|;\",\n\t\t\t\"w:a\": \"width:auto;\",\n\t\t\t\"h\": \"height:|;\",\n\t\t\t\"h:a\": \"height:auto;\",\n\t\t\t\"maw\": \"max-width:|;\",\n\t\t\t\"maw:n\": \"max-width:none;\",\n\t\t\t\"mah\": \"max-height:|;\",\n\t\t\t\"mah:n\": \"max-height:none;\",\n\t\t\t\"miw\": \"min-width:|;\",\n\t\t\t\"mih\": \"min-height:|;\",\n\t\t\t\"o\": \"outline:|;\",\n\t\t\t\"o:n\": \"outline:none;\",\n\t\t\t\"oo\": \"outline-offset:|;\",\n\t\t\t\"ow\": \"outline-width:|;\",\n\t\t\t\"os\": \"outline-style:|;\",\n\t\t\t\"oc\": \"outline-color:#000;\",\n\t\t\t\"oc:i\": \"outline-color:invert;\",\n\t\t\t\"bd\": \"border:|;\",\n\t\t\t\"bd+\": \"border:1px solid #000;\",\n\t\t\t\"bd:n\": \"border:none;\",\n\t\t\t\"bdbk\": \"border-break:|;\",\n\t\t\t\"bdbk:c\": \"border-break:close;\",\n\t\t\t\"bdcl\": \"border-collapse:|;\",\n\t\t\t\"bdcl:c\": \"border-collapse:collapse;\",\n\t\t\t\"bdcl:s\": \"border-collapse:separate;\",\n\t\t\t\"bdc\": \"border-color:#000;\",\n\t\t\t\"bdi\": \"border-image:url(|);\",\n\t\t\t\"bdi:n\": \"border-image:none;\",\n\t\t\t\"bdi:w\": \"-webkit-border-image:url(|) 0 0 0 0 stretch stretch;\",\n\t\t\t\"bdi:m\": \"-moz-border-image:url(|) 0 0 0 0 stretch stretch;\",\n\t\t\t\"bdti\": \"border-top-image:url(|);\",\n\t\t\t\"bdti:n\": \"border-top-image:none;\",\n\t\t\t\"bdri\": \"border-right-image:url(|);\",\n\t\t\t\"bdri:n\": \"border-right-image:none;\",\n\t\t\t\"bdbi\": \"border-bottom-image:url(|);\",\n\t\t\t\"bdbi:n\": \"border-bottom-image:none;\",\n\t\t\t\"bdli\": \"border-left-image:url(|);\",\n\t\t\t\"bdli:n\": \"border-left-image:none;\",\n\t\t\t\"bdci\": \"border-corner-image:url(|);\",\n\t\t\t\"bdci:n\": \"border-corner-image:none;\",\n\t\t\t\"bdci:c\": \"border-corner-image:continue;\",\n\t\t\t\"bdtli\": \"border-top-left-image:url(|);\",\n\t\t\t\"bdtli:n\": \"border-top-left-image:none;\",\n\t\t\t\"bdtli:c\": \"border-top-left-image:continue;\",\n\t\t\t\"bdtri\": \"border-top-right-image:url(|);\",\n\t\t\t\"bdtri:n\": \"border-top-right-image:none;\",\n\t\t\t\"bdtri:c\": \"border-top-right-image:continue;\",\n\t\t\t\"bdbri\": \"border-bottom-right-image:url(|);\",\n\t\t\t\"bdbri:n\": \"border-bottom-right-image:none;\",\n\t\t\t\"bdbri:c\": \"border-bottom-right-image:continue;\",\n\t\t\t\"bdbli\": \"border-bottom-left-image:url(|);\",\n\t\t\t\"bdbli:n\": \"border-bottom-left-image:none;\",\n\t\t\t\"bdbli:c\": \"border-bottom-left-image:continue;\",\n\t\t\t\"bdf\": \"border-fit:|;\",\n\t\t\t\"bdf:c\": \"border-fit:clip;\",\n\t\t\t\"bdf:r\": \"border-fit:repeat;\",\n\t\t\t\"bdf:sc\": \"border-fit:scale;\",\n\t\t\t\"bdf:st\": \"border-fit:stretch;\",\n\t\t\t\"bdf:ow\": \"border-fit:overwrite;\",\n\t\t\t\"bdf:of\": \"border-fit:overflow;\",\n\t\t\t\"bdf:sp\": \"border-fit:space;\",\n\t\t\t\"bdl\": \"border-length:|;\",\n\t\t\t\"bdl:a\": \"border-length:auto;\",\n\t\t\t\"bdsp\": \"border-spacing:|;\",\n\t\t\t\"bds\": \"border-style:|;\",\n\t\t\t\"bds:n\": \"border-style:none;\",\n\t\t\t\"bds:h\": \"border-style:hidden;\",\n\t\t\t\"bds:dt\": \"border-style:dotted;\",\n\t\t\t\"bds:ds\": \"border-style:dashed;\",\n\t\t\t\"bds:s\": \"border-style:solid;\",\n\t\t\t\"bds:db\": \"border-style:double;\",\n\t\t\t\"bds:dtds\": \"border-style:dot-dash;\",\n\t\t\t\"bds:dtdtds\": \"border-style:dot-dot-dash;\",\n\t\t\t\"bds:w\": \"border-style:wave;\",\n\t\t\t\"bds:g\": \"border-style:groove;\",\n\t\t\t\"bds:r\": \"border-style:ridge;\",\n\t\t\t\"bds:i\": \"border-style:inset;\",\n\t\t\t\"bds:o\": \"border-style:outset;\",\n\t\t\t\"bdw\": \"border-width:|;\",\n\t\t\t\"bdt\": \"border-top:|;\",\n\t\t\t\"bdt+\": \"border-top:1px solid #000;\",\n\t\t\t\"bdt:n\": \"border-top:none;\",\n\t\t\t\"bdtw\": \"border-top-width:|;\",\n\t\t\t\"bdts\": \"border-top-style:|;\",\n\t\t\t\"bdts:n\": \"border-top-style:none;\",\n\t\t\t\"bdtc\": \"border-top-color:#000;\",\n\t\t\t\"bdr\": \"border-right:|;\",\n\t\t\t\"bdr+\": \"border-right:1px solid #000;\",\n\t\t\t\"bdr:n\": \"border-right:none;\",\n\t\t\t\"bdrw\": \"border-right-width:|;\",\n\t\t\t\"bdrs\": \"border-right-style:|;\",\n\t\t\t\"bdrs:n\": \"border-right-style:none;\",\n\t\t\t\"bdrc\": \"border-right-color:#000;\",\n\t\t\t\"bdb\": \"border-bottom:|;\",\n\t\t\t\"bdb+\": \"border-bottom:1px solid #000;\",\n\t\t\t\"bdb:n\": \"border-bottom:none;\",\n\t\t\t\"bdbw\": \"border-bottom-width:|;\",\n\t\t\t\"bdbs\": \"border-bottom-style:|;\",\n\t\t\t\"bdbs:n\": \"border-bottom-style:none;\",\n\t\t\t\"bdbc\": \"border-bottom-color:#000;\",\n\t\t\t\"bdl\": \"border-left:|;\",\n\t\t\t\"bdl+\": \"border-left:1px solid #000;\",\n\t\t\t\"bdl:n\": \"border-left:none;\",\n\t\t\t\"bdlw\": \"border-left-width:|;\",\n\t\t\t\"bdls\": \"border-left-style:|;\",\n\t\t\t\"bdls:n\": \"border-left-style:none;\",\n\t\t\t\"bdlc\": \"border-left-color:#000;\",\n\t\t\t\"bdrs\": \"border-radius:|;\",\n\t\t\t\"bdtrrs\": \"border-top-right-radius:|;\",\n\t\t\t\"bdtlrs\": \"border-top-left-radius:|;\",\n\t\t\t\"bdbrrs\": \"border-bottom-right-radius:|;\",\n\t\t\t\"bdblrs\": \"border-bottom-left-radius:|;\",\n\t\t\t\"bg\": \"background:|;\",\n\t\t\t\"bg+\": \"background:#FFF url(|) 0 0 no-repeat;\",\n\t\t\t\"bg:n\": \"background:none;\",\n\t\t\t\"bg:ie\": \"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='|x.png');\",\n\t\t\t\"bgc\": \"background-color:#FFF;\",\n\t\t\t\"bgi\": \"background-image:url(|);\",\n\t\t\t\"bgi:n\": \"background-image:none;\",\n\t\t\t\"bgr\": \"background-repeat:|;\",\n\t\t\t\"bgr:n\": \"background-repeat:no-repeat;\",\n\t\t\t\"bgr:x\": \"background-repeat:repeat-x;\",\n\t\t\t\"bgr:y\": \"background-repeat:repeat-y;\",\n\t\t\t\"bga\": \"background-attachment:|;\",\n\t\t\t\"bga:f\": \"background-attachment:fixed;\",\n\t\t\t\"bga:s\": \"background-attachment:scroll;\",\n\t\t\t\"bgp\": \"background-position:0 0;\",\n\t\t\t\"bgpx\": \"background-position-x:|;\",\n\t\t\t\"bgpy\": \"background-position-y:|;\",\n\t\t\t\"bgbk\": \"background-break:|;\",\n\t\t\t\"bgbk:bb\": \"background-break:bounding-box;\",\n\t\t\t\"bgbk:eb\": \"background-break:each-box;\",\n\t\t\t\"bgbk:c\": \"background-break:continuous;\",\n\t\t\t\"bgcp\": \"background-clip:|;\",\n\t\t\t\"bgcp:bb\": \"background-clip:border-box;\",\n\t\t\t\"bgcp:pb\": \"background-clip:padding-box;\",\n\t\t\t\"bgcp:cb\": \"background-clip:content-box;\",\n\t\t\t\"bgcp:nc\": \"background-clip:no-clip;\",\n\t\t\t\"bgo\": \"background-origin:|;\",\n\t\t\t\"bgo:pb\": \"background-origin:padding-box;\",\n\t\t\t\"bgo:bb\": \"background-origin:border-box;\",\n\t\t\t\"bgo:cb\": \"background-origin:content-box;\",\n\t\t\t\"bgz\": \"background-size:|;\",\n\t\t\t\"bgz:a\": \"background-size:auto;\",\n\t\t\t\"bgz:ct\": \"background-size:contain;\",\n\t\t\t\"bgz:cv\": \"background-size:cover;\",\n\t\t\t\"c\": \"color:#000;\",\n\t\t\t\"tbl\": \"table-layout:|;\",\n\t\t\t\"tbl:a\": \"table-layout:auto;\",\n\t\t\t\"tbl:f\": \"table-layout:fixed;\",\n\t\t\t\"cps\": \"caption-side:|;\",\n\t\t\t\"cps:t\": \"caption-side:top;\",\n\t\t\t\"cps:b\": \"caption-side:bottom;\",\n\t\t\t\"ec\": \"empty-cells:|;\",\n\t\t\t\"ec:s\": \"empty-cells:show;\",\n\t\t\t\"ec:h\": \"empty-cells:hide;\",\n\t\t\t\"lis\": \"list-style:|;\",\n\t\t\t\"lis:n\": \"list-style:none;\",\n\t\t\t\"lisp\": \"list-style-position:|;\",\n\t\t\t\"lisp:i\": \"list-style-position:inside;\",\n\t\t\t\"lisp:o\": \"list-style-position:outside;\",\n\t\t\t\"list\": \"list-style-type:|;\",\n\t\t\t\"list:n\": \"list-style-type:none;\",\n\t\t\t\"list:d\": \"list-style-type:disc;\",\n\t\t\t\"list:c\": \"list-style-type:circle;\",\n\t\t\t\"list:s\": \"list-style-type:square;\",\n\t\t\t\"list:dc\": \"list-style-type:decimal;\",\n\t\t\t\"list:dclz\": \"list-style-type:decimal-leading-zero;\",\n\t\t\t\"list:lr\": \"list-style-type:lower-roman;\",\n\t\t\t\"list:ur\": \"list-style-type:upper-roman;\",\n\t\t\t\"lisi\": \"list-style-image:|;\",\n\t\t\t\"lisi:n\": \"list-style-image:none;\",\n\t\t\t\"q\": \"quotes:|;\",\n\t\t\t\"q:n\": \"quotes:none;\",\n\t\t\t\"q:ru\": \"quotes:'\\00AB' '\\00BB' '\\201E' '\\201C';\",\n\t\t\t\"q:en\": \"quotes:'\\201C' '\\201D' '\\2018' '\\2019';\",\n\t\t\t\"ct\": \"content:|;\",\n\t\t\t\"ct:n\": \"content:normal;\",\n\t\t\t\"ct:oq\": \"content:open-quote;\",\n\t\t\t\"ct:noq\": \"content:no-open-quote;\",\n\t\t\t\"ct:cq\": \"content:close-quote;\",\n\t\t\t\"ct:ncq\": \"content:no-close-quote;\",\n\t\t\t\"ct:a\": \"content:attr(|);\",\n\t\t\t\"ct:c\": \"content:counter(|);\",\n\t\t\t\"ct:cs\": \"content:counters(|);\",\n\t\t\t\"coi\": \"counter-increment:|;\",\n\t\t\t\"cor\": \"counter-reset:|;\",\n\t\t\t\"va\": \"vertical-align:|;\",\n\t\t\t\"va:sup\": \"vertical-align:super;\",\n\t\t\t\"va:t\": \"vertical-align:top;\",\n\t\t\t\"va:tt\": \"vertical-align:text-top;\",\n\t\t\t\"va:m\": \"vertical-align:middle;\",\n\t\t\t\"va:bl\": \"vertical-align:baseline;\",\n\t\t\t\"va:b\": \"vertical-align:bottom;\",\n\t\t\t\"va:tb\": \"vertical-align:text-bottom;\",\n\t\t\t\"va:sub\": \"vertical-align:sub;\",\n\t\t\t\"ta\": \"text-align:|;\",\n\t\t\t\"ta:l\": \"text-align:left;\",\n\t\t\t\"ta:c\": \"text-align:center;\",\n\t\t\t\"ta:r\": \"text-align:right;\",\n\t\t\t\"tal\": \"text-align-last:|;\",\n\t\t\t\"tal:a\": \"text-align-last:auto;\",\n\t\t\t\"tal:l\": \"text-align-last:left;\",\n\t\t\t\"tal:c\": \"text-align-last:center;\",\n\t\t\t\"tal:r\": \"text-align-last:right;\",\n\t\t\t\"td\": \"text-decoration:|;\",\n\t\t\t\"td:n\": \"text-decoration:none;\",\n\t\t\t\"td:u\": \"text-decoration:underline;\",\n\t\t\t\"td:o\": \"text-decoration:overline;\",\n\t\t\t\"td:l\": \"text-decoration:line-through;\",\n\t\t\t\"te\": \"text-emphasis:|;\",\n\t\t\t\"te:n\": \"text-emphasis:none;\",\n\t\t\t\"te:ac\": \"text-emphasis:accent;\",\n\t\t\t\"te:dt\": \"text-emphasis:dot;\",\n\t\t\t\"te:c\": \"text-emphasis:circle;\",\n\t\t\t\"te:ds\": \"text-emphasis:disc;\",\n\t\t\t\"te:b\": \"text-emphasis:before;\",\n\t\t\t\"te:a\": \"text-emphasis:after;\",\n\t\t\t\"th\": \"text-height:|;\",\n\t\t\t\"th:a\": \"text-height:auto;\",\n\t\t\t\"th:f\": \"text-height:font-size;\",\n\t\t\t\"th:t\": \"text-height:text-size;\",\n\t\t\t\"th:m\": \"text-height:max-size;\",\n\t\t\t\"ti\": \"text-indent:|;\",\n\t\t\t\"ti:-\": \"text-indent:-9999px;\",\n\t\t\t\"tj\": \"text-justify:|;\",\n\t\t\t\"tj:a\": \"text-justify:auto;\",\n\t\t\t\"tj:iw\": \"text-justify:inter-word;\",\n\t\t\t\"tj:ii\": \"text-justify:inter-ideograph;\",\n\t\t\t\"tj:ic\": \"text-justify:inter-cluster;\",\n\t\t\t\"tj:d\": \"text-justify:distribute;\",\n\t\t\t\"tj:k\": \"text-justify:kashida;\",\n\t\t\t\"tj:t\": \"text-justify:tibetan;\",\n\t\t\t\"to\": \"text-outline:|;\",\n\t\t\t\"to+\": \"text-outline:0 0 #000;\",\n\t\t\t\"to:n\": \"text-outline:none;\",\n\t\t\t\"tr\": \"text-replace:|;\",\n\t\t\t\"tr:n\": \"text-replace:none;\",\n\t\t\t\"tt\": \"text-transform:|;\",\n\t\t\t\"tt:n\": \"text-transform:none;\",\n\t\t\t\"tt:c\": \"text-transform:capitalize;\",\n\t\t\t\"tt:u\": \"text-transform:uppercase;\",\n\t\t\t\"tt:l\": \"text-transform:lowercase;\",\n\t\t\t\"tw\": \"text-wrap:|;\",\n\t\t\t\"tw:n\": \"text-wrap:normal;\",\n\t\t\t\"tw:no\": \"text-wrap:none;\",\n\t\t\t\"tw:u\": \"text-wrap:unrestricted;\",\n\t\t\t\"tw:s\": \"text-wrap:suppress;\",\n\t\t\t\"tsh\": \"text-shadow:|;\",\n\t\t\t\"tsh+\": \"text-shadow:0 0 0 #000;\",\n\t\t\t\"tsh:n\": \"text-shadow:none;\",\n\t\t\t\"lh\": \"line-height:|;\",\n\t\t\t\"whs\": \"white-space:|;\",\n\t\t\t\"whs:n\": \"white-space:normal;\",\n\t\t\t\"whs:p\": \"white-space:pre;\",\n\t\t\t\"whs:nw\": \"white-space:nowrap;\",\n\t\t\t\"whs:pw\": \"white-space:pre-wrap;\",\n\t\t\t\"whs:pl\": \"white-space:pre-line;\",\n\t\t\t\"whsc\": \"white-space-collapse:|;\",\n\t\t\t\"whsc:n\": \"white-space-collapse:normal;\",\n\t\t\t\"whsc:k\": \"white-space-collapse:keep-all;\",\n\t\t\t\"whsc:l\": \"white-space-collapse:loose;\",\n\t\t\t\"whsc:bs\": \"white-space-collapse:break-strict;\",\n\t\t\t\"whsc:ba\": \"white-space-collapse:break-all;\",\n\t\t\t\"wob\": \"word-break:|;\",\n\t\t\t\"wob:n\": \"word-break:normal;\",\n\t\t\t\"wob:k\": \"word-break:keep-all;\",\n\t\t\t\"wob:l\": \"word-break:loose;\",\n\t\t\t\"wob:bs\": \"word-break:break-strict;\",\n\t\t\t\"wob:ba\": \"word-break:break-all;\",\n\t\t\t\"wos\": \"word-spacing:|;\",\n\t\t\t\"wow\": \"word-wrap:|;\",\n\t\t\t\"wow:nm\": \"word-wrap:normal;\",\n\t\t\t\"wow:n\": \"word-wrap:none;\",\n\t\t\t\"wow:u\": \"word-wrap:unrestricted;\",\n\t\t\t\"wow:s\": \"word-wrap:suppress;\",\n\t\t\t\"lts\": \"letter-spacing:|;\",\n\t\t\t\"f\": \"font:|;\",\n\t\t\t\"f+\": \"font:1em Arial,sans-serif;\",\n\t\t\t\"fw\": \"font-weight:|;\",\n\t\t\t\"fw:n\": \"font-weight:normal;\",\n\t\t\t\"fw:b\": \"font-weight:bold;\",\n\t\t\t\"fw:br\": \"font-weight:bolder;\",\n\t\t\t\"fw:lr\": \"font-weight:lighter;\",\n\t\t\t\"fs\": \"font-style:|;\",\n\t\t\t\"fs:n\": \"font-style:normal;\",\n\t\t\t\"fs:i\": \"font-style:italic;\",\n\t\t\t\"fs:o\": \"font-style:oblique;\",\n\t\t\t\"fv\": \"font-variant:|;\",\n\t\t\t\"fv:n\": \"font-variant:normal;\",\n\t\t\t\"fv:sc\": \"font-variant:small-caps;\",\n\t\t\t\"fz\": \"font-size:|;\",\n\t\t\t\"fza\": \"font-size-adjust:|;\",\n\t\t\t\"fza:n\": \"font-size-adjust:none;\",\n\t\t\t\"ff\": \"font-family:|;\",\n\t\t\t\"ff:s\": \"font-family:serif;\",\n\t\t\t\"ff:ss\": \"font-family:sans-serif;\",\n\t\t\t\"ff:c\": \"font-family:cursive;\",\n\t\t\t\"ff:f\": \"font-family:fantasy;\",\n\t\t\t\"ff:m\": \"font-family:monospace;\",\n\t\t\t\"fef\": \"font-effect:|;\",\n\t\t\t\"fef:n\": \"font-effect:none;\",\n\t\t\t\"fef:eg\": \"font-effect:engrave;\",\n\t\t\t\"fef:eb\": \"font-effect:emboss;\",\n\t\t\t\"fef:o\": \"font-effect:outline;\",\n\t\t\t\"fem\": \"font-emphasize:|;\",\n\t\t\t\"femp\": \"font-emphasize-position:|;\",\n\t\t\t\"femp:b\": \"font-emphasize-position:before;\",\n\t\t\t\"femp:a\": \"font-emphasize-position:after;\",\n\t\t\t\"fems\": \"font-emphasize-style:|;\",\n\t\t\t\"fems:n\": \"font-emphasize-style:none;\",\n\t\t\t\"fems:ac\": \"font-emphasize-style:accent;\",\n\t\t\t\"fems:dt\": \"font-emphasize-style:dot;\",\n\t\t\t\"fems:c\": \"font-emphasize-style:circle;\",\n\t\t\t\"fems:ds\": \"font-emphasize-style:disc;\",\n\t\t\t\"fsm\": \"font-smooth:|;\",\n\t\t\t\"fsm:a\": \"font-smooth:auto;\",\n\t\t\t\"fsm:n\": \"font-smooth:never;\",\n\t\t\t\"fsm:aw\": \"font-smooth:always;\",\n\t\t\t\"fst\": \"font-stretch:|;\",\n\t\t\t\"fst:n\": \"font-stretch:normal;\",\n\t\t\t\"fst:uc\": \"font-stretch:ultra-condensed;\",\n\t\t\t\"fst:ec\": \"font-stretch:extra-condensed;\",\n\t\t\t\"fst:c\": \"font-stretch:condensed;\",\n\t\t\t\"fst:sc\": \"font-stretch:semi-condensed;\",\n\t\t\t\"fst:se\": \"font-stretch:semi-expanded;\",\n\t\t\t\"fst:e\": \"font-stretch:expanded;\",\n\t\t\t\"fst:ee\": \"font-stretch:extra-expanded;\",\n\t\t\t\"fst:ue\": \"font-stretch:ultra-expanded;\",\n\t\t\t\"op\": \"opacity:|;\",\n\t\t\t\"op:ie\": \"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\",\n\t\t\t\"op:ms\": \"-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=100)';\",\n\t\t\t\"rz\": \"resize:|;\",\n\t\t\t\"rz:n\": \"resize:none;\",\n\t\t\t\"rz:b\": \"resize:both;\",\n\t\t\t\"rz:h\": \"resize:horizontal;\",\n\t\t\t\"rz:v\": \"resize:vertical;\",\n\t\t\t\"cur\": \"cursor:|;\",\n\t\t\t\"cur:a\": \"cursor:auto;\",\n\t\t\t\"cur:d\": \"cursor:default;\",\n\t\t\t\"cur:c\": \"cursor:crosshair;\",\n\t\t\t\"cur:ha\": \"cursor:hand;\",\n\t\t\t\"cur:he\": \"cursor:help;\",\n\t\t\t\"cur:m\": \"cursor:move;\",\n\t\t\t\"cur:p\": \"cursor:pointer;\",\n\t\t\t\"cur:t\": \"cursor:text;\",\n\t\t\t\"pgbb\": \"page-break-before:|;\",\n\t\t\t\"pgbb:au\": \"page-break-before:auto;\",\n\t\t\t\"pgbb:al\": \"page-break-before:always;\",\n\t\t\t\"pgbb:l\": \"page-break-before:left;\",\n\t\t\t\"pgbb:r\": \"page-break-before:right;\",\n\t\t\t\"pgbi\": \"page-break-inside:|;\",\n\t\t\t\"pgbi:au\": \"page-break-inside:auto;\",\n\t\t\t\"pgbi:av\": \"page-break-inside:avoid;\",\n\t\t\t\"pgba\": \"page-break-after:|;\",\n\t\t\t\"pgba:au\": \"page-break-after:auto;\",\n\t\t\t\"pgba:al\": \"page-break-after:always;\",\n\t\t\t\"pgba:l\": \"page-break-after:left;\",\n\t\t\t\"pgba:r\": \"page-break-after:right;\",\n\t\t\t\"orp\": \"orphans:|;\",\n\t\t\t\"wid\": \"widows:|;\"\n\t\t}\n\t},\n\t\n\t'html': {\n\t\t'snippets': {\n\t\t\t'cc:ie6': '<!--[if lte IE 6]>\\n\\t${child}|\\n<![endif]-->',\n\t\t\t'cc:ie': '<!--[if IE]>\\n\\t${child}|\\n<![endif]-->',\n\t\t\t'cc:noie': '<!--[if !IE]><!-->\\n\\t${child}|\\n<!--<![endif]-->',\n\t\t\t'html:4t': '<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\\n' +\n\t\t\t\t\t'<html lang=\"${lang}\">\\n' +\n\t\t\t\t\t'<head>\\n' +\n\t\t\t\t\t'\t<title></title>\\n' +\n\t\t\t\t\t'\t<meta http-equiv=\"Content-Type\" content=\"text/html;charset=${charset}\">\\n' +\n\t\t\t\t\t'</head>\\n' +\n\t\t\t\t\t'<body>\\n\\t${child}|\\n</body>\\n' +\n\t\t\t\t\t'</html>',\n\t\t\t\n\t\t\t'html:4s': '<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\\n' +\n\t\t\t\t\t'<html lang=\"${lang}\">\\n' +\n\t\t\t\t\t'<head>\\n' +\n\t\t\t\t\t'\t<title></title>\\n' +\n\t\t\t\t\t'\t<meta http-equiv=\"Content-Type\" content=\"text/html;charset=${charset}\">\\n' +\n\t\t\t\t\t'</head>\\n' +\n\t\t\t\t\t'<body>\\n\\t${child}|\\n</body>\\n' +\n\t\t\t\t\t'</html>',\n\t\t\t\n\t\t\t'html:xt': '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\\n' +\n\t\t\t\t\t'<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"${lang}\">\\n' +\n\t\t\t\t\t'<head>\\n' +\n\t\t\t\t\t'\t<title></title>\\n' +\n\t\t\t\t\t'\t<meta http-equiv=\"Content-Type\" content=\"text/html;charset=${charset}\" />\\n' +\n\t\t\t\t\t'</head>\\n' +\n\t\t\t\t\t'<body>\\n\\t${child}|\\n</body>\\n' +\n\t\t\t\t\t'</html>',\n\t\t\t\n\t\t\t'html:xs': '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\\n' +\n\t\t\t\t\t'<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"${lang}\">\\n' +\n\t\t\t\t\t'<head>\\n' +\n\t\t\t\t\t'\t<title></title>\\n' +\n\t\t\t\t\t'\t<meta http-equiv=\"Content-Type\" content=\"text/html;charset=${charset}\" />\\n' +\n\t\t\t\t\t'</head>\\n' +\n\t\t\t\t\t'<body>\\n\\t${child}|\\n</body>\\n' +\n\t\t\t\t\t'</html>',\n\t\t\t\n\t\t\t'html:xxs': '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\\n' +\n\t\t\t\t\t'<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"${lang}\">\\n' +\n\t\t\t\t\t'<head>\\n' +\n\t\t\t\t\t'\t<title></title>\\n' +\n\t\t\t\t\t'\t<meta http-equiv=\"Content-Type\" content=\"text/html;charset=${charset}\" />\\n' +\n\t\t\t\t\t'</head>\\n' +\n\t\t\t\t\t'<body>\\n\\t${child}|\\n</body>\\n' +\n\t\t\t\t\t'</html>',\n\t\t\t\n\t\t\t'html:5': '<!DOCTYPE HTML>\\n' +\n\t\t\t\t\t'<html lang=\"${locale}\">\\n' +\n\t\t\t\t\t'<head>\\n' +\n\t\t\t\t\t'\t<title></title>\\n' +\n\t\t\t\t\t'\t<meta charset=\"${charset}\">\\n' +\n\t\t\t\t\t'</head>\\n' +\n\t\t\t\t\t'<body>\\n\\t${child}|\\n</body>\\n' +\n\t\t\t\t\t'</html>',\n            \n            'more': '\\n<!--more-->\\n'\n\t\t},\n\t\t\n\t\t'abbreviations': {\n\t\t\t'a': '<a href=\"\"></a>',\n\t\t\t'a:link': '<a href=\"http://|\"></a>',\n\t\t\t'a:mail': '<a href=\"mailto:|\"></a>',\n\t\t\t'abbr': '<abbr title=\"\"></abbr>',\n\t\t\t'acronym': '<acronym title=\"\"></acronym>',\n\t\t\t'base': '<base href=\"\" />',\n\t\t\t'bdo': '<bdo dir=\"\"></bdo>',\n\t\t\t'bdo:r': '<bdo dir=\"rtl\"></bdo>',\n\t\t\t'bdo:l': '<bdo dir=\"ltr\"></bdo>',\n\t\t\t'link:css': '<link rel=\"stylesheet\" type=\"text/css\" href=\"|style.css\" media=\"all\" />',\n\t\t\t'link:print': '<link rel=\"stylesheet\" type=\"text/css\" href=\"|print.css\" media=\"print\" />',\n\t\t\t'link:favicon': '<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"|favicon.ico\" />',\n\t\t\t'link:touch': '<link rel=\"apple-touch-icon\" href=\"|favicon.png\" />',\n\t\t\t'link:rss': '<link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS\" href=\"|rss.xml\" />',\n\t\t\t'link:atom': '<link rel=\"alternate\" type=\"application/atom+xml\" title=\"Atom\" href=\"atom.xml\" />',\n\t\t\t'meta:utf': '<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\" />',\n\t\t\t'meta:win': '<meta http-equiv=\"Content-Type\" content=\"text/html;charset=windows-1251\" />',\n\t\t\t'meta:compat': '<meta http-equiv=\"X-UA-Compatible\" content=\"IE=7\" />',\n\t\t\t'style': '<style type=\"text/css\"></style>',\n\t\t\t'script': '<script type=\"text/javascript\"></script>',\n\t\t\t'script:src': '<script type=\"text/javascript\" src=\"\"></script>',\n\t\t\t'img': '<img src=\"\" alt=\"\" />',\n\t\t\t'iframe': '<iframe src=\"\" frameborder=\"0\"></iframe>',\n\t\t\t'embed': '<embed src=\"\" type=\"\" />',\n\t\t\t'object': '<object data=\"\" type=\"\"></object>',\n\t\t\t'param': '<param name=\"\" value=\"\" />',\n\t\t\t'map': '<map name=\"\"></map>',\n\t\t\t'area': '<area shape=\"\" coords=\"\" href=\"\" alt=\"\" />',\n\t\t\t'area:d': '<area shape=\"default\" href=\"\" alt=\"\" />',\n\t\t\t'area:c': '<area shape=\"circle\" coords=\"\" href=\"\" alt=\"\" />',\n\t\t\t'area:r': '<area shape=\"rect\" coords=\"\" href=\"\" alt=\"\" />',\n\t\t\t'area:p': '<area shape=\"poly\" coords=\"\" href=\"\" alt=\"\" />',\n\t\t\t'link': '<link rel=\"stylesheet\" href=\"\" />',\n\t\t\t'form': '<form action=\"\"></form>',\n\t\t\t'form:get': '<form action=\"\" method=\"get\"></form>',\n\t\t\t'form:post': '<form action=\"\" method=\"post\"></form>',\n\t\t\t'label': '<label for=\"\"></label>',\n\t\t\t'input': '<input type=\"\" />',\n\t\t\t'input:hidden': '<input type=\"hidden\" name=\"\" />',\n\t\t\t'input:h': '<input type=\"hidden\" name=\"\" />',\n\t\t\t'input:text': '<input type=\"text\" name=\"\" id=\"\" />',\n\t\t\t'input:t': '<input type=\"text\" name=\"\" id=\"\" />',\n\t\t\t'input:search': '<input type=\"search\" name=\"\" id=\"\" />',\n\t\t\t'input:email': '<input type=\"email\" name=\"\" id=\"\" />',\n\t\t\t'input:url': '<input type=\"url\" name=\"\" id=\"\" />',\n\t\t\t'input:password': '<input type=\"password\" name=\"\" id=\"\" />',\n\t\t\t'input:p': '<input type=\"password\" name=\"\" id=\"\" />',\n\t\t\t'input:datetime': '<input type=\"datetime\" name=\"\" id=\"\" />',\n\t\t\t'input:date': '<input type=\"date\" name=\"\" id=\"\" />',\n\t\t\t'input:datetime-local': '<input type=\"datetime-local\" name=\"\" id=\"\" />',\n\t\t\t'input:month': '<input type=\"month\" name=\"\" id=\"\" />',\n\t\t\t'input:week': '<input type=\"week\" name=\"\" id=\"\" />',\n\t\t\t'input:time': '<input type=\"time\" name=\"\" id=\"\" />',\n\t\t\t'input:number': '<input type=\"number\" name=\"\" id=\"\" />',\n\t\t\t'input:color': '<input type=\"color\" name=\"\" id=\"\" />',\n\t\t\t'input:checkbox': '<input type=\"checkbox\" name=\"\" id=\"\" />',\n\t\t\t'input:c': '<input type=\"checkbox\" name=\"\" id=\"\" />',\n\t\t\t'input:radio': '<input type=\"radio\" name=\"\" id=\"\" />',\n\t\t\t'input:r': '<input type=\"radio\" name=\"\" id=\"\" />',\n\t\t\t'input:range': '<input type=\"range\" name=\"\" id=\"\" />',\n\t\t\t'input:file': '<input type=\"file\" name=\"\" id=\"\" />',\n\t\t\t'input:f': '<input type=\"file\" name=\"\" id=\"\" />',\n\t\t\t'input:submit': '<input type=\"submit\" value=\"\" />',\n\t\t\t'input:s': '<input type=\"submit\" value=\"\" />',\n\t\t\t'input:image': '<input type=\"image\" src=\"\" alt=\"\" />',\n\t\t\t'input:i': '<input type=\"image\" src=\"\" alt=\"\" />',\n\t\t\t'input:reset': '<input type=\"reset\" value=\"\" />',\n\t\t\t'input:button': '<input type=\"button\" value=\"\" />',\n\t\t\t'input:b': '<input type=\"button\" value=\"\" />',\n\t\t\t'select': '<select name=\"\" id=\"\"></select>',\n\t\t\t'option': '<option value=\"\"></option>',\n\t\t\t'textarea': '<textarea name=\"\" id=\"\" cols=\"30\" rows=\"10\"></textarea>',\n\t\t\t'menu:context': '<menu type=\"context\"></menu>',\n\t\t\t'menu:c': '<menu type=\"context\"></menu>',\n\t\t\t'menu:toolbar': '<menu type=\"toolbar\"></menu>',\n\t\t\t'menu:t': '<menu type=\"toolbar\"></menu>',\n\t\t\t'video': '<video src=\"\"></video>',\n\t\t\t'audio': '<audio src=\"\"></audio>',\n\t\t\t'html:xml': '<html xmlns=\"http://www.w3.org/1999/xhtml\"></html>',\n\t\t\t'bq': '<blockquote></blockquote>',\n\t\t\t'acr': '<acronym></acronym>',\n\t\t\t'fig': '<figure></figure>',\n\t\t\t'ifr': '<iframe></iframe>',\n\t\t\t'emb': '<embed></embed>',\n\t\t\t'obj': '<object></object>',\n\t\t\t'src': '<source></source>',\n\t\t\t'cap': '<caption></caption>',\n\t\t\t'colg': '<colgroup></colgroup>',\n\t\t\t'fst': '<fieldset></fieldset>',\n\t\t\t'btn': '<button></button>',\n\t\t\t'optg': '<optgroup></optgroup>',\n\t\t\t'opt': '<option></option>',\n\t\t\t'tarea': '<textarea></textarea>',\n\t\t\t'leg': '<legend></legend>',\n\t\t\t'sect': '<section></section>',\n\t\t\t'art': '<article></article>',\n\t\t\t'hdr': '<header></header>',\n\t\t\t'ftr': '<footer></footer>',\n\t\t\t'adr': '<address></address>',\n\t\t\t'dlg': '<dialog></dialog>',\n\t\t\t'str': '<strong></strong>',\n\t\t\t'prog': '<progress></progress>',\n\t\t\t'fset': '<fieldset></fieldset>',\n\t\t\t'datag': '<datagrid></datagrid>',\n\t\t\t'datal': '<datalist></datalist>',\n\t\t\t'kg': '<keygen></keygen>',\n\t\t\t'out': '<output></output>',\n\t\t\t'det': '<details></details>',\n\t\t\t'cmd': '<command></command>',\n\t\t\t\n\t\t\t// expandos\n\t\t\t'ol+': 'ol>li',\n\t\t\t'ul+': 'ul>li',\n\t\t\t'dl+': 'dl>dt+dd',\n\t\t\t'map+': 'map>area',\n\t\t\t'table+': 'table>tr>td',\n\t\t\t'colgroup+': 'colgroup>col',\n\t\t\t'colg+': 'colgroup>col',\n\t\t\t'tr+': 'tr>td',\n\t\t\t'select+': 'select>option',\n\t\t\t'optgroup+': 'optgroup>option',\n\t\t\t'optg+': 'optgroup>option'\n\n\t\t},\n\t\t\n\t\t'element_types': {\n\t\t\t'empty': 'area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,keygen,command',\n\t\t\t'block_level': 'address,applet,blockquote,button,center,dd,del,dir,div,dl,dt,fieldset,form,frameset,hr,iframe,ins,isindex,li,link,map,menu,noframes,noscript,object,ol,p,pre,script,table,tbody,td,tfoot,th,thead,tr,ul,h1,h2,h3,h4,h5,h6',\n\t\t\t'inline_level': 'a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'\n\t\t}\n\t},\n\t\n\t'xsl': {\n\t\t'extends': 'html', \n\t\t'abbreviations': {\n\t\t\t'tm': '<xsl:template match=\"\" mode=\"\"></xsl:template>',\n\t\t\t'tmatch': 'tm',\n\t\t\t'tn': '<xsl:template name=\"\"></xsl:template>',\n\t\t\t'tname': 'tn',\n\t\t\t'xsl:when': '<xsl:when test=\"\"></xsl:when>',\n\t\t\t'wh': 'xsl:when',\n\t\t\t'var': '<xsl:variable name=\"\">|</xsl:variable>',\n\t\t\t'vare': '<xsl:variable name=\"\" select=\"\"/>',\n\t\t\t'if': '<xsl:if test=\"\"></xsl:if>',\n\t\t\t'call': '<xsl:call-template name=\"\"/>',\n\t\t\t'attr': '<xsl:attribute name=\"\"></xsl:attribute>',\n\t\t\t'wp': '<xsl:with-param name=\"\" select=\"\"/>',\n\t\t\t'par': '<xsl:param name=\"\" select=\"\"/>',\n\t\t\t'val': '<xsl:value-of select=\"\"/>',\n\t\t\t'co': '<xsl:copy-of select=\"\"/>',\n\t\t\t'each': '<xsl:for-each select=\"\"></xsl:for-each>',\n\t\t\t'ap': '<xsl:apply-templates select=\"\" mode=\"\"/>',\n\t\t\t\n\t\t\t//expandos\n\t\t\t'choose+': 'xsl:choose>xsl:when+xsl:otherwise'\n\t\t}\n\t}\n};/**\n * @author Sergey Chikuyonok (serge.che@gmail.com)\n * @link http://chikuyonok.ru\n */\r(function(){\n\t// Regular Expressions for parsing tags and attributes\n\tvar start_tag = /^<([\\w\\:\\-]+)((?:\\s+[\\w\\-:]+(?:\\s*=\\s*(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?)*)\\s*(\\/?)>/,\n\t\tend_tag = /^<\\/([\\w\\:\\-]+)[^>]*>/,\n\t\tattr = /([\\w\\-:]+)(?:\\s*=\\s*(?:(?:\"((?:\\\\.|[^\"])*)\")|(?:'((?:\\\\.|[^'])*)')|([^>\\s]+)))?/g;\n\t\t\n\t// Empty Elements - HTML 4.01\n\tvar empty = makeMap(\"area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed\");\n\n\t// Block Elements - HTML 4.01\n\tvar block = makeMap(\"address,applet,blockquote,button,center,dd,dir,div,dl,dt,fieldset,form,frameset,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,p,pre,script,table,tbody,td,tfoot,th,thead,tr,ul\");\n\n\t// Inline Elements - HTML 4.01\n\tvar inline = makeMap(\"a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var\");\n\n\t// Elements that you can, intentionally, leave open\n\t// (and which close themselves)\n\tvar close_self = makeMap(\"colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr\");\n\t\n\t/** Last matched HTML pair */\n\tvar last_match = {\n\t\topening_tag: null, // tag() or comment() object\n\t\tclosing_tag: null, // tag() or comment() object\n\t\tstart_ix: -1,\n\t\tend_ix: -1\n\t};\n\t\n\tfunction tag(match, ix) {\n\t\tvar name = match[1].toLowerCase();\n\t\treturn  {\n\t\t\tname: name,\n\t\t\tfull_tag: match[0],\n\t\t\tstart: ix,\n\t\t\tend: ix + match[0].length,\n\t\t\tunary: Boolean(match[3]) || (name in empty),\n\t\t\ttype: 'tag',\n\t\t\tclose_self: (name in close_self)\n\t\t};\n\t}\n\t\n\tfunction comment(start, end) {\n\t\treturn {\n\t\t\tstart: start,\n\t\t\tend: end,\n\t\t\ttype: 'comment'\n\t\t};\n\t}\n\t\n\tfunction makeMap(str){\n\t\tvar obj = {}, items = str.split(\",\");\n\t\tfor ( var i = 0; i < items.length; i++ )\n\t\t\tobj[ items[i] ] = true;\n\t\treturn obj;\n\t}\n\t\n\t/**\n\t * Makes selection ranges for matched tag pair\n\t * @param {tag} opening_tag\n\t * @param {tag} closing_tag\n\t * @param {Number} ix\n\t */\n\tfunction makeRange(opening_tag, closing_tag, ix) {\n\t\tix = ix || 0;\n\t\t\n\t\tvar start_ix = -1, \n\t\t\tend_ix = -1;\n\t\t\n\t\tif (opening_tag && !closing_tag) { // unary element\n\t\t\tstart_ix = opening_tag.start;\n\t\t\tend_ix = opening_tag.end;\n\t\t} else if (opening_tag && closing_tag) { // complete element\n\t\t\tif (\n\t\t\t\t(opening_tag.start < ix && opening_tag.end > ix) || \n\t\t\t\t(closing_tag.start <= ix && closing_tag.end > ix)\n\t\t\t) {\n\t\t\t\tstart_ix = opening_tag.start;\n\t\t\t\tend_ix = closing_tag.end;\n\t\t\t} else {\n\t\t\t\tstart_ix = opening_tag.end;\n\t\t\t\tend_ix = closing_tag.start;\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn [start_ix, end_ix];\n\t}\n\t\n\t/**\n\t * Save matched tag for later use and return found indexes\n\t * @param {tag} opening_tag\n\t * @param {tag} closing_tag\n\t * @param {Number} ix\n\t * @return {Array}\n\t */\n\tfunction saveMatch(opening_tag, closing_tag, ix) {\n\t\tix = ix || 0;\n\t\tlast_match.opening_tag = opening_tag; \n\t\tlast_match.closing_tag = closing_tag;\n\t\t\n\t\tvar range = makeRange(opening_tag, closing_tag, ix);\n\t\tlast_match.start_ix = range[0];\n\t\tlast_match.end_ix = range[1];\n\t\t\n\t\treturn last_match.start_ix != -1 ? [last_match.start_ix, last_match.end_ix] : null;\n\t}\n\t\n\t/**\n\t * Search for matching tags in <code>html</code>, starting from \n\t * <code>start_ix</code> position\n\t * @param {String} html Code to search\n\t * @param {Number} start_ix Character index where to start searching pair \n\t * (commonly, current caret position)\n\t * @param {Function} action Function that creates selection range\n\t * @return {Array|null}\n\t */\n\tfunction findPair(html, start_ix, action) {\n\t\taction = action || makeRange;\n\t\t\n\t\tvar forward_stack = [],\n\t\t\tbackward_stack = [],\n\t\t\t/** @type {tag()} */\n\t\t\topening_tag = null,\n\t\t\t/** @type {tag()} */\n\t\t\tclosing_tag = null,\n\t\t\trange = null,\n\t\t\thtml_len = html.length,\n\t\t\tm,\n\t\t\tix,\n\t\t\ttmp_tag;\n\t\t\t\n\t\tforward_stack.last = backward_stack.last = function() {\n\t\t\treturn this[this.length - 1];\n\t\t}\n\t\t\n\t\tfunction hasMatch(str, start) {\n\t\t\tif (arguments.length == 1)\n\t\t\t\tstart = ix;\n\t\t\treturn html.substr(start, str.length) == str;\n\t\t}\n\t\t\n\t\tfunction searchCommentStart(from) {\n\t\t\twhile (from--) {\n\t\t\t\tif (html.charAt(from) == '<' && hasMatch('<!--', from))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t\n\t\t\treturn from;\n\t\t}\n\t\t\n\t\t// find opening tag\n\t\tix = start_ix;\n\t\twhile (ix-- && ix >= 0) {\n\t\t\tvar ch = html.charAt(ix);\n\t\t\tif (ch == '<') {\n\t\t\t\tvar check_str = html.substring(ix, html_len);\n\t\t\t\t\n\t\t\t\tif ( (m = check_str.match(end_tag)) ) { // found closing tag\n\t\t\t\t\ttmp_tag = tag(m, ix);\n\t\t\t\t\tif (tmp_tag.start < start_ix && tmp_tag.end > start_ix) // direct hit on searched closing tag\n\t\t\t\t\t\tclosing_tag = tmp_tag;\n\t\t\t\t\telse\n\t\t\t\t\t\tbackward_stack.push(tmp_tag);\n\t\t\t\t} else if ( (m = check_str.match(start_tag)) ) { // found opening tag\n\t\t\t\t\ttmp_tag = tag(m, ix);\n\t\t\t\t\t\n\t\t\t\t\tif (tmp_tag.unary) {\n\t\t\t\t\t\tif (tmp_tag.start < start_ix && tmp_tag.end > start_ix) // exact match\n\t\t\t\t\t\t\treturn saveMatch(tmp_tag, null, start_ix);\n\t\t\t\t\t} else if (backward_stack.last() && backward_stack.last().name == tmp_tag.name) {\n\t\t\t\t\t\tbackward_stack.pop();\n\t\t\t\t\t} else { // found nearest unclosed tag\n\t\t\t\t\t\topening_tag = tmp_tag;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else if (check_str.indexOf('<!--') == 0) { // found comment start\n\t\t\t\t\tvar end_ix = check_str.search('-->') + ix + 3;\n\t\t\t\t\tif (ix < start_ix && end_ix >= start_ix)\n\t\t\t\t\t\treturn saveMatch( comment(ix, end_ix) );\n\t\t\t\t}\n\t\t\t} else if (ch == '-' && hasMatch('-->')) { // found comment end\n\t\t\t\t// search left until comment start is reached\n\t\t\t\tix = searchCommentStart(ix);\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (!opening_tag)\n\t\t\treturn action(null);\n\t\t\n\t\t// find closing tag\n\t\tif (!closing_tag) {\n\t\t\tfor (ix = start_ix; ix < html_len; ix++) {\n\t\t\t\tvar ch = html.charAt(ix);\n\t\t\t\tif (ch == '<') {\n\t\t\t\t\tvar check_str = html.substring(ix, html_len);\n\t\t\t\t\t\n\t\t\t\t\tif ( (m = check_str.match(start_tag)) ) { // found opening tag\n\t\t\t\t\t\ttmp_tag = tag(m, ix);\n\t\t\t\t\t\tif (!tmp_tag.unary)\n\t\t\t\t\t\t\tforward_stack.push( tmp_tag );\n\t\t\t\t\t} else if ( (m = check_str.match(end_tag)) ) { // found closing tag\n\t\t\t\t\t\tvar tmp_tag = tag(m, ix);\n\t\t\t\t\t\tif (forward_stack.last() && forward_stack.last().name == tmp_tag.name)\n\t\t\t\t\t\t\tforward_stack.pop();\n\t\t\t\t\t\telse { // found matched closing tag\n\t\t\t\t\t\t\tclosing_tag = tmp_tag;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (hasMatch('<!--')) { // found comment\n\t\t\t\t\t\tix += check_str.search('-->') + 3;\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == '-' && hasMatch('-->')) {\n\t\t\t\t\t// looks like cursor was inside comment with invalid HTML\n\t\t\t\t\tif (!forward_stack.last() || forward_stack.last().type != 'comment') {\n\t\t\t\t\t\tvar end_ix = ix + 3;\n\t\t\t\t\t\treturn action(comment( searchCommentStart(ix), end_ix ));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn action(opening_tag, closing_tag, start_ix);\n\t}\n\t\n\t/**\n\t * Search for matching tags in <code>html</code>, starting \n\t * from <code>start_ix</code> position. The result is automatically saved in \n\t * <code>last_match</code> property\n\t * \n\t * @return {Array|null}\n\t */\n\tvar HTMLPairMatcher = this.HTMLPairMatcher = function(/* String */ html, /* Number */ start_ix){\n\t\treturn findPair(html, start_ix, saveMatch);\n\t}\n\t\n\tHTMLPairMatcher.start_tag = start_tag;\n\tHTMLPairMatcher.end_tag = end_tag;\n\t\n\t/**\n\t * Search for matching tags in <code>html</code>, starting from \n\t * <code>start_ix</code> position. The difference between \n\t * <code>HTMLPairMatcher</code> function itself is that <code>find</code> \n\t * method doesn't save matched result in <code>last_match</code> property.\n\t * This method is generally used for lookups \n\t */\n\tHTMLPairMatcher.find = function(html, start_ix) {\n\t\treturn findPair(html, start_ix);\n\t};\n\t\n\t/**\n\t * Search for matching tags in <code>html</code>, starting from \n\t * <code>start_ix</code> position. The difference between \n\t * <code>HTMLPairMatcher</code> function itself is that <code>getTags</code> \n\t * method doesn't save matched result in <code>last_match</code> property \n\t * and returns array of opening and closing tags\n\t * This method is generally used for lookups \n\t */\n\tHTMLPairMatcher.getTags = function(html, start_ix) {\n\t\treturn findPair(html, start_ix, function(opening_tag, closing_tag){\n\t\t\treturn [opening_tag, closing_tag];\n\t\t});\n\t};\n\t\n\tHTMLPairMatcher.last_match = last_match;\n})();/**\n * @author Sergey Chikuyonok (serge.che@gmail.com)\n * @link http://chikuyonok.ru\n * @include \"settings.js\"\n * @include \"/EclipseMonkey/scripts/monkey-doc.js\"\n */\rvar zen_coding = (function(){\n\t\n\tvar re_tag = /<\\/?[\\w:\\-]+(?:\\s+[\\w\\-:]+(?:\\s*=\\s*(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?)*\\s*(\\/?)>$/;\n\t\n\tvar TYPE_ABBREVIATION = 'zen-tag',\n\t\tTYPE_EXPANDO = 'zen-expando',\n\t\n\t\t/** Reference to another abbreviation or tag */\n\t\tTYPE_REFERENCE = 'zen-reference',\n\t\t\n\t\tcontent_placeholder = '{%::zen-content::%}',\n\t\tnewline = '\\n';\n\t\t\n\tvar default_profile = {\n\t\ttag_case: 'lower',\n\t\tattr_case: 'lower',\n\t\tattr_quotes: 'double',\n\t\t\n\t\t// each tag on new line\n\t\ttag_nl: 'decide',\n\t\t\n\t\tplace_cursor: true,\n\t\t\n\t\t// indent tags\n\t\tindent: true,\n\t\t\n\t\t// use self-closing style for writing empty elements, e.g. <br /> or <br>\n\t\tself_closing_tag: 'xhtml'\n\t};\n\t\n\tvar profiles = {};\n\t\n\t/**\n\t * Проверяет, является ли символ допустимым в аббревиатуре\n\t * @param {String} ch\n\t * @return {Boolean}\n\t */\n\tfunction isAllowedChar(ch) {\n\t\tvar char_code = ch.charCodeAt(0),\n\t\t\tspecial_chars = '#.>+*:$-_!@';\n\t\t\n\t\treturn (char_code > 64 && char_code < 91)       // uppercase letter\n\t\t\t\t|| (char_code > 96 && char_code < 123)  // lowercase letter\n\t\t\t\t|| (char_code > 47 && char_code < 58)   // number\n\t\t\t\t|| special_chars.indexOf(ch) != -1;     // special character\n\t}\n\t\n\t/**\n\t * Возвращает символ перевода строки, используемый в редакторе\n\t * @return {String}\n\t */\n\tfunction getNewline() {\n\t\treturn zen_coding.getNewline();\n\t}\n\t\n\t/**\n\t * Split text into lines. Set <code>remove_empty</code> to true to filter\n\t * empty lines\n\t * @param {String} text\n\t * @param {Boolean} [remove_empty]\n\t * @return {Array}\n\t */\n\tfunction splitByLines(text, remove_empty) {\n\t\t\n\t\t// IE fails to split string by regexp, \n\t\t// need to normalize newlines first\n\t\tvar lines = text.replace(/\\r\\n/g, '\\n').replace(/\\n\\r/g, '\\n').split('\\n');\n\t\t\n//\t\tvar nl = getNewline(), \n//\t\t\tlines = text.split(new RegExp('\\\\r?\\\\n|\\\\n\\\\r|\\\\r|' + nl));\n\t\t\t\n\t\tif (remove_empty) {\n\t\t\tfor (var i = lines.length; i >= 0; i--) {\n\t\t\t\tif (!trim(lines[i]))\n\t\t\t\t\tlines.splice(i, 1);\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn lines;\n\t}\n\t\n\t/**\n\t * Trim whitespace from string\n\t * @param {String} text\n\t * @return {String}\n\t */\n\tfunction trim(text) {\n\t\treturn (text || \"\").replace( /^\\s+|\\s+$/g, \"\" );\n\t}\n\t\n\tfunction createProfile(options) {\n\t\tvar result = {};\n\t\tfor (var p in default_profile)\n\t\t\tresult[p] = (p in options) ? options[p] : default_profile[p];\n\t\t\n\t\treturn result;\n\t}\n\t\n\tfunction setupProfile(name, options) {\n\t\tprofiles[name.toLowerCase()] = createProfile(options || {});\n\t}\n\t\n\t/**\n\t * Helper function that transforms string into hash\n\t * @return {Object}\n\t */\n\tfunction stringToHash(str){\n\t\tvar obj = {}, items = str.split(\",\");\n\t\tfor ( var i = 0; i < items.length; i++ )\n\t\t\tobj[ items[i] ] = true;\n\t\treturn obj;\n\t}\n\t\n\t/**\n\t * Отбивает текст отступами\n\t * @param {String} text Текст, который нужно отбить\n\t * @param {String|Number} pad Количество отступов или сам отступ\n\t * @return {String}\n\t */\n\tfunction padString(text, pad, verbose) {\n\t\tvar pad_str = '', result = '';\n\t\tif (typeof(pad) == 'number')\n\t\t\tfor (var i = 0; i < pad; i++) \n\t\t\t\tpad_str += zen_settings.variables.indentation;\n\t\telse\n\t\t\tpad_str = pad;\n\t\t\n\t\tvar lines = splitByLines(text),\n\t\t\tnl = getNewline();\n\t\t\t\n\t\tresult += lines[0];\n\t\tfor (var j = 1; j < lines.length; j++) \n\t\t\tresult += nl + pad_str + lines[j];\n\t\t\t\n\t\treturn result;\n\t}\n\t\n\t/**\n\t * Check if passed abbreviation is snippet\n\t * @param {String} abbr\n\t * @param {String} type\n\t * @return {Boolean}\n\t */\n\tfunction isShippet(abbr, type) {\n\t\treturn getSnippet(type, abbr) ? true : false;\n\t}\n\t\n\t/**\n\t * Проверяет, закачивается ли строка полноценным тэгом. В основном \n\t * используется для проверки принадлежности символа '>' аббревиатуре \n\t * или тэгу\n\t * @param {String} str\n\t * @return {Boolean}\n\t */\n\tfunction isEndsWithTag(str) {\n\t\treturn re_tag.test(str);\n\t}\n\t\n\t/**\n\t * Returns specified elements collection (like 'empty', 'block_level') from\n\t * <code>resource</code>. If collections wasn't found, returns empty object\n\t * @param {Object} resource\n\t * @param {String} type\n\t * @return {Object}\n\t */\n\tfunction getElementsCollection(resource, type) {\n\t\tif (resource && resource.element_types)\n\t\t\treturn resource.element_types[type] || {}\n\t\telse\n\t\t\treturn {};\n\t}\n\t\n\t/**\n\t * Replace variables like ${var} in string\n\t * @param {String} str\n\t * @param {Object} [vars] Variable set (default is <code>zen_settings.variables</code>) \n\t * @return {String}\n\t */\n\tfunction replaceVariables(str, vars) {\n\t\tvars = vars || zen_settings.variables;\n\t\treturn str.replace(/\\$\\{([\\w\\-]+)\\}/g, function(str, p1){\n\t\t\treturn (p1 in vars) ? vars[p1] : str;\n\t\t});\n\t}\n\t\n\t/**\n\t * Тэг\n\t * @class\n\t * @param {String} name Имя тэга\n\t * @param {Number} count Сколько раз вывести тэг (по умолчанию: 1)\n\t * @param {String} type Тип тэга (html, xml)\n\t */\n\tfunction Tag(name, count, type) {\n\t\tname = name.toLowerCase();\n\t\ttype = type || 'html';\n\t\t\n\t\tvar abbr = getAbbreviation(type, name);\n\t\tif (abbr && abbr.type == TYPE_REFERENCE)\n\t\t\tabbr = getAbbreviation(type, abbr.value);\n\t\t\n\t\tthis.name = (abbr) ? abbr.value.name : name.replace('+', '');\n\t\tthis.count = count || 1;\n\t\tthis.children = [];\n\t\tthis.attributes = [];\n\t\tthis._attr_hash = {};\n\t\tthis._abbr = abbr;\n\t\tthis._res = zen_settings[type];\n\t\tthis._content = '';\n\t\tthis.repeat_by_lines = false;\n\t\t\n\t\t// add default attributes\n\t\tif (this._abbr && this._abbr.value.attributes) {\n\t\t\tvar def_attrs = this._abbr.value.attributes;\r\t\t\tif (def_attrs) {\n\t\t\t\tfor (var i = 0; i < def_attrs.length; i++) {\n\t\t\t\t\tvar attr = def_attrs[i];\n\t\t\t\t\tthis.addAttribute(attr.name, attr.value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tTag.prototype = {\n\t\t/**\n\t\t * Добавляет нового потомка\n\t\t * @param {Tag} tag\n\t\t */\n\t\taddChild: function(tag) {\n\t\t\tthis.children.push(tag);\n\t\t},\n\t\t\n\t\t/**\n\t\t * Добавляет атрибут\n\t\t * @param {String} name Название атрибута\n\t\t * @param {String} value Значение атрибута\n\t\t */\n\t\taddAttribute: function(name, value) {\n\t\t\tvar a;\n\t\t\tif (name in this._attr_hash) {\n\t\t\t\t// attribute already exists, decide what to do\n\t\t\t\ta = this._attr_hash[name];\n\t\t\t\tif (name == 'class') {\n\t\t\t\t\t// 'class' is a magic attribute\n\t\t\t\t\ta.value += ((a.value) ? ' ' : '') + value;\n\t\t\t\t} else {\n\t\t\t\t\ta.value = value;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ta = {name: name, value: value};\n\t\t\t\tthis._attr_hash[name] = a\n\t\t\t\tthis.attributes.push(a);\n\t\t\t}\n\t\t\t\n\t\t},\n\t\t\n\t\t/**\n\t\t * Проверяет, является ли текущий элемент пустым\n\t\t * @return {Boolean}\n\t\t */\n\t\tisEmpty: function() {\n\t\t\treturn (this._abbr && this._abbr.value.is_empty) || (this.name in getElementsCollection(this._res, 'empty'));\n\t\t},\n\t\t\n\t\t/**\n\t\t * Проверяет, является ли текущий элемент строчным\n\t\t * @return {Boolean}\n\t\t */\n\t\tisInline: function() {\n\t\t\treturn (this.name in getElementsCollection(this._res, 'inline_level'));\n\t\t},\n\t\t\n\t\t/**\n\t\t * Проверяет, является ли текущий элемент блочным\n\t\t * @return {Boolean}\n\t\t */\n\t\tisBlock: function() {\n\t\t\treturn (this.name in getElementsCollection(this._res, 'block_level'));\n\t\t},\n\t\t\n\t\t/**\n\t\t * This function tests if current tags' content contains xHTML tags. \n\t\t * This function is mostly used for output formatting\n\t\t */\n\t\thasTagsInContent: function() {\n\t\t\treturn this.getContent() && re_tag.test(this.getContent());\n\t\t},\n\t\t\n\t\t/**\n\t\t * Проверяет, есть ли блочные потомки у текущего тэга. \n\t\t * Используется для форматирования\n\t\t * @return {Boolean}\n\t\t */\n\t\thasBlockChildren: function() {\n\t\t\tif (this.hasTagsInContent() && this.isBlock()) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t\n\t\t\tfor (var i = 0; i < this.children.length; i++) {\n\t\t\t\tif (this.children[i].isBlock())\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\t\n\t\t\treturn false;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Set textual content for tag\n\t\t * @param {String} str Tag's content\n\t\t */\n\t\tsetContent: function(str) {\n\t\t\tthis._content = str;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Returns tag's textual content\n\t\t * @return {String}\n\t\t */\n\t\tgetContent: function() {\n\t\t\treturn this._content;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Search for deepest and latest child of current element\n\t\t * @return {Tag|null} Returns null if there's no children\n\t\t */\n\t\tfindDeepestChild: function() {\n\t\t\tif (!this.children.length)\n\t\t\t\treturn null;\n\t\t\t\t\n\t\t\tvar deepest_child = this;\n\t\t\twhile (true) {\n\t\t\t\tdeepest_child = deepest_child.children[ deepest_child.children.length - 1 ];\n\t\t\t\tif (!deepest_child.children.length)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t\n\t\t\treturn deepest_child;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Transforms and formats tag into string using profile\n\t\t * @param {String} profile Profile name\n\t\t * @return {String}\n\t\t * TODO Function is too large, need refactoring\n\t\t */\n\t\ttoString: function(profile_name) {\n\t\t\t\n\t\t\tvar result = [], \n\t\t\t\tprofile = (profile_name in profiles) ? profiles[profile_name] : profiles['plain'],\n\t\t\t\tattrs = '', \n\t\t\t\tcontent = '', \n\t\t\t\tstart_tag = '', \n\t\t\t\tend_tag = '',\n\t\t\t\tcursor = profile.place_cursor ? '|' : '',\n\t\t\t\tself_closing = '',\n\t\t\t\tattr_quote = profile.attr_quotes == 'single' ? \"'\" : '\"',\n\t\t\t\tattr_name,\n\t\t\t\t\n\t\t\t\tis_empty = (this.isEmpty() && !this.children.length);\n\n\t\t\tif (profile.self_closing_tag == 'xhtml')\n\t\t\t\tself_closing = ' /';\n\t\t\telse if (profile.self_closing_tag === true)\n\t\t\t\tself_closing = '/';\n\t\t\t\t\n\t\t\tfunction allowNewline(tag) {\n\t\t\t\treturn (profile.tag_nl === true || (profile.tag_nl == 'decide' && tag.isBlock()))\n\t\t\t}\n\t\t\t\t\n\t\t\t// make attribute string\n\t\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\t\tvar a = this.attributes[i];\n\t\t\t\tattr_name = (profile.attr_case == 'upper') ? a.name.toUpperCase() : a.name.toLowerCase();\n\t\t\t\tattrs += ' ' + attr_name + '=' + attr_quote + (a.value || cursor) + attr_quote;\n\t\t\t}\n\t\t\t\n\t\t\tvar deepest_child = this.findDeepestChild();\n\t\t\t\n\t\t\t// output children\n\t\t\tif (!is_empty) {\n\t\t\t\tif (deepest_child && this.repeat_by_lines)\n\t\t\t\t\tdeepest_child.setContent(content_placeholder);\n\t\t\t\t\n\t\t\t\tfor (var j = 0; j < this.children.length; j++) {\n//\t\t\t\t\t\n\t\t\t\t\tcontent += this.children[j].toString(profile_name);\n\t\t\t\t\tif (\n\t\t\t\t\t\t(j != this.children.length - 1) &&\n\t\t\t\t\t\t( allowNewline(this.children[j]) || allowNewline(this.children[j + 1]) )\n\t\t\t\t\t)\n\t\t\t\t\t\tcontent += getNewline();\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// define opening and closing tags\n\t\t\tif (this.name) {\n\t\t\t\tvar tag_name = (profile.tag_case == 'upper') ? this.name.toUpperCase() : this.name.toLowerCase();\n\t\t\t\tif (is_empty) {\n\t\t\t\t\tstart_tag = '<' + tag_name + attrs + self_closing + '>';\n\t\t\t\t} else {\n\t\t\t\t\tstart_tag = '<' + tag_name + attrs + '>';\n\t\t\t\t\tend_tag = '</' + tag_name + '>';\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// formatting output\n\t\t\tif (profile.tag_nl !== false) {\n\t\t\t\tif (\n\t\t\t\t\tthis.name && \n\t\t\t\t\t(\n\t\t\t\t\t\tprofile.tag_nl === true || \n\t\t\t\t\t\tthis.hasBlockChildren() \n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tif (end_tag) { // non-empty tag: add indentation\n\t\t\t\t\t\tstart_tag += getNewline() + zen_settings.variables.indentation;\n\t\t\t\t\t\tend_tag = getNewline() + end_tag;\n\t\t\t\t\t} else { // empty tag\n\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (this.name) {\n\t\t\t\t\tif (content)\n\t\t\t\t\t\tcontent = padString(content, profile.indent ? 1 : 0);\n\t\t\t\t\telse if (!is_empty)\n\t\t\t\t\t\tstart_tag += cursor;\n\t\t\t\t}\n\t\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\t// repeat tag by lines count\n\t\t\tvar cur_content = '';\n\t\t\tif (this.repeat_by_lines) {\n\t\t\t\tvar lines = splitByLines( trim(this.getContent()) , true);\n\t\t\t\tfor (var j = 0; j < lines.length; j++) {\n\t\t\t\t\tcur_content = deepest_child ? '' : content_placeholder;\n\t\t\t\t\tif (content && !deepest_child)\n\t\t\t\t\t\tcur_content += getNewline();\n\t\t\t\t\t\t\n\t\t\t\t\tvar elem_str = start_tag.replace(/\\$/g, j + 1) + cur_content + content + end_tag;\n\t\t\t\t\tresult.push(elem_str.replace(content_placeholder, trim(lines[j])));\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// repeat tag output\n\t\t\tif (!result.length) {\n\t\t\t\tif (this.getContent()) {\n\t\t\t\t\tvar pad = (profile.tag_nl === true || (this.hasTagsInContent() && this.isBlock())) ? 1 : 0;\n\t\t\t\t\tcontent = padString(this.getContent(), pad) + content;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tfor (var i = 0; i < this.count; i++) \n\t\t\t\t\tresult.push(start_tag.replace(/\\$/g, i + 1) + content + end_tag);\n\t\t\t}\n\t\t\t\n\t\t\tvar glue = '';\n\t\t\tif (allowNewline(this))\n\t\t\t\tglue = getNewline();\n\t\t\t\t\n\t\t\treturn result.join(glue);\n\t\t}\n\t};\n\t\n\t// TODO inherit from Tag\n\tfunction Snippet(name, count, type) {\n\t\t/** @type {String} */\n\t\tthis.name = name;\n\t\tthis.count = count || 1;\n\t\tthis.children = [];\n\t\tthis._content = '';\n\t\tthis.repeat_by_lines = false;\n\t\tthis.attributes = {'id': '|', 'class': '|'};\n\t\tthis.value = getSnippet(type, name);\n\t}\n\t\n\tSnippet.prototype = {\n\t\t/**\n\t\t * Добавляет нового потомка\n\t\t * @param {Tag} tag\n\t\t */\n\t\taddChild: function(tag) {\n\t\t\tthis.children.push(tag);\n\t\t},\n\t\t\n\t\taddAttribute: function(name, value){\n\t\t\tthis.attributes[name] = value;\n\t\t},\n\t\t\n\t\tisBlock: function() {\n\t\t\treturn true; \n\t\t},\n\t\t\n\t\t/**\n\t\t * Set textual content for snippet\n\t\t * @param {String} str Tag's content\n\t\t */\n\t\tsetContent: function(str) {\n\t\t\tthis._content = str;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Returns snippet's textual content\n\t\t * @return {String}\n\t\t */\n\t\tgetContent: function() {\n\t\t\treturn this._content;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Search for deepest and latest child of current element\n\t\t * @return {Tag|null} Returns null if there's no children\n\t\t */\n\t\tfindDeepestChild: function() {\n\t\t\tif (!this.children.length)\n\t\t\t\treturn null;\n\t\t\t\t\n\t\t\tvar deepest_child = this;\n\t\t\twhile (true) {\n\t\t\t\tdeepest_child = deepest_child.children[ deepest_child.children.length - 1 ];\n\t\t\t\tif (!deepest_child.children.length)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t\n\t\t\treturn deepest_child;\n\t\t},\n\t\t\n\t\ttoString: function(profile_name) {\n\t\t\tvar content = '', \n\t\t\t\tprofile = (profile_name in profiles) ? profiles[profile_name] : profiles['plain'],\n\t\t\t\tresult = [],\n\t\t\t\tdata = this.value,\n\t\t\t\tbegin = '',\n\t\t\t\tend = '',\n\t\t\t\tchild_padding = '',\n\t\t\t\tchild_token = '${child}';\n\t\t\t\n\t\t\tif (data) {\n\t\t\t\tif (profile.tag_nl !== false) {\n\t\t\t\t\tvar nl = getNewline();\n\t\t\t\t\tdata = data.replace(/\\n/g, nl);\n\t\t\t\t\t// figuring out indentation for children\n\t\t\t\t\tvar lines = data.split(nl), m;\n\t\t\t\t\tfor (var j = 0; j < lines.length; j++) {\n\t\t\t\t\t\tif (lines[j].indexOf(child_token) != -1) {\n\t\t\t\t\t\t\tchild_padding =  (m = lines[j].match(/(^\\s+)/)) ? m[1] : '';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar parts = data.split(child_token);\n\t\t\t\tbegin = parts[0] || '';\n\t\t\t\tend = parts[1] || '';\n\t\t\t}\n\t\t\t\n\t\t\tfor (var i = 0; i < this.children.length; i++) {\n\t\t\t\tcontent += this.children[i].toString(profile_name);\n\t\t\t\tif (\n\t\t\t\t\ti != this.children.length - 1 &&\n\t\t\t\t\t(\n\t\t\t\t\t\tprofile.tag_nl === true || \n\t\t\t\t\t\t(profile.tag_nl == 'decide' && this.children[i].isBlock())\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t\tcontent += getNewline();\n\t\t\t}\n\t\t\t\n\t\t\tif (child_padding)\n\t\t\t\tcontent = padString(content, child_padding);\n\t\t\t\n\t\t\t\n\t\t\t// substitute attributes\n\t\t\tbegin = replaceVariables(begin, this.attributes);\n\t\t\tend = replaceVariables(end, this.attributes);\n\t\t\t\t\n\t\t\tif (this.getContent()) {\n\t\t\t\tcontent = padString(this.getContent(), 1) + content;\n\t\t\t}\n\t\t\t\n\t\t\t// выводим тэг нужное количество раз\n\t\t\tfor (var i = 0; i < this.count; i++) \n\t\t\t\tresult.push(begin + content + end);\n//\t\t\t\tresult.push(begin.replace(/\\$(?!\\{)/g, i + 1) + content + end);\n\t\t\t\n\t\t\treturn result.join((profile.tag_nl !== false) ? getNewline() : '');\n\t\t}\n\t}\n\t\n\t/**\n\t * Returns abbreviation value from data set\n\t * @param {String} type Resource type (html, css, ...)\n\t * @param {String} abbr Abbreviation name\n\t * @return {Object|null}\n\t */\n\tfunction getAbbreviation(type, abbr) {\n\t\treturn getSettingsResource(type, abbr, 'abbreviations');\n\t}\n\t\n\t/**\n\t * Returns snippet value from data set\n\t * @param {String} type Resource type (html, css, ...)\n\t * @param {String} snippet_name Snippet name\n\t * @return {Object|null}\n\t */\n\tfunction getSnippet(type, snippet_name) {\n\t\treturn getSettingsResource(type, snippet_name, 'snippets');\n\t}\n\t\n\t/**\n\t * Returns resurce value from data set with respect of inheritance\n\t * @param {String} type Resource type (html, css, ...)\n\t * @param {String} abbr Abbreviation name\n\t * @param {String} res_name Resource name ('snippets' or 'abbreviation')\n\t * @return {Object|null}\n\t */\n\tfunction getSettingsResource(type, abbr, res_name) {\n\t\tvar resource = zen_settings[type];\n\t\t\n\t\tif (resource) {\n\t\t\tif (res_name in resource && abbr in resource[res_name])\n\t\t\t\treturn resource[res_name][abbr];\n\t\t\telse if ('extends' in resource) {\n\t\t\t\t// find abbreviation in ancestors\n\t\t\t\tfor (var i = 0; i < resource['extends'].length; i++) {\n\t\t\t\t\tvar type = resource['extends'][i];\n\t\t\t\t\tif (\n\t\t\t\t\t\tzen_settings[type] && \n\t\t\t\t\t\tzen_settings[type][res_name] && \n\t\t\t\t\t\tzen_settings[type][res_name][abbr]\n\t\t\t\t\t)\n\t\t\t\t\t\treturn zen_settings[type][res_name][abbr];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\treturn null;\n\t}\n\t\n\t// create default profiles\n\tsetupProfile('xhtml');\n\tsetupProfile('html', {self_closing_tag: false});\n\tsetupProfile('xml', {self_closing_tag: true, tag_nl: true});\n\tsetupProfile('plain', {tag_nl: false, indent: false, place_cursor: false});\n\t\n\t\n\treturn {\n\t\texpandAbbreviation: function(abbr, type, profile) {\n\t\t\tvar tree = this.parseIntoTree(abbr, type || 'html');\n\t\t\treturn replaceVariables(tree ? tree.toString(profile) : '');\n\t\t},\n\t\t\n\t\t/**\n\t\t * Extracts abbreviations from text stream, starting from the end\n\t\t * @param {String} str\n\t\t * @return {String} Abbreviation or empty string\n\t\t */\n\t\textractAbbreviation: function(str) {\n\t\t\tvar cur_offset = str.length,\n\t\t\t\tstart_index = -1;\n\t\t\t\n\t\t\twhile (true) {\n\t\t\t\tcur_offset--;\n\t\t\t\tif (cur_offset < 0) {\n\t\t\t\t\t// дошли до начала строки\n\t\t\t\t\tstart_index = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar ch = str.charAt(cur_offset);\n\t\t\t\t\n\t\t\t\tif (!isAllowedChar(ch) || (ch == '>' && isEndsWithTag(str.substring(0, cur_offset + 1)))) {\n\t\t\t\t\tstart_index = cur_offset + 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tif (start_index != -1) \n\t\t\t\t// что-то нашли, возвращаем аббревиатуру\n\t\t\t\treturn str.substring(start_index);\n\t\t\telse\n\t\t\t\treturn '';\n\t\t},\n\t\t\n\t\t/**\n\t\t * Parses abbreviation into a node set\n\t\t * @param {String} abbr Abbreviation\n\t\t * @param {String} type Document type (xsl, html, etc.)\n\t\t * @return {Tag}\n\t\t */\n\t\tparseIntoTree: function(abbr, type) {\n\t\t\ttype = type || 'html';\n\t\t\tvar root = new Tag('', 1, type),\n\t\t\t\tparent = root,\n\t\t\t\tlast = null,\n\t\t\t\tmultiply_elem = null,\n\t\t\t\tres = zen_settings[type],\n\t\t\t\tre = /([\\+>])?([a-z@\\!][a-z0-9:\\-]*)(#[\\w\\-\\$]+)?((?:\\.[\\w\\-\\$]+)*)(\\*(\\d*))?(\\+$)?/ig;\n\t\t\t\n\t\t\tif (!abbr)\n\t\t\t\treturn null;\n\t\t\t\n\t\t\t// replace expandos\n\t\t\tabbr = abbr.replace(/([a-z][\\w\\:\\-]*)\\+$/i, function(str){\n\t\t\t\tvar a = getAbbreviation(type, str);\n\t\t\t\treturn a ? a.value : str;\n\t\t\t});\n\t\t\t\n\t\t\tabbr = abbr.replace(re, function(str, operator, tag_name, id, class_name, has_multiplier, multiplier, has_expando){\n\t\t\t\tvar multiply_by_lines = (has_multiplier && !multiplier);\n\t\t\t\tmultiplier = multiplier ? parseInt(multiplier) : 1;\n\t\t\t\t\n\t\t\t\tif (has_expando)\n\t\t\t\t\ttag_name += '+';\n\t\t\t\t\n\t\t\t\tvar current = isShippet(tag_name, type) ? new Snippet(tag_name, multiplier, type) : new Tag(tag_name, multiplier, type);\n\t\t\t\tif (id)\n\t\t\t\t\tcurrent.addAttribute('id', id.substr(1));\n\t\t\t\t\n\t\t\t\tif (class_name) \n\t\t\t\t\tcurrent.addAttribute('class', class_name.substr(1).replace(/\\./g, ' '));\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t// dive into tree\n\t\t\t\tif (operator == '>' && last)\n\t\t\t\t\tparent = last;\n\t\t\t\t\t\n\t\t\t\tparent.addChild(current);\n\t\t\t\t\n\t\t\t\tlast = current;\n\t\t\t\t\n\t\t\t\tif (multiply_by_lines)\n\t\t\t\t\tmultiply_elem = current;\n\t\t\t\t\n\t\t\t\treturn '';\n\t\t\t});\n\t\t\t\n\t\t\troot.last = last;\n\t\t\troot.multiply_elem = multiply_elem;\n\t\t\t\n\t\t\t// empty 'abbr' string means that abbreviation was successfully expanded,\n\t\t\t// if not — abbreviation wasn't valid \n\t\t\treturn (!abbr) ? root : null;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Отбивает текст отступами\n\t\t * @param {String} text Текст, который нужно отбить\n\t\t * @param {String|Number} pad Количество отступов или сам отступ\n\t\t * @return {String}\n\t\t */\n\t\tpadString: padString,\n\t\tsetupProfile: setupProfile,\n\t\tgetNewline: function(){\n\t\t\treturn newline;\n\t\t},\n\t\t\n\t\tsetNewline: function(str) {\n\t\t\tnewline = str;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Returns range for matched tag pair inside document\n\t\t * @requires HTMLParser\n\t\t * @param {String} html Full xHTML document\n\t\t * @param {Number} cursor_pos Cursor position inside document\n\t\t * @return {Object} Pair of indicies (<code>start</code> and <code>end</code>). \n\t\t * Returns 'null' if match wasn't found \n\t\t */\n\t\tgetPairRange: function(html, cursor_pos) {\n\t\t\tvar tags = {},\n\t\t\t\tranges = [],\n\t\t\t\tresult = null;\n\t\t\t\t\n\t\t\tfunction inRange(start, end) {\n\t\t\t\treturn cursor_pos > start && cursor_pos < end;\n\t\t\t} \n\t\t\t\n\t\t\tvar handler = {\n\t\t\t\tstart: function(name, attrs, unary, ix_start, ix_end) {\n\t\t\t\t\tif (unary && inRange(ix_start, ix_end)) {\n\t\t\t\t\t\t// this is the exact range for cursor position, stop searching\n\t\t\t\t\t\tresult = {start: ix_start, end: ix_end};\n\t\t\t\t\t\tthis.stop = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!tags.hasOwnProperty(name))\n\t\t\t\t\t\t\ttags[name] = [];\n\t\t\t\t\t\t\t\n\t\t\t\t\t\ttags[name].push(ix_start);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\tend: function(name, ix_start, ix_end) {\n\t\t\t\t\tif (tags.hasOwnProperty(name)) {\n\t\t\t\t\t\tvar start = tags[name].pop();\n\t\t\t\t\t\tif (inRange(start, ix_end))\n\t\t\t\t\t\t\tranges.push({start: start, end: ix_end});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\tcomment: function(data, ix_start, ix_end) {\n\t\t\t\t\tif (inRange(ix_start, ix_end)) {\n\t\t\t\t\t\t// this is the exact range for cursor position, stop searching\n\t\t\t\t\t\tresult = {start: ix_start, end: ix_end};\n\t\t\t\t\t\tthis.stop = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\t\n\t\t\t// scan document\n\t\t\ttry {\n\t\t\t\tHTMLParser(html, handler);\n\t\t\t} catch(e) {}\n\t\t\t\n\t\t\tif (!result && ranges.length) {\n\t\t\t\t// because we have overlaped ranges only, we have to sort array by \n\t\t\t\t// length: the shorter range length, the most probable match\n\t\t\t\tresult = ranges.sort(function(a, b){\n\t\t\t\t\treturn (a.end - a.start) - (b.end - b.start);\n\t\t\t\t})[0];\n\t\t\t}\n\t\t\t\n\t\t\treturn result;\n\t\t},\n\t\t\n\t\t/**\n\t\t * Wraps passed text with abbreviation. Text will be placed inside last\n\t\t * expanded element\n\t\t * @param {String} abbr Abbreviation\n\t\t * @param {String} text Text to wrap\n\t\t * @param {String} [type] Document type (html, xml, etc.). Default is 'html'\n\t\t * @param {String} [profile] Output profile's name. Default is 'plain'\n\t\t * @return {String}\n\t\t */\n\t\twrapWithAbbreviation: function(abbr, text, type, profile) {\n\t\t\tvar tree = this.parseIntoTree(abbr, type || 'html');\n\t\t\tif (tree) {\n\t\t\t\tvar repeat_elem = tree.multiply_elem || tree.last;\n\t\t\t\trepeat_elem.setContent(text);\n\t\t\t\trepeat_elem.repeat_by_lines = !!tree.multiply_elem;\n\t\t\t\treturn tree.toString(profile);\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\t\n\t\tsplitByLines: splitByLines,\n\t\t\n\t\t/**\n\t\t * Check if cursor is placed inside xHTML tag\n\t\t * @param {String} html Contents of the document\n\t\t * @param {Number} cursor_pos Current caret position inside tag\n\t\t * @return {Boolean}\n\t\t */\n\t\tisInsideTag: function(html, cursor_pos) {\n\t\t\tvar re_tag = /^<\\/?\\w[\\w\\:\\-]*.*?>/;\n\t\t\t\n\t\t\t// search left to find opening brace\n\t\t\tvar pos = cursor_pos;\n\t\t\twhile (pos > -1) {\n\t\t\t\tif (html.charAt(pos) == '<') \n\t\t\t\t\tbreak;\n\t\t\t\tpos--;\n\t\t\t}\n\t\t\t\n\t\t\tif (pos != -1) {\n\t\t\t\tvar m = re_tag.exec(html.substring(pos));\n\t\t\t\tif (m && cursor_pos > pos && cursor_pos < pos + m[0].length)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\t\n\t\t\treturn false;\n\t\t},\n\t\t\n\t\tsettings_parser: (function(){\n\t\t\t/**\n\t\t\t * Unified object for parsed data\n\t\t\t */\n\t\t\tfunction entry(type, key, value) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: type,\n\t\t\t\t\tkey: key,\n\t\t\t\t\tvalue: value\n\t\t\t\t};\n\t\t\t}\n\t\t\t\n\t\t\t/** Regular expression for XML tag matching */\n\t\t\tvar re_tag = /^<(\\w+\\:?[\\w\\-]*)((?:\\s+[\\w\\:\\-]+\\s*=\\s*(['\"]).*?\\3)*)\\s*(\\/?)>/,\n\t\t\t\tre_attrs = /([\\w\\-]+)\\s*=\\s*(['\"])(.*?)\\2/g;\n\t\t\t\n\t\t\t/**\n\t\t\t * Make expando from string\n\t\t\t * @param {String} key\n\t\t\t * @param {String} value\n\t\t\t * @return {Object}\n\t\t\t */\n\t\t\tfunction makeExpando(key, value) {\n\t\t\t\treturn entry(TYPE_EXPANDO, key, value);\n\t\t\t}\n\t\t\t\n\t\t\t/**\n\t\t\t * Make abbreviation from string\n\t\t\t * @param {String} key Abbreviation key\n\t\t\t * @param {String} tag_name Expanded element's tag name\n\t\t\t * @param {String} attrs Expanded element's attributes\n\t\t\t * @param {Boolean} is_empty Is expanded element empty or not\n\t\t\t * @return {Object}\n\t\t\t */\n\t\t\tfunction makeAbbreviation(key, tag_name, attrs, is_empty) {\n\t\t\t\tvar result = {\n\t\t\t\t\tname: tag_name,\n\t\t\t\t\tis_empty: Boolean(is_empty)\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tif (attrs) {\n\t\t\t\t\tvar m;\n\t\t\t\t\tresult.attributes = [];\n\t\t\t\t\twhile (m = re_attrs.exec(attrs)) {\n\t\t\t\t\t\tresult.attributes.push({\n\t\t\t\t\t\t\tname: m[1],\n\t\t\t\t\t\t\tvalue: m[3]\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn entry(TYPE_ABBREVIATION, key, result);\n\t\t\t}\n\t\t\t\n\t\t\t/**\n\t\t\t * Parses all abbreviations inside object\n\t\t\t * @param {Object} obj\n\t\t\t */\n\t\t\tfunction parseAbbreviations(obj) {\n\t\t\t\tfor (var key in obj) {\n\t\t\t\t\tvar value = obj[key], m;\n\t\t\t\t\t\n\t\t\t\t\tkey = trim(key);\n\t\t\t\t\tif (key.substr(-1) == '+') {\n\t\t\t\t\t\t// this is expando, leave 'value' as is\n\t\t\t\t\t\tobj[key] = makeExpando(key, value);\n\t\t\t\t\t} else if (m = re_tag.exec(value)) {\n\t\t\t\t\t\tobj[key] = makeAbbreviation(key, m[1], m[2], m[4] == '/');\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// assume it's reference to another abbreviation\n\t\t\t\t\t\tobj[key] = entry(TYPE_REFERENCE, key, value);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\treturn {\n\t\t\t\t/**\n\t\t\t\t * Parse user's settings\n\t\t\t\t * @param {Object} settings\n\t\t\t\t */\n\t\t\t\tparse: function(settings) {\n\t\t\t\t\tfor (var p in settings) {\n\t\t\t\t\t\tif (p == 'abbreviations')\n\t\t\t\t\t\t\tparseAbbreviations(settings[p]);\n\t\t\t\t\t\telse if (p == 'extends') {\n\t\t\t\t\t\t\tvar ar = settings[p].split(',');\n\t\t\t\t\t\t\tfor (var i = 0; i < ar.length; i++) \n\t\t\t\t\t\t\t\tar[i] = trim(ar[i]);\n\t\t\t\t\t\t\tsettings[p] = ar;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (typeof(settings[p]) == 'object')\n\t\t\t\t\t\t\targuments.callee(settings[p]);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\textend: function(parent, child) {\n\t\t\t\t\tfor (var p in child) {\n\t\t\t\t\t\tif (typeof(child[p]) == 'object' && parent.hasOwnProperty(p))\n\t\t\t\t\t\t\targuments.callee(parent[p], child[p]);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tparent[p] = child[p];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\t/**\n\t\t\t\t * Create hash maps on certain string properties\n\t\t\t\t * @param {Object} obj\n\t\t\t\t */\n\t\t\t\tcreateMaps: function(obj) {\n\t\t\t\t\tfor (var p in obj) {\n\t\t\t\t\t\tif (p == 'element_types') {\n\t\t\t\t\t\t\tfor (var k in obj[p]) \n\t\t\t\t\t\t\t\tobj[p][k] = stringToHash(obj[p][k]);\n\t\t\t\t\t\t} else if (typeof(obj[p]) == 'object') {\n\t\t\t\t\t\t\targuments.callee(obj[p]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\tTYPE_ABBREVIATION: TYPE_ABBREVIATION,\n\t\t\t\tTYPE_EXPANDO: TYPE_EXPANDO,\n\t\t\t\t\n\t\t\t\t/** Reference to another abbreviation or tag */\n\t\t\t\tTYPE_REFERENCE: TYPE_REFERENCE\n\t\t\t}\n\t\t})()\n\t}\n\t\n})();\n\nif ('zen_settings' in this || zen_settings) {\n\t// first we need to expand some strings into hashes\n\tzen_coding.settings_parser.createMaps(zen_settings);\n\tif ('my_zen_settings' in this) {\n\t\t// we need to extend default settings with user's\n\t\tzen_coding.settings_parser.createMaps(my_zen_settings);\n\t\tzen_coding.settings_parser.extend(zen_settings, my_zen_settings);\n\t}\n\t\n\t// now we need to parse final set of settings\n\tzen_coding.settings_parser.parse(zen_settings);\n}/**\n * High-level editor interface which communicates with other editor (like \n * TinyMCE, CKEditor, etc.) or browser.\n * Before using any of editor's methods you should initialize it with\n * <code>editor.setTarget(elem)</code> method and pass reference to \n * &lt;textarea&gt; element.\n * @example\n * var textarea = document.getElemenetsByTagName('textarea')[0];\n * editor.setTarget(textarea);\n * //now you are ready to use editor object\n * editor.getSelectionRange() \n * \n * @author Sergey Chikuyonok (serge.che@gmail.com)\n * @link http://chikuyonok.ru\n * @include \"../../aptana/lib/zen_coding.js\"\n */\nvar zen_editor = (function(){\n\t/** @param {Element} Source element */\n\tvar target = null,\n\t\t/** Textual placeholder that identifies cursor position in pasted text */\n\t\tcaret_placeholder = '|';\n\t\n\t\t\n\t// different browser uses different newlines, so we have to figure out\n\t// native browser newline and sanitize incoming text with them\n\tvar tx = document.createElement('textarea');\n\ttx.value = '\\n';\n\tzen_coding.setNewline(tx.value);\n\ttx = null;\n\t\n\t/**\n\t * Returns content of current target element\n\t */\n\tfunction getContent() {\n\t\treturn target.value || '';\n\t}\n\t\n\t/**\n\t * Returns selection indexes from element\n\t */\n\tfunction getSelectionRange() {\n\t\tif ('selectionStart' in target) { // W3C's DOM\n\t\t\tvar length = target.selectionEnd - target.selectionStart;\n\t\t\treturn {\n\t\t\t\tstart: target.selectionStart, \n\t\t\t\tend: target.selectionEnd \n\t\t\t};\n\t\t} else if (document.selection) { // IE\n\t\t\ttarget.focus();\n\t \n\t\t\tvar range = document.selection.createRange();\n\t\t\t\n\t\t\tif (range === null) {\n\t\t\t\treturn {\n\t\t\t\t\tstart: 0, \n\t\t\t\t\tend: getContent().length\n\t\t\t\t};\n\t\t\t}\n\t \n\t\t\tvar re = target.createTextRange();\n\t\t\tvar rc = re.duplicate();\n\t\t\tre.moveToBookmark(range.getBookmark());\n\t\t\trc.setEndPoint('EndToStart', re);\n\t \n\t\t\treturn {\n\t\t\t\tstart: rc.text.length, \n\t\t\t\tend: rc.text.length + range.text.length\n\t\t\t};\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\t\n\t/**\n\t * Creates text selection on target element\n\t * @param {Number} start\n\t * @param {Number} end\n\t */\n\tfunction createSelection(start, end) {\n\t\t// W3C's DOM\n\t\tif (typeof(end) == 'undefined')\n\t\t\tend = start;\n\t\t\t\n\t\tif ('setSelectionRange' in target) {\n\t\t\ttarget.setSelectionRange(start, end);\n\t\t} else if ('createTextRange' in target) {\n\t\t\tvar t = target.createTextRange();\n\t\t\t\n\t\t\tt.collapse(true);\n\t\t\tvar delta = zen_coding.splitByLines(getContent().substring(0, start)).length - 1;\n\t\t\t\n\t\t\t// IE has an issue with handling newlines while creating selection,\n\t\t\t// so we need to adjust start and end indexes\n\t\t\tend -= delta + zen_coding.splitByLines(getContent().substring(start, end)).length - 1;\n\t\t\tstart -= delta;\n\t\t\t\n\t\t\tt.moveStart('character', start);\n\t\t\tt.moveEnd('character', end - start);\n\t\t\tt.select();\n\t\t}\n\t}\n\t\n\t/**\n\t * Find start and end index of text line for <code>from</code> index\n\t * @param {String} text \n\t * @param {Number} from \n\t */\n\tfunction findNewlineBounds(text, from) {\n\t\tvar len = text.length,\n\t\t\tstart = 0,\n\t\t\tend = len - 1;\n\t\t\n\t\t// search left\n\t\tfor (var i = from - 1; i > 0; i--) {\n\t\t\tvar ch = text.charAt(i);\n\t\t\tif (ch == '\\n' || ch == '\\r') {\n\t\t\t\tstart = i + 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// search right\n\t\tfor (var j = from; j < len; j++) {\n\t\t\tvar ch = text.charAt(j);\n\t\t\tif (ch == '\\n' || ch == '\\r') {\n\t\t\t\tend = j;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn {start: start, end: end};\n\t}\n\t\n\t/**\n\t * Returns current caret position\n\t */\n\tfunction getCaretPos() {\n\t\tvar selection = getSelectionRange();\n\t\treturn selection ? selection.start : null;\n\t}\n\t\n\t/**\n\t * Returns whitrespace padding of string\n\t * @param {String} str String line\n\t * @return {String}\n\t */\n\tfunction getStringPadding(str) {\n\t\treturn (str.match(/^(\\s+)/) || [''])[0];\n\t}\n\t\n\treturn {\n\t\tsetTarget: function(elem) {\n\t\t\ttarget = elem;\n\t\t},\n\t\t\n\t\tgetSelectionRange: getSelectionRange,\n\t\tcreateSelection: createSelection,\n\t\t\n\t\t/**\n\t\t * Returns current line's start and end indexes\n\t\t */\n\t\tgetCurrentLineRange: function() {\n\t\t\tvar caret_pos = getCaretPos(),\n\t\t\t\tcontent = getContent();\n\t\t\tif (caret_pos === null) return null;\n\t\t\t\n\t\t\treturn findNewlineBounds(content, caret_pos);\n\t\t},\n\t\t\n\t\t/**\n\t\t * Returns current caret position\n\t\t * @return {Number}\n\t\t */\n\t\tgetCaretPos: getCaretPos,\n\t\t\n\t\t/**\n\t\t * Returns content of current line\n\t\t * @return {String}\n\t\t */\n\t\tgetCurrentLine: function() {\n\t\t\tvar range = this.getCurrentLineRange();\n\t\t\treturn range.start < range.end ? this.getContent().substring(range.start, range.end) : '';\n\t\t},\n\t\t\n\t\t/**\n\t\t * Replace editor's content or it's part (from <code>start</code> to \n\t\t * <code>end</code> index). If <code>value</code> contains \n\t\t * <code>caret_placeholder</code>, the editor will put caret into \n\t\t * this position. If you skip <code>start</code> and <code>end</code>\n\t\t * arguments, the whole target's content will be replaced with \n\t\t * <code>value</code>. \n\t\t * \n\t\t * If you pass <code>start</code> argument only,\n\t\t * the <code>value</code> will be placed at <code>start</code> string \n\t\t * index of current content. \n\t\t * \n\t\t * If you pass <code>start</code> and <code>end</code> arguments,\n\t\t * the corresponding substring of current target's content will be \n\t\t * replaced with <code>value</code>. \n\t\t * @param {String} value Content you want to paste\n\t\t * @param {Number} [start] Start index of editor's content\n\t\t * @param {Number} [end] End index of editor's content\n\t\t */\n\t\treplaceContent: function(value, start, end) {\n\t\t\tvar content = getContent(),\n\t\t\t\tcaret_pos = getCaretPos(),\n\t\t\t\thas_start = typeof(start) !== 'undefined',\n\t\t\t\thas_end = typeof(end) !== 'undefined';\n\t\t\t\t\n\t\t\t// indent new value\n\t\t\tvalue = zen_coding.padString(value, getStringPadding(this.getCurrentLine()));\n\t\t\t\n\t\t\t// find new caret position\n\t\t\tvar new_pos = value.indexOf(caret_placeholder);\n\t\t\tif (new_pos != -1) {\n\t\t\t\tcaret_pos = (start || 0) + new_pos;\n\t\t\t\tvalue = value.split(caret_placeholder).join('');\n\t\t\t} else {\n\t\t\t\tcaret_pos += value.length;\n\t\t\t}\n\t\t\t\n\t\t\ttry {\n\t\t\t\tif (has_start && has_end) {\n\t\t\t\t\tcontent = content.substring(0, start) + value + content.substring(end);\n\t\t\t\t} else if (has_start) {\n\t\t\t\t\tcontent = content.substring(0, start) + value + content.substring(start);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\ttarget.value = content;\n\t\t\t\tcreateSelection(caret_pos, caret_pos);\n\t\t\t} catch(e){}\n\t\t},\n\t\t\n\t\t/**\n\t\t * Returns editor's content\n\t\t * @return {String}\n\t\t */\n\t\tgetContent: getContent\n\t}\n})();\n /**\n * Middleware layer that communicates between editor and Zen Coding.\n * This layer describes all available Zen Coding actions, like \n * \"Expand Abbreviation\".\n * @author Sergey Chikuyonok (serge.che@gmail.com)\n * @link http://chikuyonok.ru\n * \n * @include \"editor.js\"\n * @include \"../../aptana/lib/html_matcher.js\"\n * @include \"../../aptana/lib/zen_coding.js\"\n */\n\n/**\n * Search for abbreviation in editor from current caret position\n * @param {zen_editor} editor Editor instance\n * @return {String|null}\n */\nfunction findAbbreviation(editor) {\n\tvar range = editor.getSelectionRange();\n\tif (range.start != range.end) {\n\t\t// abbreviation is selected by user\n\t\treturn editor.getContent().substring(range.start, range.end);\n\t}\n\t\n\t// search for new abbreviation from current caret position\n\tvar cur_line = editor.getCurrentLineRange();\n\treturn zen_coding.extractAbbreviation(editor.getContent().substring(cur_line.start, range.start));\n}\n\n/**\n * Find from current caret position and expand abbreviation in editor\n * @param {zen_editor} editor Editor instance\n * @param {String} type Syntax type (html, css, etc.)\n * @param {String} profile_name Output profile name (html, xml, xhtml)\n * @return {Boolean} Returns <code>true</code> if abbreviation was expanded \n * successfully\n */\nfunction expandAbbreviation(editor, type, profile_name) {\n\tprofile_name = profile_name || 'xhtml';\n\t\n\tvar caret_pos = editor.getSelectionRange().end,\n\t\tabbr,\n\t\tcontent = '';\n\t\t\n\tif ( (abbr = findAbbreviation(editor)) ) {\n\t\tcontent = zen_coding.expandAbbreviation(abbr, type, profile_name);\n\t\tif (content) {\n\t\t\teditor.replaceContent(content, caret_pos - abbr.length, caret_pos);\n\t\t\treturn true;\n\t\t}\n\t}\n\t\n\treturn false;\n}\n\n/**\n * A special version of <code>expandAbbreviation</code> function: if it can't\n * find abbreviation, it will place Tab character at caret position\n * @param {zen_editor} editor Editor instance\n * @param {String} type Syntax type (html, css, etc.)\n * @param {String} profile_name Output profile name (html, xml, xhtml)\n */\nfunction expandAbbreviationWithTab(editor, type, profile_name) {\n\tif (!expandAbbreviation(editor, type, profile_name))\n\t\teditor.replaceContent('\\t', editor.getCaretPos());\n}\n\n/**\n * Find and select HTML tag pair\n * @param {zen_editor} editor Editor instance\n * @param {String} [direction] Direction of pair matching: 'in' or 'out'. \n * Default is 'out'\n */\nfunction matchPair(editor, direction) {\n\tdirection = (direction || 'out').toLowerCase();\n\t\n\tvar range = editor.getSelectionRange(),\n\t\tcursor = range.end,\n\t\trange_start = range.start, \n\t\trange_end = range.end,\n//\t\tcontent = zen_coding.splitByLines(editor.getContent()).join('\\n'),\n\t\tcontent = editor.getContent(),\n\t\trange = null,\n\t\t_r,\n\t\n\t\told_open_tag = HTMLPairMatcher.last_match['opening_tag'],\n\t\told_close_tag = HTMLPairMatcher.last_match['closing_tag'];\n\t\t\n\tif (direction == 'in' && old_open_tag && range_start != range_end) {\n//\t\tuser has previously selected tag and wants to move inward\n\t\tif (!old_close_tag) {\n//\t\t\tunary tag was selected, can't move inward\n\t\t\treturn false;\n\t\t} else if (old_open_tag.start == range_start) {\n\t\t\tif (content[old_open_tag.end] == '<') {\n//\t\t\t\ttest if the first inward tag matches the entire parent tag's content\n\t\t\t\t_r = HTMLPairMatcher.find(content, old_open_tag.end + 1);\n\t\t\t\tif (_r[0] == old_open_tag.end && _r[1] == old_close_tag.start) {\n\t\t\t\t\trange = HTMLPairMatcher(content, old_open_tag.end + 1);\n\t\t\t\t} else {\n\t\t\t\t\trange = [old_open_tag.end, old_close_tag.start];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trange = [old_open_tag.end, old_close_tag.start];\n\t\t\t}\n\t\t} else {\n\t\t\tvar new_cursor = content.substring(0, old_close_tag.start).indexOf('<', old_open_tag.end);\n\t\t\tvar search_pos = new_cursor != -1 ? new_cursor + 1 : old_open_tag.end;\n\t\t\trange = HTMLPairMatcher(content, search_pos);\n\t\t}\n\t} else {\n\t\trange = HTMLPairMatcher(content, cursor);\n\t}\n\t\n\tif (range !== null && range[0] != -1) {\n//\t\talert(range[0] + ', '+ range[1]);\n\t\teditor.createSelection(range[0], range[1]);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n/**\n * Wraps content with abbreviation\n * @param {zen_editor} Editor instance\n * @param {String} type Syntax type (html, css, etc.)\n * @param {String} profile_name Output profile name (html, xml, xhtml)\n */\nfunction wrapWithAbbreviation(editor, abbr, type, profile_name) {\n\tprofile_name = profile_name || 'xhtml';\n\t\n\tvar range = editor.getSelectionRange(),\n\t\tstart_offset = range.start,\n\t\tend_offset = range.end,\n\t\tcontent = editor.getContent();\n\t\t\n\t\t\n\tif (!abbr)\n\t\treturn null; \n\t\n\tif (start_offset == end_offset) {\n\t\t// no selection, find tag pair\n\t\trange = HTMLPairMatcher(content, start_offset);\n\t\t\n\t\tif (!range || range[0] == -1) // nothing to wrap\n\t\t\treturn null;\n\t\t\t\n\t\tstart_offset = range[0];\n\t\tend_offset = range[1];\n\t\t\t\n\t\t// narrow down selection until first non-space character\n\t\tvar re_space = /\\s|\\n|\\r/;\n\t\tfunction isSpace(ch) {\n\t\t\treturn re_space.test(ch);\n\t\t}\n\t\t\n\t\twhile (start_offset < end_offset) {\n\t\t\tif (!isSpace(content.charAt(start_offset)))\n\t\t\t\tbreak;\n\t\t\t\t\n\t\t\tstart_offset++;\n\t\t}\n\t\t\n\t\twhile (end_offset > start_offset) {\n\t\t\tend_offset--;\n\t\t\tif (!isSpace(content.charAt(end_offset))) {\n\t\t\t\tend_offset++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t\t\n\t}\n\t\n\tvar new_content = content.substring(start_offset, end_offset),\n\t\tresult = zen_coding.wrapWithAbbreviation(abbr, unindent(editor, new_content), type, profile_name);\n\t\n\tif (result) {\n\t\teditor.createSelection(end_offset);\n\t\teditor.replaceContent(result, start_offset, end_offset);\n\t}\n}\n\n/**\n * Unindent content, thus preparing text for tag wrapping\n * @param {zen_editor} Editor instance\n * @param {String} text\n * @return {String}\n */\nfunction unindent(editor, text) {\n\tvar pad = getCurrentLinePadding(editor);\n\tvar lines = zen_coding.splitByLines(text);\n\tfor (var i = 0; i < lines.length; i++) {\n\t\tif (lines[i].search(pad) == 0)\n\t\t\tlines[i] = lines[i].substr(pad.length);\n\t}\n\t\n\treturn lines.join(zen_coding.getNewline());\n}\n\n/**\n * Returns padding of current editor's line\n * @param {zen_editor} Editor instance\n * @return {String}\n */\nfunction getCurrentLinePadding(editor) {\n\treturn (editor.getCurrentLine().match(/^(\\s+)/) || [''])[0];\n}\n\n/**\n * Search for new caret insertion point\n * @param {zen_editor} editor Editor instance\n * @param {Number} Search increment: -1 — search left, 1 — search right\n * @param {Number} Initial offset relative to current caret position\n * @return {Number} Returns -1 if insertion point wasn't found\n */\nfunction findNewEditPoint(editor, inc, offset) {\n\tinc = inc || 1;\n\toffset = offset || 0;\n\tvar cur_point = editor.getCaretPos() + offset,\n\t\tcontent = editor.getContent(),\n\t\tmax_len = content.length,\n\t\tnext_point = -1,\n\t\tre_empty_line = /^\\s+$/;\n\t\n\tfunction ch(ix) {\n\t\treturn content.charAt(ix);\n\t}\n\t\n\tfunction getLine(ix) {\n\t\tvar start = ix;\n\t\twhile (start >= 0) {\n\t\t\tvar c = ch(start);\n\t\t\tif (c == '\\n' || c == '\\r')\n\t\t\t\tbreak;\n\t\t\tstart--;\n\t\t}\n\t\t\n\t\treturn content.substring(start, ix);\n\t}\n\t\t\n\twhile (cur_point < max_len && cur_point > 0) {\n\t\tcur_point += inc;\n\t\tvar cur_char = ch(cur_point),\n\t\t\tnext_char = ch(cur_point + 1),\n\t\t\tprev_char = ch(cur_point - 1);\n\t\t\t\n\t\tswitch (cur_char) {\n\t\t\tcase '\"':\n\t\t\tcase '\\'':\n\t\t\t\tif (next_char == cur_char && prev_char == '=') {\n\t\t\t\t\t// empty attribute\n\t\t\t\t\tnext_point = cur_point + 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '>':\n\t\t\t\tif (next_char == '<') {\n\t\t\t\t\t// between tags\n\t\t\t\t\tnext_point = cur_point + 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase '\\n':\n\t\t\tcase '\\r':\n\t\t\t\t// empty line\n\t\t\t\tif (re_empty_line.test(getLine(cur_point - 1))) {\n\t\t\t\t\tnext_point = cur_point;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\t\n\t\tif (next_point != -1)\n\t\t\tbreak;\n\t}\n\t\n\treturn next_point;\n}\n\n/**\n * Move caret to previous edit point\n * @param {zen_editor} editor Editor instance\n */\nfunction prevEditPoint(editor) {\n\tvar cur_pos = editor.getCaretPos(),\n\t\tnew_point = findNewEditPoint(editor, -1);\n\t\t\n\tif (new_point == cur_pos)\n\t\t// we're still in the same point, try searching from the other place\n\t\tnew_point = findNewEditPoint(editor, -1, -2);\n\t\n\tif (new_point != -1) \n\t\teditor.createSelection(new_point);\n}\n\n/**\n * Move caret to next edit point\n * @param {zen_editor} editor Editor instance\n */\nfunction nextEditPoint(editor) {\n\tvar new_point = findNewEditPoint(editor, 1);\n\tif (new_point != -1)\n\t\teditor.createSelection(new_point);\n}\n\n/**\n * Inserts newline character with proper indentation\n * @param {zen_editor} editor Editor instance\n * @param {String} mode Syntax mode (only 'html' is implemented)\n */\nfunction insertFormattedNewline(editor, mode) {\n\tmode = mode || 'html';\n\tvar pad = getCurrentLinePadding(editor),\n\t\tcaret_pos = editor.getCaretPos();\n\t\t\n\tfunction insert_nl() {\n\t\teditor.replaceContent('\\n', caret_pos);\n\t}\n\t\n\tswitch (mode) {\n\t\tcase 'html':\n\t\t\t// let's see if we're breaking newly created tag\n\t\t\tvar pair = HTMLPairMatcher.getTags(editor.getContent(), editor.getCaretPos());\n\t\t\t\n\t\t\tif (pair[0] && pair[1] && pair[0].type == 'tag' && pair[0].end == caret_pos && pair[1].start == caret_pos) {\n\t\t\t\teditor.replaceContent('\\n\\t|\\n', caret_pos);\n\t\t\t} else {\n\t\t\t\tinsert_nl();\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tinsert_nl();\n\t}\n}\n\n/**\n * Select line under cursor\n * @param {zen_editor} editor Editor instance\n */\nfunction selectLine(editor) {\n\tvar range = editor.getCurrentLineRange();\n\teditor.createSelection(range.start, range.end);\n}/**\n * http://www.openjs.com/scripts/events/keyboard_shortcuts/\n * Version : 2.01.B\n * By Binny V A\n * License : BSD\n */\nshortcut = {\n\t'all_shortcuts':{},//All the shortcuts are stored in this array\n\t'add': function(shortcut_combination,callback,opt) {\n\t\tvar is_opera = !!window.opera,\n\t\t\tis_mac = /mac\\s+os/i.test(navigator.userAgent);\n\t\t\n\t\t//Provide a set of default options\n\t\tvar default_options = {\n\t\t\t'type':is_opera ? 'keypress' : 'keydown',\n\t\t\t'propagate':false,\n\t\t\t'disable_in_input':false,\n\t\t\t'target':document,\n\t\t\t'keycode':false\n\t\t}\n\t\tif(!opt) opt = default_options;\n\t\telse {\n\t\t\tfor(var dfo in default_options) {\n\t\t\t\tif(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];\n\t\t\t}\n\t\t}\n\n\t\tvar ele = opt.target;\n\t\tif(typeof opt.target == 'string') ele = document.getElementById(opt.target);\n\t\tvar ths = this;\n\t\tshortcut_combination = shortcut_combination.toLowerCase();\n\n\t\t//The function to be called at keypress\n\t\tvar func = function(e) {\n\t\t\te = e || window.event;\n\t\t\tvar code;\n\t\t\t\n\t\t\tif(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields\n\t\t\t\tvar element;\n\t\t\t\tif(e.target) element=e.target;\n\t\t\t\telse if(e.srcElement) element=e.srcElement;\n\t\t\t\tif(element.nodeType==3) element=element.parentNode;\n\n\t\t\t\tif(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;\n\t\t\t}\n\t\n\t\t\t//Find Which key is pressed\n\t\t\tif (e.keyCode) code = e.keyCode;\n\t\t\telse if (e.which) code = e.which;\n\t\t\tvar character = String.fromCharCode(code).toLowerCase();\n\t\t\t\n\t\t\tif(code == 188) character=\",\"; //If the user presses , when the type is onkeydown\n\t\t\tif(code == 190) character=\".\"; //If the user presses , when the type is onkeydown\n\n\t\t\tvar keys = shortcut_combination.split(\"+\");\n\t\t\t//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked\n\t\t\tvar kp = 0;\n\t\t\t\n\t\t\t//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken\n\t\t\tvar shift_nums = {\n\t\t\t\t\"`\":\"~\",\n\t\t\t\t\"1\":\"!\",\n\t\t\t\t\"2\":\"@\",\n\t\t\t\t\"3\":\"#\",\n\t\t\t\t\"4\":\"$\",\n\t\t\t\t\"5\":\"%\",\n\t\t\t\t\"6\":\"^\",\n\t\t\t\t\"7\":\"&\",\n\t\t\t\t\"8\":\"*\",\n\t\t\t\t\"9\":\"(\",\n\t\t\t\t\"0\":\")\",\n\t\t\t\t\"-\":\"_\",\n\t\t\t\t\"=\":\"+\",\n\t\t\t\t\";\":\":\",\n\t\t\t\t\"'\":\"\\\"\",\n\t\t\t\t\",\":\"<\",\n\t\t\t\t\".\":\">\",\n\t\t\t\t\"/\":\"?\",\n\t\t\t\t\"\\\\\":\"|\"\n\t\t\t}\n\t\t\t//Special Keys - and their codes\n\t\t\tvar special_keys = {\n\t\t\t\t'esc':27,\n\t\t\t\t'escape':27,\n\t\t\t\t'tab':9,\n\t\t\t\t'space':32,\n\t\t\t\t'return':13,\n\t\t\t\t'enter':13,\n\t\t\t\t'backspace':8,\n\t\n\t\t\t\t'scrolllock':145,\n\t\t\t\t'scroll_lock':145,\n\t\t\t\t'scroll':145,\n\t\t\t\t'capslock':20,\n\t\t\t\t'caps_lock':20,\n\t\t\t\t'caps':20,\n\t\t\t\t'numlock':144,\n\t\t\t\t'num_lock':144,\n\t\t\t\t'num':144,\n\t\t\t\t\n\t\t\t\t'pause':19,\n\t\t\t\t'break':19,\n\t\t\t\t\n\t\t\t\t'insert':45,\n\t\t\t\t'home':36,\n\t\t\t\t'delete':46,\n\t\t\t\t'end':35,\n\t\t\t\t\n\t\t\t\t'pageup':33,\n\t\t\t\t'page_up':33,\n\t\t\t\t'pu':33,\n\t\n\t\t\t\t'pagedown':34,\n\t\t\t\t'page_down':34,\n\t\t\t\t'pd':34,\n\t\t\t\t\n\t\t\t\t'plus': 187,\n\t\t\t\t'minus': 189,\n\t\n\t\t\t\t'left':37,\n\t\t\t\t'up':38,\n\t\t\t\t'right':39,\n\t\t\t\t'down':40,\n\t\n\t\t\t\t'f1':112,\n\t\t\t\t'f2':113,\n\t\t\t\t'f3':114,\n\t\t\t\t'f4':115,\n\t\t\t\t'f5':116,\n\t\t\t\t'f6':117,\n\t\t\t\t'f7':118,\n\t\t\t\t'f8':119,\n\t\t\t\t'f9':120,\n\t\t\t\t'f10':121,\n\t\t\t\t'f11':122,\n\t\t\t\t'f12':123\n\t\t\t}\n\t\n\t\t\tvar modifiers = { \n\t\t\t\tshift: { wanted:false, pressed:false},\n\t\t\t\tctrl : { wanted:false, pressed:false},\n\t\t\t\talt  : { wanted:false, pressed:false},\n\t\t\t\tmeta : { wanted:false, pressed:false}\t//Meta is Mac specific\n\t\t\t};\n                        \n\t\t\tif(e.ctrlKey)\tmodifiers.ctrl.pressed = true;\n\t\t\tif(e.shiftKey)\tmodifiers.shift.pressed = true;\n\t\t\tif(e.altKey)\tmodifiers.alt.pressed = true;\n\t\t\tif(e.metaKey)   modifiers.meta.pressed = true;\n            \n\t\t\tvar k;\n\t\t\tfor(var i=0; k=keys[i], i<keys.length; i++) {\n\t\t\t\t// Due to stupid Opera bug I have to swap Ctrl and Meta keys\n\t\t\t\tif (is_mac && is_opera) {\n\t\t\t\t\tif (k == 'ctrl' || k == 'control')\n\t\t\t\t\t\tk = 'meta';\n\t\t\t\t\telse if (k == 'meta')\n\t\t\t\t\t\tk = 'ctrl';\n\t\t\t\t} else if (!is_mac && k == 'meta') {\n\t\t\t\t\tk = 'ctrl';\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t//Modifiers\n\t\t\t\tif(k == 'ctrl' || k == 'control') {\n\t\t\t\t\tkp++;\n\t\t\t\t\tmodifiers.ctrl.wanted = true;\n\n\t\t\t\t} else if(k == 'shift') {\n\t\t\t\t\tkp++;\n\t\t\t\t\tmodifiers.shift.wanted = true;\n\n\t\t\t\t} else if(k == 'alt') {\n\t\t\t\t\tkp++;\n\t\t\t\t\tmodifiers.alt.wanted = true;\n\t\t\t\t} else if(k == 'meta') {\n\t\t\t\t\tkp++;\n\t\t\t\t\tmodifiers.meta.wanted = true;\n\t\t\t\t} else if(k.length > 1) { //If it is a special key\n\t\t\t\t\tif(special_keys[k] == code) kp++;\n\t\t\t\t\t\n\t\t\t\t} else if(opt['keycode']) {\n\t\t\t\t\tif(opt['keycode'] == code) kp++;\n\n\t\t\t\t} else { //The special keys did not match\n\t\t\t\t\tif(character == k) kp++;\n\t\t\t\t\telse {\n\t\t\t\t\t\tif(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase\n\t\t\t\t\t\t\tcharacter = shift_nums[character]; \n\t\t\t\t\t\t\tif(character == k) kp++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tif(kp == keys.length && \n\t\t\t\t\t\tmodifiers.ctrl.pressed == modifiers.ctrl.wanted &&\n\t\t\t\t\t\tmodifiers.shift.pressed == modifiers.shift.wanted &&\n\t\t\t\t\t\tmodifiers.alt.pressed == modifiers.alt.wanted &&\n\t\t\t\t\t\tmodifiers.meta.pressed == modifiers.meta.wanted) {\n\t\t\t\t\n\t\t\t\tvar result = callback(e);\n\t\n\t\t\t\tif(result !== true && !opt['propagate']) { //Stop the event\n\t\t\t\t\t//e.cancelBubble is supported by IE - this will kill the bubbling process.\n\t\t\t\t\te.cancelBubble = true;\n\t\t\t\t\te.returnValue = false;\n\t\n\t\t\t\t\t//e.stopPropagation works in Firefox.\n\t\t\t\t\tif (e.stopPropagation) {\n\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.all_shortcuts[shortcut_combination] = {\n\t\t\t'callback':func, \n\t\t\t'target':ele, \n\t\t\t'event': opt['type']\n\t\t};\n\t\t//Attach the function with the event\n\t\tif(ele.addEventListener) ele.addEventListener(opt['type'], func, false);\n\t\telse if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);\n\t\telse ele['on'+opt['type']] = func;\n\t},\n\n\t//Remove the shortcut - just specify the shortcut and I will remove the binding\n\t'remove':function(shortcut_combination) {\n\t\tshortcut_combination = shortcut_combination.toLowerCase();\n\t\tvar binding = this.all_shortcuts[shortcut_combination];\n\t\tdelete(this.all_shortcuts[shortcut_combination])\n\t\tif(!binding) return;\n\t\tvar type = binding['event'];\n\t\tvar ele = binding['target'];\n\t\tvar callback = binding['callback'];\n\n\t\tif(ele.detachEvent) ele.detachEvent('on'+type, callback);\n\t\telse if(ele.removeEventListener) ele.removeEventListener(type, callback, false);\n\t\telse ele['on'+type] = false;\n\t}\n}/**\n * Editor manager that handles all incoming events and runs Zen Coding actions.\n * This manager is also used for setting up editor preferences\n * @author Sergey Chikuyonok (serge.che@gmail.com)\n * @link http://chikuyonok.ru\n * \n * @include \"actions.js\"\n * @include \"editor.js\"\n * @include \"shortcut.js\"\n */\rzen_textarea = (function(){ // should be global\n\tvar default_options = {\n\t\tprofile: 'xhtml',\n\t\tsyntax: 'html',\n\t\tuse_tab: false,\n\t\tpretty_break: false\n\t},\n\t\n\tmac_char_map = {\n\t\t'ctrl': '⌃',\n\t\t'control': '⌃',\n\t\t'meta': '⌘',\n\t\t'shift': '⇧',\n\t\t'alt': '⌥',\n\t\t'enter': '⏎',\n\t\t'tab': '⇥',\n\t\t'left': '←',\n\t\t'right': '→'\n\t},\n\t\n\tpc_char_map = {\n\t\t'left': '←',\n\t\t'right': '→'\n\t},\n\t\n\tshortcuts = {},\n\tis_mac = /mac\\s+os/i.test(navigator.userAgent),\n\t\n\t/** Zen Coding parameter name/value regexp for getting options from element */\n\tre_param = /\\bzc\\-(\\w+)\\-(\\w+)/g;\n\t\n\t/** @type {default_options} */\n\tvar options = {};\n\t\n\tfunction copyOptions(opt) {\n\t\topt = opt || {};\n\t\tvar result = {};\n\t\tfor (var p in default_options) if (default_options.hasOwnProperty(p)) {\n\t\t\tresult[p] = (p in opt) ? opt[p] : default_options[p];\n\t\t}\n\t\t\n\t\treturn result;\n\t}\n\t\n\toptions = copyOptions();\n\t\n\t/**\n\t * Makes first letter of string in uppercase\n\t * @param {String} str\n\t */\n\tfunction capitalize(str) {\n\t\treturn str.charAt().toUpperCase() + str.substring(1);\n\t}\n\t\n\tfunction humanize(str) {\n\t\treturn capitalize(str.replace(/_(\\w)/g, function(s, p){return ' ' + p.toUpperCase()}));\n\t}\n\t\n\tfunction formatShortcut(char_map, glue) {\n\t\tvar result = [];\n\t\tif (typeof(glue) == 'undefined')\n\t\t\tglue = '+';\n\t\t\t\n\t\tfor (var p in shortcuts) if (shortcuts.hasOwnProperty(p)) {\n\t\t\tvar keys = p.split('+'),\n\t\t\t\tar = [],\n\t\t\t\tlp = p.toLowerCase();\n\t\t\t\t\n\t\t\tif (lp == 'tab' || lp == 'enter')\n\t\t\t\tcontinue;\n\t\t\t\t\n\t\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\t\tvar key = keys[i].toLowerCase();\n\t\t\t\tar.push(key in char_map ? char_map[key] : capitalize(key));\n\t\t\t}\n\t\t\t\n\t\t\tresult.push({\n\t\t\t\t'keystroke': ar.join(glue), \n\t\t\t\t'action_name': humanize(shortcuts[p])\n\t\t\t});\n\t\t}\n\t\t\n\t\treturn result;\n\t}\n\t\n\t\n\t/**\n\t * Get Zen Coding options from element's class name\n\t * @param {Element} elem\n\t */\n\tfunction getOptionsFromElement(elem) {\n\t\tvar param_str = elem.className || '',\n\t\t\tm,\n\t\t\tresult = copyOptions(options);\n\t\t\t\n\t\twhile ( (m = re_param.exec(param_str)) ) {\n\t\t\tvar key = m[1].toLowerCase(),\n\t\t\t\tvalue = m[2].toLowerCase();\n\t\t\t\n\t\t\tif (value == 'true' || value == 'yes' || value == '1')\n\t\t\t\tvalue = true;\n\t\t\telse if (value == 'false' || value == 'no' || value == '0')\n\t\t\t\tvalue = false;\n\t\t\t\t\n\t\t\tresult[key] = value;\n\t\t}\n\t\t\n\t\treturn result;\n\t}\n\t\n\t/**\n\t * Returns normalized action name\n\t * @param {String} name Action name (like 'Expand Abbreviation')\n\t * @return Normalized name for coding (like 'expand_abbreviation')\n\t */\n\tfunction normalizeActionName(name) {\n\t\treturn name\n\t\t\t.replace(/(^\\s+|\\s+$)/g, '') // remove trailing spaces\n\t\t\t.replace(/\\s+/g, '_')\n\t\t\t.toLowerCase();\n\t}\n\t\n\t/**\n\t * Runs actions called by user\n\t * @param {String} name Normalized action name\n\t * @param {Event} evt Event object\n\t */\n\tfunction runAction(name, evt) {\n\t\t/** @type {Element} */\n\t\tvar target_elem = evt.target || evt.srcElement,\n\t\t\tkey_code = evt.keyCode || evt.which;\n\t\t\t\n\t\tif (target_elem && target_elem.nodeType == 1 && target_elem.nodeName == 'TEXTAREA') {\n\t\t\tzen_editor.setTarget(target_elem);\n\t\t\t\n\t\t\tvar options = getOptionsFromElement(target_elem),\n\t\t\t\tsyntax = options.syntax,\n\t\t\t\tprofile_name = options.profile;\n\t\t\t\n\t\t\tswitch (name) {\n\t\t\t\tcase 'expand_abbreviation':\n\t\t\t\t\tif (key_code == 9) {\n\t\t\t\t\t\tif (options.use_tab)\n\t\t\t\t\t\t\texpandAbbreviationWithTab(zen_editor, syntax, profile_name);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t// user pressed Tab key but it's forbidden in \n\t\t\t\t\t\t\t// Zen Coding: bubble up event\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\n\t\t\t\t\t} else {\n\t\t\t\t\t\texpandAbbreviation(zen_editor, syntax, profile_name);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'match_pair_inward':\n\t\t\t\tcase 'balance_tag_inward':\n\t\t\t\t\tmatchPair(zen_editor, 'in');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'match_pair_outward':\n\t\t\t\tcase 'balance_tag_outward':\n\t\t\t\t\tmatchPair(zen_editor, 'out');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'wrap_with_abbreviation':\n\t\t\t\t\tvar abbr = prompt('Enter abbreviation', 'div');\n\t\t\t\t\tif (abbr)\n\t\t\t\t\t\twrapWithAbbreviation(zen_editor, abbr, syntax, profile_name);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'next_edit_point':\n\t\t\t\t\tnextEditPoint(zen_editor);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'previous_edit_point':\n\t\t\t\tcase 'prev_edit_point':\n\t\t\t\t\tprevEditPoint(zen_editor);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'pretty_break':\n\t\t\t\tcase 'format_line_break':\n\t\t\t\t\tif (key_code == 13) {\n\t\t\t\t\t\tif (options.pretty_break)\n\t\t\t\t\t\t\tinsertFormattedNewline(zen_editor);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t// user pressed Enter but it's forbidden in \n\t\t\t\t\t\t\t// Zen Coding: bubble up event\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinsertFormattedNewline(zen_editor);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'select_line':\n\t\t\t\t\tselectLine(zen_editor);\n\t\t\t}\n\t\t} else {\n\t\t\t// allow event bubbling\n\t\t\treturn true;\n\t\t}\n\t}\n\t\n\t/**\n\t * Bind shortcut to Zen Coding action\n\t * @param {String} keystroke\n\t * @param {String} action_name\n\t */\n\tfunction addShortcut(keystroke, action_name) {\n\t\taction_name = normalizeActionName(action_name);\n\t\tshortcuts[keystroke.toLowerCase()] = action_name;\n\t\tshortcut.add(keystroke, function(evt){\n\t\t\treturn runAction(action_name, evt);\n\t\t});\n\t}\n\t\n\t// add default shortcuts\n\taddShortcut('Meta+E', 'Expand Abbreviation');\n\taddShortcut('Tab', 'Expand Abbreviation');\n\taddShortcut('Meta+D', 'Balance Tag Outward');\n\taddShortcut('Shift+Meta+D', 'Balance Tag inward');\n\taddShortcut('Shift+Meta+A', 'Wrap with Abbreviation');\n\taddShortcut('Ctrl+RIGHT', 'Next Edit Point');\n\taddShortcut('Ctrl+LEFT', 'Previous Edit Point');\n\taddShortcut('Meta+L', 'Select Line');\n\taddShortcut('Enter', 'Format Line Break');\n\t\n\t\n\treturn {\n\t\tshortcut: addShortcut,\n\t\t\n\t\t/**\n\t\t * Removes shortcut binding\n\t\t * @param {String} keystroke\n\t\t */\n\t\tunbindShortcut: function(keystroke) {\n\t\t\tkeystroke = keystroke.toLowerCase();\n\t\t\tif (keystroke in shortcuts)\n\t\t\t\tdelete shortcuts[keystroke];\n\t\t\tshortcut.remove(keystroke);\n\t\t},\n\t\t\n\t\t/**\n\t\t * Setup editor. Pass object with values defined in \n\t\t * <code>default_options</code>\n\t\t */\n\t\tsetup: function(opt) {\n\t\t\toptions = copyOptions(opt);\n\t\t},\n\t\t\n\t\t/**\n\t\t * Returns option value\n\t\t */\n\t\tgetOption: function(name) {\n\t\t\treturn options[name];\n\t\t},\n\t\t\n\t\t/**\n\t\t * Returns array of binded actions and their keystrokes\n\t\t * @return {Array}\n\t\t */\n\t\tgetShortcuts: function() {\n\t\t\treturn formatShortcut(is_mac ? mac_char_map : pc_char_map, is_mac ? '' : '+');\n\t\t},\n\t\t\n\t\t/**\n\t\t * Show info window about Zen Coding\n\t\t */\n\t\tshowInfo: function() {\n\t\t\tvar message = 'All textareas on this page are powered by Zen Coding project: ' +\n\t\t\t\t\t'a set of tools for fast HTML coding.\\n\\n' +\n\t\t\t\t\t'Available shortcuts:\\n';\n\t\t\t\t\t\n\t\t\tvar sh = this.getShortcuts(),\n\t\t\t\tactions = [];\n\t\t\t\t\n\t\t\tfor (var i = 0; i < sh.length; i++) {\n\t\t\t\tactions.push(sh[i].keystroke + ' — ' + sh[i].action_name)\n\t\t\t}\n\t\t\t\n\t\t\tmessage += actions.join('\\n') + '\\n\\n';\n\t\t\tmessage += 'More info on http://code.google.com/p/zen-coding/';\n\t\t\t\n\t\t\talert(message);\n\t\t\t\n\t\t}\n\t}\n})();\t\n})();\n"
  }
]