Showing preview only (1,741K chars total). Download the full file or copy to clipboard to get everything.
Repository: Dither/full-text-rss
Branch: master
Commit: c155b628eba2
Files: 100
Total size: 1.6 MB
Directory structure:
gitextract_1gv9702v/
├── README.md
├── README.txt
├── UPDATING.txt
├── admin/
│ ├── apc.php
│ ├── codemirror/
│ │ ├── codemirror.css
│ │ ├── codemirror.js
│ │ └── properties.js
│ ├── edit-pattern.php
│ ├── index.php
│ ├── login.php
│ ├── require_login.php
│ ├── template.php
│ └── update.php
├── cache/
│ ├── index.php
│ ├── rss/
│ │ └── index.php
│ └── urls/
│ └── index.php
├── changelog.txt
├── cleancache.php
├── config.php
├── css/
│ ├── feed.css
│ └── feed.xsl
├── custom_config.php.demo
├── ftr_compatibility_test.php
├── index.php
├── js/
│ ├── bootstrap-popover.js
│ ├── bootstrap-tab.js
│ └── bootstrap-tooltip.js
├── libraries/
│ ├── Zend/
│ │ ├── Cache/
│ │ │ ├── Backend/
│ │ │ │ ├── ExtendedInterface.php
│ │ │ │ ├── File.php
│ │ │ │ └── Interface.php
│ │ │ ├── Backend.php
│ │ │ ├── Core.php
│ │ │ └── Exception.php
│ │ ├── Cache.php
│ │ └── Exception.php
│ ├── content-extractor/
│ │ ├── ContentExtractor.php
│ │ └── SiteConfig.php
│ ├── feedwriter/
│ │ ├── FeedItem.php
│ │ └── FeedWriter.php
│ ├── htmLawed/
│ │ └── htmLawed2.php
│ ├── html5/
│ │ ├── Data.php
│ │ ├── InputStream.php
│ │ ├── Parser.php
│ │ ├── Tokenizer.php
│ │ ├── TreeBuilder.php
│ │ └── named-character-references.ser
│ ├── humble-http-agent/
│ │ ├── CookieJar.php
│ │ ├── HumbleHttpAgent.php
│ │ ├── RollingCurl.php
│ │ └── SimplePie_HumbleHttpAgent.php
│ ├── language-detect/
│ │ ├── LanguageDetect/
│ │ │ ├── Exception.php
│ │ │ ├── ISO639.php
│ │ │ └── Parser.php
│ │ └── LanguageDetect.php
│ ├── readability/
│ │ ├── ImageCaching.php
│ │ ├── JSLikeHTMLElement.php
│ │ └── Readability.php
│ └── simplepie/
│ ├── LICENSE.txt
│ ├── autoloader.php
│ └── library/
│ ├── SimplePie/
│ │ ├── Author.php
│ │ ├── Cache/
│ │ │ ├── Base.php
│ │ │ ├── DB.php
│ │ │ ├── File.php
│ │ │ ├── Memcache.php
│ │ │ └── MySQL.php
│ │ ├── Cache.php
│ │ ├── Caption.php
│ │ ├── Category.php
│ │ ├── Content/
│ │ │ └── Type/
│ │ │ └── Sniffer.php
│ │ ├── Copyright.php
│ │ ├── Core.php
│ │ ├── Credit.php
│ │ ├── Decode/
│ │ │ └── HTML/
│ │ │ └── Entities.php
│ │ ├── Enclosure.php
│ │ ├── Exception.php
│ │ ├── File.php
│ │ ├── HTTP/
│ │ │ └── Parser.php
│ │ ├── IRI.php
│ │ ├── Item.php
│ │ ├── Locator.php
│ │ ├── Misc.php
│ │ ├── Net/
│ │ │ └── IPv6.php
│ │ ├── Parse/
│ │ │ └── Date.php
│ │ ├── Parser.php
│ │ ├── Rating.php
│ │ ├── Registry.php
│ │ ├── Restriction.php
│ │ ├── Sanitize.php
│ │ ├── Source.php
│ │ ├── XML/
│ │ │ └── Declaration/
│ │ │ └── Parser.php
│ │ └── gzdecode.php
│ └── SimplePie.php
├── license.txt
├── makefulltextfeed.php
├── manifest.yml
└── site_config/
├── README.txt
├── custom/
│ └── index.php
├── index.php
└── standard/
├── .wikipedia.org.txt
└── version.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: README.md
================================================
Full-Text RSS
=============
### NOTE
This is a our public version of Full-Text RSS available to download for free from <http://code.fivefilters.org>.
For best extraction results, and to help us sustain the project, you can purchase the most up-to-date version at <http://fivefilters.org/content-only/#download> - so if you like this free version, please consider supporting us by purchasing the latest release.
If you have no need for the latest release, but would still like to contribute something, you can donate via [Gittip](https://www.gittip.com/fivefilters/) or [Flattr](https://flattr.com/profile/k1m).
### About
See <http://fivefilters.org/content-only/> for a description of the code.
### Installation
1. Extract the files in this ZIP archive to a folder on your computer.
2. FTP the files up to your server
3. Access index.php through your browser. E.g. http://example.org/full-text-rss/index.php
4. Enter a URL in the form field to test the code
5. If you get an RSS feed with full-text content, all is working well. :)
### Configuration (optional)
1. Save a copy of config.php as custom_config.php and edit custom_config.php
2. If you decide to enable caching, make sure the cache folder (and its 2 sub folders) is writable. (You might need to change the permissions of these folders to 777 through your FTP client.)
### Site-specific extraction rules
This free version does not contain the site config files we include with purchased copies, but these are now all available [online](https://github.com/fivefilters/ftr-site-config). If you'd like to keep yours up to date using Git, follow the steps below:
1. Change into the site_config/standard/ folder
2. Delete everything in there
3. Using the command line, enter: `git clone https://github.com/fivefilters/ftr-site-config.git .`
4. Git should now download the latest site config files for you.
5. To update the site config files again, you can simply run `git pull` from the directory.
### Code example
If you're developing an application which requires content extraction, you can call Full-Text RSS as a web service from within your application. Here's how to do it in PHP:
<?php
// $ftr should be URL where you installed this application
$ftr = 'http://example.org/full-text-rss/';
$article = 'http://www.bbc.co.uk/news/world-europe-21936308';
$request = $ftr.'makefulltextfeed.php?format=json&url='.urlencode($article);
// Send HTTP request and get response
$result = @file_get_contents($request);
if (!$result) die('Failed to fetch content');
$json = @json_decode($result);
if (!$json) die('Failed to parse JSON');
// What do we have?
// var_dump($json);
// Items?
// var_dump($json->rss->channel->item);
$title = $json->rss->channel->item->title;
// Note: this works when you're processing an article.
// If the input URL is a feed, ->item will be an array.
echo $title;
### Different language?
Although we don't have examples in other programming languages, the essential steps should be:
1. Construct the request URL using URL where you installed Full-Text RSS and the article or feed URL (see $ftr, $article, $request in example above).
2. Fetch the resulting URL using an HTTP GET request.
3. Parse the HTTP response body as JSON and grab what you need.
================================================
FILE: README.txt
================================================
Full-Text RSS
=============
About
-----
See http://fivefilters.org/content-only/ for a description of the code.
Installation
------------
1. Extract the files in this ZIP archive to a folder on your computer.
2. FTP the files up to your server
3. Access index.php through your browser. E.g. http://example.org/full-text-rss/index.php
4. Enter a URL in the form field to test the code
5. If you get an RSS feed with full-text content, all is working well. :)
Configuration (optional)
------------------------
1. Save a copy of config.php as custom_config.php and edit custom_config.php
2. If you decide to enable caching, make sure the cache folder (and its 2 sub folders) is writable.
(You might need to change the permissions of these folders to 777 through your FTP client.)
3. If you want to use the admin area to edit/update your site config files, make sure the
site_config folder (and its 2 sub folders) is writable. (You might need to change the permissions
of these folders to 777 through your FTP client.)
Help
----
Please visit http://help.fivefilters.org
================================================
FILE: UPDATING.txt
================================================
Updating Full-Text RSS
======================
To update your copy of Full-Text RSS to ensure feeds continue to be processed as they were before, we suggest the following steps:
1. Keep your current installation in place for now (we'll deal with it later)
2. Extract this updated package to a new folder -- for example, if the last version is in a folder called 'full-text-rss', extract this version to a new folder called 'full-text-rss-updated'
3. Upload the new folder to your server
4. Access index.php in the new folder through your browser -- for example http://example.org/full-text-rss-updated/index.php
5. Enter a URL in the form field to test the updated code
6. If you'd configured the last version, copy custom_config.php from your old version to the new installation.
7. If you'd added custom site config files (in site_config/custom/), copy those over to the new installation.
8. If you'd enabled caching, make sure the cache folder (and its 2 sub folders) is writable. (You might need to change the permissions of these folders to 777 through your FTP client.)
9. Test the new copy again to make sure the config values are now applied to the new version.
10. Now simply rename the folder with your old copy to 'full-text-rss-old' and then rename the folder with the new copy to 'full-text-rss' (or whatever name you'd given the original folder).
That's all that's needed. Your feeds should continue to work as they did before. Let us know if you have any trouble: help@fivefilters.org.
Updating Site Patterns
======================
Site patterns are used by Full-Text RSS to improve extraction for certain sites. These are simple text files which are updated more frequently than the Full-Text RSS software itself.
To make sure your copy of Full-Text RSS is using the latest site patterns, We've created a simple tool to help you get the latest copy of these site patterns from FiveFilters.org. To use it, access the admin/ folder in your browser and follow the instructions.
Alternatively, you can download the latest set of site config files via GitHub: https://github.com/fivefilters/ftr-site-config
================================================
FILE: admin/apc.php
================================================
<?php
/*
+----------------------------------------------------------------------+
| APC (slightly modified for the Full-Text RSS admin panel) |
+----------------------------------------------------------------------+
| Copyright (c) 2006-2011 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Ralf Becker <beckerr@php.net> |
| Rasmus Lerdorf <rasmus@php.net> |
| Ilia Alshanetsky <ilia@prohost.org> |
+----------------------------------------------------------------------+
All other licensing and usage conditions are those of the PHP Group.
*/
$VERSION='$Id: apc.php 307048 2011-01-03 23:53:17Z kalle $';
////////// READ OPTIONAL CONFIGURATION FILE ////////////
if (file_exists("apc.conf.php")) include("apc.conf.php");
////////////////////////////////////////////////////////
////////////////////////////////
// Load config file
////////////////////////////////
$admin_page = 'apc';
require_once('../config.php');
require_once('require_login.php');
require_once('template.php');
if (!isset($_REQUEST['IMG'])) tpl_header('APC');
////////// BEGIN OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////
defaults('USE_AUTHENTICATION',0); // Use (internal) authentication - best choice if
// no other authentication is available
// If set to 0:
// There will be no further authentication. You
// will have to handle this by yourself!
// If set to 1:
// You need to change ADMIN_PASSWORD to make
// this work!
//defaults('ADMIN_USERNAME','admin'); // Admin Username
//defaults('ADMIN_PASSWORD',''); // Admin Password - CHANGE THIS TO ENABLE!!!
// (beckerr) I'm using a clear text password here, because I've no good idea how to let
// users generate a md5 or crypt password in a easy way to fill it in above
//defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German
defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US
defaults('GRAPH_SIZE',200); // Image size
//defaults('PROXY', 'tcp://127.0.0.1:8080');
////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
// "define if not defined"
function defaults($d,$v) {
if (!defined($d)) define($d,$v); // or just @define(...)
}
// rewrite $PHP_SELF to block XSS attacks
//
$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],''), ENT_QUOTES, 'UTF-8') : '';
$time = time();
$host = php_uname('n');
if($host) { $host = '('.$host.')'; }
if (isset($_SERVER['SERVER_ADDR'])) {
$host .= ' ('.$_SERVER['SERVER_ADDR'].')';
}
// operation constants
define('OB_HOST_STATS',1);
define('OB_SYS_CACHE',2);
define('OB_USER_CACHE',3);
define('OB_SYS_CACHE_DIR',4);
define('OB_VERSION_CHECK',9);
// check validity of input variables
$vardom=array(
'OB' => '/^\d+$/', // operational mode switch
'CC' => '/^[01]$/', // clear cache requested
'DU' => '/^.*$/', // Delete User Key
'SH' => '/^[a-z0-9]+$/', // shared object description
'IMG' => '/^[123]$/', // image to generate
'LO' => '/^1$/', // login requested
'COUNT' => '/^\d+$/', // number of line displayed in list
'SCOPE' => '/^[AD]$/', // list view scope
'SORT1' => '/^[AHSMCDTZ]$/', // first sort key
'SORT2' => '/^[DA]$/', // second sort key
'AGGR' => '/^\d+$/', // aggregation by dir level
'SEARCH' => '~^[a-zA-Z0-1/_.-]*$~' // aggregation by dir level
);
// default cache mode
$cache_mode='opcode';
// cache scope
$scope_list=array(
'A' => 'cache_list',
'D' => 'deleted_list'
);
// handle POST and GET requests
if (empty($_REQUEST)) {
if (!empty($_GET) && !empty($_POST)) {
$_REQUEST = array_merge($_GET, $_POST);
} else if (!empty($_GET)) {
$_REQUEST = $_GET;
} else if (!empty($_POST)) {
$_REQUEST = $_POST;
} else {
$_REQUEST = array();
}
}
// check parameter syntax
foreach($vardom as $var => $dom) {
if (!isset($_REQUEST[$var])) {
$MYREQUEST[$var]=NULL;
} else if (!is_array($_REQUEST[$var]) && preg_match($dom.'D',$_REQUEST[$var])) {
$MYREQUEST[$var]=$_REQUEST[$var];
} else {
$MYREQUEST[$var]=$_REQUEST[$var]=NULL;
}
}
// check parameter sematics
if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE']="A";
if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1']="H";
if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D";
if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS;
if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20;
if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A';
$MY_SELF=
"$PHP_SELF".
"?SCOPE=".$MYREQUEST['SCOPE'].
"&SORT1=".$MYREQUEST['SORT1'].
"&SORT2=".$MYREQUEST['SORT2'].
"&COUNT=".$MYREQUEST['COUNT'];
$MY_SELF_WO_SORT=
"$PHP_SELF".
"?SCOPE=".$MYREQUEST['SCOPE'].
"&COUNT=".$MYREQUEST['COUNT'];
// authentication needed?
//
if (!USE_AUTHENTICATION) {
$AUTHENTICATED=1;
} else {
$AUTHENTICATED=0;
if (ADMIN_PASSWORD!='password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) {
if (!isset($_SERVER['PHP_AUTH_USER']) ||
!isset($_SERVER['PHP_AUTH_PW']) ||
$_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||
$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
Header("WWW-Authenticate: Basic realm=\"APC Login\"");
Header("HTTP/1.0 401 Unauthorized");
echo <<<EOB
<html><body>
<h1>Rejected!</h1>
<big>Wrong Username or Password!</big><br/> <br/>
<big><a href='$PHP_SELF?OB={$MYREQUEST['OB']}'>Continue...</a></big>
</body></html>
EOB;
exit;
} else {
$AUTHENTICATED=1;
}
}
}
// select cache mode
if ($AUTHENTICATED && $MYREQUEST['OB'] == OB_USER_CACHE) {
$cache_mode='user';
}
// clear cache
if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) {
apc_clear_cache($cache_mode);
}
if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) {
apc_delete($MYREQUEST['DU']);
}
if(!function_exists('apc_cache_info') || !($cache=@apc_cache_info($cache_mode))) {
echo "No cache info available. APC does not appear to be running.";
exit;
}
$cache_user = apc_cache_info('user', 1);
$mem=apc_sma_info();
if(!$cache['num_hits']) { $cache['num_hits']=1; $time++; } // Avoid division by 0 errors on a cache clear
// don't cache this page
//
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
function duration($ts) {
global $time;
$years = (int)((($time - $ts)/(7*86400))/52.177457);
$rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
$weeks = (int)(($rem)/(7*86400));
$days = (int)(($rem)/86400) - $weeks*7;
$hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
$mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
$str = '';
if($years==1) $str .= "$years year, ";
if($years>1) $str .= "$years years, ";
if($weeks==1) $str .= "$weeks week, ";
if($weeks>1) $str .= "$weeks weeks, ";
if($days==1) $str .= "$days day,";
if($days>1) $str .= "$days days,";
if($hours == 1) $str .= " $hours hour and";
if($hours>1) $str .= " $hours hours and";
if($mins == 1) $str .= " 1 minute";
else $str .= " $mins minutes";
return $str;
}
// create graphics
//
function graphics_avail() {
return extension_loaded('gd');
}
if (isset($MYREQUEST['IMG']))
{
if (!graphics_avail()) {
exit(0);
}
function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
$r=$diameter/2;
$w=deg2rad((360+$start+($end-$start)/2)%360);
if (function_exists("imagefilledarc")) {
// exists only if GD 2.0.1 is avaliable
imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
} else {
imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
}
if ($text) {
if ($placeindex>0) {
imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
} else {
imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
}
}
}
function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) {
$r=$diameter/2;
$w=deg2rad((360+$start+($end-$start)/2)%360);
if ($placeindex>0) {
imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
} else {
imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
}
}
function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
global $col_black;
$x1=$x+$w-1;
$y1=$y+$h-1;
imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
imagerectangle($im, $x, $y1, $x1, $y, $color1);
if ($text) {
if ($placeindex>0) {
if ($placeindex<16)
{
$px=5;
$py=$placeindex*12+6;
imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
imagestring($im,2,$px,$py-6,$text,$color1);
} else {
if ($placeindex<31) {
$px=$x+40*2;
$py=($placeindex-15)*12+6;
} else {
$px=$x+40*2+100*intval(($placeindex-15)/15);
$py=($placeindex%15)*12+6;
}
imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
imagestring($im,2,$px+2,$py-6,$text,$color1);
}
} else {
imagestring($im,4,$x+5,$y1-16,$text,$color1);
}
}
}
$size = GRAPH_SIZE; // image size
if ($MYREQUEST['IMG']==3)
$image = imagecreate(2*$size+150, $size+10);
else
$image = imagecreate($size+50, $size+10);
$col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
$col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
$col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
$col_black = imagecolorallocate($image, 0, 0, 0);
imagecolortransparent($image,$col_white);
switch ($MYREQUEST['IMG']) {
case 1:
$s=$mem['num_seg']*$mem['seg_size'];
$a=$mem['avail_mem'];
$x=$y=$size/2;
$fuzz = 0.000001;
// This block of code creates the pie chart. It is a lot more complex than you
// would expect because we try to visualize any memory fragmentation as well.
$angle_from = 0;
$string_placement=array();
for($i=0; $i<$mem['num_seg']; $i++) {
$ptr = 0;
$free = $mem['block_lists'][$i];
uasort($free, 'block_sort');
foreach($free as $block) {
if($block['offset']!=$ptr) { // Used block
$angle_to = $angle_from+($block['offset']-$ptr)/$s;
if(($angle_to+$fuzz)>1) $angle_to = 1;
if( ($angle_to*360) - ($angle_from*360) >= 1) {
fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
if (($angle_to-$angle_from)>0.05) {
array_push($string_placement, array($angle_from,$angle_to));
}
}
$angle_from = $angle_to;
}
$angle_to = $angle_from+($block['size'])/$s;
if(($angle_to+$fuzz)>1) $angle_to = 1;
if( ($angle_to*360) - ($angle_from*360) >= 1) {
fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_green);
if (($angle_to-$angle_from)>0.05) {
array_push($string_placement, array($angle_from,$angle_to));
}
}
$angle_from = $angle_to;
$ptr = $block['offset']+$block['size'];
}
if ($ptr < $mem['seg_size']) { // memory at the end
$angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s;
if(($angle_to+$fuzz)>1) $angle_to = 1;
fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
if (($angle_to-$angle_from)>0.05) {
array_push($string_placement, array($angle_from,$angle_to));
}
}
}
foreach ($string_placement as $angle) {
text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0])));
}
break;
case 2:
$s=$cache['num_hits']+$cache['num_misses'];
$a=$cache['num_hits'];
fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
break;
case 3:
$s=$mem['num_seg']*$mem['seg_size'];
$a=$mem['avail_mem'];
$x=130;
$y=1;
$j=1;
// This block of code creates the bar chart. It is a lot more complex than you
// would expect because we try to visualize any memory fragmentation as well.
for($i=0; $i<$mem['num_seg']; $i++) {
$ptr = 0;
$free = $mem['block_lists'][$i];
uasort($free, 'block_sort');
foreach($free as $block) {
if($block['offset']!=$ptr) { // Used block
$h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s;
if ($h>0) {
$j++;
if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($block['offset']-$ptr),$j);
else fill_box($image,$x,$y,50,$h,$col_black,$col_red);
}
$y+=$h;
}
$h=(GRAPH_SIZE-5)*($block['size'])/$s;
if ($h>0) {
$j++;
if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_green,bsize($block['size']),$j);
else fill_box($image,$x,$y,50,$h,$col_black,$col_green);
}
$y+=$h;
$ptr = $block['offset']+$block['size'];
}
if ($ptr < $mem['seg_size']) { // memory at the end
$h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s;
if ($h > 0) {
fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++);
}
}
}
break;
case 4:
$s=$cache['num_hits']+$cache['num_misses'];
$a=$cache['num_hits'];
fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
break;
}
header("Content-type: image/png");
imagepng($image);
exit;
}
// pretty printer for byte values
//
function bsize($s) {
foreach (array('','K','M','G') as $i => $k) {
if ($s < 1024) break;
$s/=1024;
}
return sprintf("%5.1f %sBytes",$s,$k);
}
// sortable table header in "scripts for this host" view
function sortheader($key,$name,$extra='') {
global $MYREQUEST, $MY_SELF_WO_SORT;
if ($MYREQUEST['SORT1']==$key) {
$MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A';
}
return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=".$MYREQUEST['SORT2']."\">$name</a>";
}
// create menu entry
function menu_entry($ob,$title) {
global $MYREQUEST,$MY_SELF;
if ($MYREQUEST['OB']!=$ob) {
return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>";
} else if (empty($MYREQUEST['SH'])) {
return "<li><span class=active>$title</span></li>";
} else {
return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>";
}
}
function put_login_link($s="Login")
{
global $MY_SELF,$MYREQUEST,$AUTHENTICATED;
// needs ADMIN_PASSWORD to be changed!
//
if (!USE_AUTHENTICATION) {
return;
} else if (ADMIN_PASSWORD=='password')
{
print <<<EOB
<a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a>
EOB;
} else if ($AUTHENTICATED) {
print <<<EOB
'{$_SERVER['PHP_AUTH_USER']}' logged in!
EOB;
} else{
print <<<EOB
<a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a>
EOB;
}
}
function block_sort($array1, $array2)
{
if ($array1['offset'] > $array2['offset']) {
return 1;
} else {
return -1;
}
}
?>
<?php
/*
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>APC INFO <?php echo $host ?></title>
*/
?>
<style><!--
select { width: auto; }
body { font-size:100.01%; margin:0; padding:0; }
body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
* html body {font-size:0.8em}
* html p {font-size:0.8em}
* html td {font-size:0.8em}
* html th {font-size:0.8em}
* html input {font-size:0.8em}
* html submit {font-size:0.8em}
td { vertical-align:top }
a { color:black; font-weight:none; text-decoration:none; }
a:hover { text-decoration:underline; }
div.content { padding:1em 1em 1em 1em; /*position:absolute;*/ width:97%; z-index:100; }
div.head { display: none; }
div.head div.login {
position:absolute;
right: 1em;
top: 1.2em;
color:white;
width:6em;
}
div.head div.login a {
position:absolute;
right: 0em;
background:rgb(119,123,180);
border:solid rgb(102,102,153) 2px;
color:white;
font-weight:bold;
padding:0.1em 0.5em 0.1em 0.5em;
text-decoration:none;
}
div.head div.login a:hover {
background:rgb(193,193,244);
}
h1.apc { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
* html h1.apc { margin-bottom:-7px; }
h1.apc a:hover { text-decoration:none; color:rgb(90,90,90); }
h1.apc div.logo span.logo {
background:rgb(119,123,180);
color:black;
border-right: solid black 1px;
border-bottom: solid black 1px;
font-style:italic;
font-size:1em;
padding-left:1.2em;
padding-right:1.2em;
text-align:right;
}
h1.apc div.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
h1.apc div.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
h1.apc div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
hr.apc {
background:white;
border-bottom:solid rgb(102,102,153) 1px;
border-style:none;
border-top:solid rgb(102,102,153) 10px;
height:12px;
margin:0;
margin-top:1px;
padding:0;
}
ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
.menu a {
background:rgb(153,153,204);
border:solid rgb(102,102,153) 2px;
color:white;
font-weight:bold;
margin-right:0em;
padding:0.1em 0.5em 0.1em 0.5em;
text-decoration:none;
margin-left: 0;
}
ol.menu a.child_active {
background:rgb(153,153,204);
border:solid rgb(102,102,153) 2px;
color:white;
font-weight:bold;
margin-right:0em;
padding:0.1em 0.5em 0.1em 0.5em;
text-decoration:none;
border-left: solid black 5px;
margin-left: 0px;
}
ol.menu span.active {
background:rgb(153,153,204);
border:solid rgb(102,102,153) 2px;
color:black;
font-weight:bold;
margin-right:0em;
padding:0.1em 0.5em 0.1em 0.5em;
text-decoration:none;
border-left: solid black 5px;
}
ol.menu span.inactive {
background:rgb(193,193,244);
border:solid rgb(182,182,233) 2px;
color:white;
font-weight:bold;
margin-right:0em;
padding:0.1em 0.5em 0.1em 0.5em;
text-decoration:none;
margin-left: 5px;
}
ol.menu a:hover {
background:rgb(193,193,244);
text-decoration:none;
}
div.info {
background:rgb(204,204,204);
border:solid rgb(204,204,204) 1px;
margin-bottom:1em;
}
div.info h2 {
background:rgb(204,204,204);
color:black;
font-size:1em;
margin:0;
padding:0.1em 1em 0.1em 1em;
}
div.info table {
border:solid rgb(204,204,204) 1px;
border-spacing:0;
width:100%;
}
div.info table th {
background:rgb(204,204,204);
color:white;
margin:0;
padding:0.1em 1em 0.1em 1em;
}
div.info table th a.sortable { color:black; }
div.info table tr.tr-0 { background:rgb(238,238,238); }
div.info table tr.tr-1 { background:rgb(221,221,221); }
div.info table td { padding:0.3em 1em 0.3em 1em; }
div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
div.info table td h3 {
color:black;
font-size:1.1em;
margin-left:-0.3em;
}
div.graph { margin-bottom:1em }
div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
div.graph table td.td-0 { background:rgb(238,238,238); }
div.graph table td.td-1 { background:rgb(221,221,221); }
div.graph table td { padding:0.2em 1em 0.4em 1em; }
div.div1,div.div2 { margin-bottom:1em; width:35em; }
div.div3 { /*position:absolute; left:40em; top:1em; width:580px; */}
//div.div3 { position:absolute; left:37em; top:1em; right:1em; }
div.sorting { margin:1.5em 0em 1.5em 2em }
.center { text-align:center }
.aright { /*position:absolute;right:1em */}
.right { text-align:right }
.ok { color:rgb(0,200,0); font-weight:bold}
.failed { color:rgb(200,0,0); font-weight:bold}
span.box {
border: black solid 1px;
border-right:solid black 2px;
border-bottom:solid black 2px;
padding:0 0.5em 0 0.5em;
margin-right:1em;
}
span.green { background:#60F060; padding:0 0.5em 0 0.5em}
span.red { background:#D06030; padding:0 0.5em 0 0.5em }
div.authneeded {
background:rgb(238,238,238);
border:solid rgb(204,204,204) 1px;
color:rgb(200,0,0);
font-size:1.2em;
font-weight:bold;
padding:2em;
text-align:center;
}
input {
background:rgb(153,153,204);
border:solid rgb(102,102,153) 2px;
color:white;
font-weight:bold;
margin-right:1em;
padding:0.1em 0.5em 0.1em 0.5em;
}
a.clearcache {
background-color: red;
color: #fff;
}
//-->
</style>
</head>
<body>
<div class="head">
<h1 class="apc">
<div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APC">APC</a></span></div>
<div class="nameinfo">Opcode Cache</div>
</h1>
<div class="login">
<?php put_login_link(); ?>
</div>
<hr class="apc">
</div>
<?php
// Display main Menu
echo <<<EOB
<ol class=menu>
<li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li>
EOB;
echo
menu_entry(1,'View Host Stats'),
menu_entry(2,'System Cache Entries');
if ($AUTHENTICATED) {
echo menu_entry(4,'Per-Directory Entries');
}
echo
menu_entry(3,'User Cache Entries'),
menu_entry(9,'Version Check');
echo <<<EOB
</ol>
EOB;
if ($AUTHENTICATED) {
echo <<<EOB
<div class="menu" style="margin-top: 10px; text-align: right;"><a class="aright clearcache" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascript:return confirm('Are you sure?');">Clear $cache_mode Cache</a></div>
EOB;
}
// CONTENT
echo <<<EOB
<div class=content>
EOB;
// MAIN SWITCH STATEMENT
switch ($MYREQUEST['OB']) {
// -----------------------------------------------
// Host Stats
// -----------------------------------------------
case OB_HOST_STATS:
$mem_size = $mem['num_seg']*$mem['seg_size'];
$mem_avail= $mem['avail_mem'];
$mem_used = $mem_size-$mem_avail;
$seg_size = bsize($mem['seg_size']);
$req_rate = sprintf("%.2f",($cache['num_hits']+$cache['num_misses'])/($time-$cache['start_time']));
$hit_rate = sprintf("%.2f",($cache['num_hits'])/($time-$cache['start_time']));
$miss_rate = sprintf("%.2f",($cache['num_misses'])/($time-$cache['start_time']));
$insert_rate = sprintf("%.2f",($cache['num_inserts'])/($time-$cache['start_time']));
$req_rate_user = sprintf("%.2f",($cache_user['num_hits']+$cache_user['num_misses'])/($time-$cache_user['start_time']));
$hit_rate_user = sprintf("%.2f",($cache_user['num_hits'])/($time-$cache_user['start_time']));
$miss_rate_user = sprintf("%.2f",($cache_user['num_misses'])/($time-$cache_user['start_time']));
$insert_rate_user = sprintf("%.2f",($cache_user['num_inserts'])/($time-$cache_user['start_time']));
$apcversion = phpversion('apc');
$phpversion = phpversion();
$number_files = $cache['num_entries'];
$size_files = bsize($cache['mem_size']);
$number_vars = $cache_user['num_entries'];
$size_vars = bsize($cache_user['mem_size']);
$i=0;
echo <<< EOB
<div class="info div1"><h2>General Cache Information</h2>
<table cellspacing=0><tbody>
<tr class=tr-0><td class=td-0>APC Version</td><td>$apcversion</td></tr>
<tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
EOB;
if(!empty($_SERVER['SERVER_NAME']))
echo "<tr class=tr-0><td class=td-0>APC Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n";
if(!empty($_SERVER['SERVER_SOFTWARE']))
echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n";
echo <<<EOB
<tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size
<br/> ({$cache['memory_type']} memory, {$cache['locking_type']} locking)
</td></tr>
EOB;
echo '<tr class=tr-1><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$cache['start_time']),'</td></tr>';
echo '<tr class=tr-0><td class=td-0>Uptime</td><td>',duration($cache['start_time']),'</td></tr>';
echo '<tr class=tr-1><td class=td-0>File Upload Support</td><td>',$cache['file_upload_progress'],'</td></tr>';
echo <<<EOB
</tbody></table>
</div>
<div class="info div1"><h2>File Cache Information</h2>
<table cellspacing=0><tbody>
<tr class=tr-0><td class=td-0>Cached Files</td><td>$number_files ($size_files)</td></tr>
<tr class=tr-1><td class=td-0>Hits</td><td>{$cache['num_hits']}</td></tr>
<tr class=tr-0><td class=td-0>Misses</td><td>{$cache['num_misses']}</td></tr>
<tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
<tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
<tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
<tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate cache requests/second</td></tr>
<tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['expunges']}</td></tr>
</tbody></table>
</div>
<div class="info div1"><h2>User Cache Information</h2>
<table cellspacing=0><tbody>
<tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr>
<tr class=tr-1><td class=td-0>Hits</td><td>{$cache_user['num_hits']}</td></tr>
<tr class=tr-0><td class=td-0>Misses</td><td>{$cache_user['num_misses']}</td></tr>
<tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr>
<tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr>
<tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr>
<tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr>
<tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache_user['expunges']}</td></tr>
</tbody></table>
</div>
<div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody>
EOB;
$j = 0;
foreach (ini_get_all('apc') as $k => $v) {
echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n";
$j = 1 - $j;
}
if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1)
$mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>";
else
$mem_note = "Memory Usage";
echo <<< EOB
</tbody></table>
</div>
<div class="graph div3"><h2>Host Status Diagrams</h2>
<table cellspacing=0><tbody>
EOB;
$size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
echo <<<EOB
<tr>
<td class=td-0>$mem_note</td>
<td class=td-1>Hits & Misses</td>
</tr>
EOB;
echo
graphics_avail() ?
'<tr>'.
"<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF?IMG=1&$time\"></td>".
"<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF?IMG=2&$time\"></td></tr>\n"
: "",
'<tr>',
'<td class=td-0><span class="green box"> </span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
'<td class=td-1><span class="green box"> </span>Hits: ',$cache['num_hits'].sprintf(" (%.1f%%)",$cache['num_hits']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n",
'</tr>',
'<tr>',
'<td class=td-0><span class="red box"> </span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
'<td class=td-1><span class="red box"> </span>Misses: ',$cache['num_misses'].sprintf(" (%.1f%%)",$cache['num_misses']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n";
echo <<< EOB
</tr>
</tbody></table>
<br/>
<h2>Detailed Memory Usage and Fragmentation</h2>
<table cellspacing=0><tbody>
<tr>
<td class=td-0 colspan=2><br/>
EOB;
// Fragementation: (freeseg - 1) / total_seg
$nseg = $freeseg = $fragsize = $freetotal = 0;
for($i=0; $i<$mem['num_seg']; $i++) {
$ptr = 0;
foreach($mem['block_lists'][$i] as $block) {
if ($block['offset'] != $ptr) {
++$nseg;
}
$ptr = $block['offset'] + $block['size'];
/* Only consider blocks <5M for the fragmentation % */
if($block['size']<(5*1024*1024)) $fragsize+=$block['size'];
$freetotal+=$block['size'];
}
$freeseg += count($mem['block_lists'][$i]);
}
if ($freeseg > 1) {
$frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg);
} else {
$frag = "0%";
}
if (graphics_avail()) {
$size='width='.(2*GRAPH_SIZE+150).' height='.(GRAPH_SIZE+10);
echo <<<EOB
<img alt="" $size src="$PHP_SELF?IMG=3&$time">
EOB;
}
echo <<<EOB
</br>Fragmentation: $frag
</td>
</tr>
EOB;
if(isset($mem['adist'])) {
foreach($mem['adist'] as $i=>$v) {
$cur = pow(2,$i); $nxt = pow(2,$i+1)-1;
if($i==0) $range = "1";
else $range = "$cur - $nxt";
echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n";
}
}
echo <<<EOB
</tbody></table>
</div>
EOB;
break;
// -----------------------------------------------
// User Cache Entries
// -----------------------------------------------
case OB_USER_CACHE:
if (!$AUTHENTICATED) {
echo '<div class="error">You need to login to see the user values here!<br/> <br/>';
put_login_link("Login now!");
echo '</div>';
break;
}
$fieldname='info';
$fieldheading='User Entry Label';
$fieldkey='info';
// -----------------------------------------------
// System Cache Entries
// -----------------------------------------------
case OB_SYS_CACHE:
if (!isset($fieldname))
{
$fieldname='filename';
$fieldheading='Script Filename';
if(ini_get("apc.stat")) $fieldkey='inode';
else $fieldkey='filename';
}
if (!empty($MYREQUEST['SH']))
{
echo <<< EOB
<div class="info"><table cellspacing=0><tbody>
<tr><th>Attribute</th><th>Value</th></tr>
EOB;
$m=0;
foreach($scope_list as $j => $list) {
foreach($cache[$list] as $i => $entry) {
if (md5($entry[$fieldkey])!=$MYREQUEST['SH']) continue;
foreach($entry as $k => $value) {
if (!$AUTHENTICATED) {
// hide all path entries if not logged in
$value=preg_replace('/^.*(\\/|\\\\)/','<i><hidden></i>/',$value);
}
if ($k == "num_hits") {
$value=sprintf("%s (%.2f%%)",$value,$value*100/$cache['num_hits']);
}
if ($k == 'deletion_time') {
if(!$entry['deletion_time']) $value = "None";
}
echo
"<tr class=tr-$m>",
"<td class=td-0>",ucwords(preg_replace("/_/"," ",$k)),"</td>",
"<td class=td-last>",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : htmlspecialchars($value, ENT_QUOTES, 'UTF-8'),"</td>",
"</tr>";
$m=1-$m;
}
if($fieldkey=='info') {
echo "<tr class=tr-$m><td class=td-0>Stored Value</td><td class=td-last><pre>";
$output = var_export(apc_fetch($entry[$fieldkey]),true);
echo htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
echo "</pre></td></tr>\n";
}
break;
}
}
echo <<<EOB
</tbody></table>
</div>
EOB;
break;
}
$cols=6;
echo <<<EOB
<div class=sorting><form>Scope:
<input type=hidden name=OB value={$MYREQUEST['OB']}>
<select name=SCOPE>
EOB;
echo
"<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
"<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
"</select>",
" Sorting: <select name=SORT1>",
"<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Hits</option>",
"<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Size</option>",
"<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">$fieldheading</option>",
"<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Last accessed</option>",
"<option value=M",$MYREQUEST['SORT1']=='M' ? " selected":"",">Last modified</option>",
"<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Created at</option>",
"<option value=D",$MYREQUEST['SORT1']=='D' ? " selected":"",">Deleted at</option>";
if($fieldname=='info') echo
"<option value=D",$MYREQUEST['SORT1']=='T' ? " selected":"",">Timeout</option>";
echo
'</select> ',
'<select name=SORT2>',
'<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
'<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
'</select> ',
'<select name=COUNT onChange="form.submit()">',
'<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
'<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
'<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
'<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
'<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
'<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
'<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
'<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
'</select>',
'<br />',
'Search: <input name=SEARCH value="',$MYREQUEST['SEARCH'],'" type=text size=25/>',
' <input type=submit value="GO!">',
'</form></div>';
if (isset($MYREQUEST['SEARCH'])) {
// Don't use preg_quote because we want the user to be able to specify a
// regular expression subpattern.
$MYREQUEST['SEARCH'] = '/'.str_replace('/', '\\/', $MYREQUEST['SEARCH']).'/i';
if (preg_match($MYREQUEST['SEARCH'], 'test') === false) {
echo '<div class="error">Error: enter a valid regular expression as a search query.</div>';
break;
}
}
echo
'<div class="info"><table cellspacing=0><tbody>',
'<tr>',
'<th>',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'</th>';
if($fieldname=='info') {
$cols+=2;
echo '<th>',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'</th>';
}
echo '<th>',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'</th></tr>';
// builds list with alpha numeric sortable keys
//
$list = array();
foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) {
switch($MYREQUEST['SORT1']) {
case 'A': $k=sprintf('%015d-',$entry['access_time']); break;
case 'H': $k=sprintf('%015d-',$entry['num_hits']); break;
case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break;
case 'M': $k=sprintf('%015d-',$entry['mtime']); break;
case 'C': $k=sprintf('%015d-',$entry['creation_time']); break;
case 'T': $k=sprintf('%015d-',$entry['ttl']); break;
case 'D': $k=sprintf('%015d-',$entry['deletion_time']); break;
case 'S': $k=''; break;
}
if (!$AUTHENTICATED) {
// hide all path entries if not logged in
$list[$k.$entry[$fieldname]]=preg_replace('/^.*(\\/|\\\\)/','*hidden*/',$entry);
} else {
$list[$k.$entry[$fieldname]]=$entry;
}
}
if ($list) {
// sort list
//
switch ($MYREQUEST['SORT2']) {
case "A": krsort($list); break;
case "D": ksort($list); break;
}
// output list
$i=0;
foreach($list as $k => $entry) {
if(!$MYREQUEST['SEARCH'] || preg_match($MYREQUEST['SEARCH'], $entry[$fieldname]) != 0) {
$field_value = htmlentities(strip_tags($entry[$fieldname],''), ENT_QUOTES, 'UTF-8');
echo
'<tr class=tr-',$i%2,'>',
"<td class=td-0><a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&SH=",md5($entry[$fieldkey]),"\">",$field_value,'</a></td>',
'<td class="td-n center">',$entry['num_hits'],'</td>',
'<td class="td-n right">',$entry['mem_size'],'</td>',
'<td class="td-n center">',date(DATE_FORMAT,$entry['access_time']),'</td>',
'<td class="td-n center">',date(DATE_FORMAT,$entry['mtime']),'</td>',
'<td class="td-n center">',date(DATE_FORMAT,$entry['creation_time']),'</td>';
if($fieldname=='info') {
if($entry['ttl'])
echo '<td class="td-n center">'.$entry['ttl'].' seconds</td>';
else
echo '<td class="td-n center">None</td>';
}
if ($entry['deletion_time']) {
echo '<td class="td-last center">', date(DATE_FORMAT,$entry['deletion_time']), '</td>';
} else if ($MYREQUEST['OB'] == OB_USER_CACHE) {
echo '<td class="td-last center">';
echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]';
echo '</td>';
} else {
echo '<td class="td-last center"> </td>';
}
echo '</tr>';
$i++;
if ($i == $MYREQUEST['COUNT'])
break;
}
}
} else {
echo '<tr class=tr-0><td class="center" colspan=',$cols,'><i>No data</i></td></tr>';
}
echo <<< EOB
</tbody></table>
EOB;
if ($list && $i < count($list)) {
echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
}
echo <<< EOB
</div>
EOB;
break;
// -----------------------------------------------
// Per-Directory System Cache Entries
// -----------------------------------------------
case OB_SYS_CACHE_DIR:
if (!$AUTHENTICATED) {
break;
}
echo <<<EOB
<div class=sorting><form>Scope:
<input type=hidden name=OB value={$MYREQUEST['OB']}>
<select name=SCOPE>
EOB;
echo
"<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
"<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
"</select>",
" Sorting: <select name=SORT1>",
"<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Total Hits</option>",
"<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Total Size</option>",
"<option value=T",$MYREQUEST['SORT1']=='T' ? " selected":"",">Number of Files</option>",
"<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">Directory Name</option>",
"<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Avg. Size</option>",
"<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Avg. Hits</option>",
'</select> ',
'<select name=SORT2>',
'<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
'<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
'</select> ',
'<select name=COUNT onChange="form.submit()">',
'<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
'<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
'<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
'<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
'<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
'<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
'<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
'<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
'</select> ',
"Group By Dir Level: <select name=AGGR>",
"<option value='' selected>None</option>";
for ($i = 1; $i < 10; $i++)
echo "<option value=$i",$MYREQUEST['AGGR']==$i ? " selected":"",">$i</option>";
echo '</select>',
' <input type=submit value="GO!">',
'</form></div>',
'<div class="info"><table cellspacing=0><tbody>',
'<tr>',
'<th>',sortheader('S','Directory Name', "&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('T','Number of Files',"&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('H','Total Hits', "&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('Z','Total Size', "&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('C','Avg. Hits', "&OB=".$MYREQUEST['OB']),'</th>',
'<th>',sortheader('A','Avg. Size', "&OB=".$MYREQUEST['OB']),'</th>',
'</tr>';
// builds list with alpha numeric sortable keys
//
$tmp = $list = array();
foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $entry) {
$n = dirname($entry['filename']);
if ($MYREQUEST['AGGR'] > 0) {
$n = preg_replace("!^(/?(?:[^/\\\\]+[/\\\\]){".($MYREQUEST['AGGR']-1)."}[^/\\\\]*).*!", "$1", $n);
}
if (!isset($tmp[$n])) {
$tmp[$n] = array('hits'=>0,'size'=>0,'ents'=>0);
}
$tmp[$n]['hits'] += $entry['num_hits'];
$tmp[$n]['size'] += $entry['mem_size'];
++$tmp[$n]['ents'];
}
foreach ($tmp as $k => $v) {
switch($MYREQUEST['SORT1']) {
case 'A': $kn=sprintf('%015d-',$v['size'] / $v['ents']);break;
case 'T': $kn=sprintf('%015d-',$v['ents']); break;
case 'H': $kn=sprintf('%015d-',$v['hits']); break;
case 'Z': $kn=sprintf('%015d-',$v['size']); break;
case 'C': $kn=sprintf('%015d-',$v['hits'] / $v['ents']);break;
case 'S': $kn = $k; break;
}
$list[$kn.$k] = array($k, $v['ents'], $v['hits'], $v['size']);
}
if ($list) {
// sort list
//
switch ($MYREQUEST['SORT2']) {
case "A": krsort($list); break;
case "D": ksort($list); break;
}
// output list
$i = 0;
foreach($list as $entry) {
echo
'<tr class=tr-',$i%2,'>',
"<td class=td-0>",$entry[0],'</a></td>',
'<td class="td-n center">',$entry[1],'</td>',
'<td class="td-n center">',$entry[2],'</td>',
'<td class="td-n center">',$entry[3],'</td>',
'<td class="td-n center">',round($entry[2] / $entry[1]),'</td>',
'<td class="td-n center">',round($entry[3] / $entry[1]),'</td>',
'</tr>';
if (++$i == $MYREQUEST['COUNT']) break;
}
} else {
echo '<tr class=tr-0><td class="center" colspan=6><i>No data</i></td></tr>';
}
echo <<< EOB
</tbody></table>
EOB;
if ($list && $i < count($list)) {
echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
}
echo <<< EOB
</div>
EOB;
break;
// -----------------------------------------------
// Version check
// -----------------------------------------------
case OB_VERSION_CHECK:
echo <<<EOB
<div class="info"><h2>APC Version Information</h2>
<table cellspacing=0><tbody>
<tr>
<th></th>
</tr>
EOB;
if (defined('PROXY')) {
$ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => True ) ) );
$rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss", False, $ctxt);
} else {
$rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss");
}
if (!$rss) {
echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>';
} else {
$apcversion = phpversion('apc');
preg_match('!<title>APC ([0-9.]+)</title>!', $rss, $match);
echo '<tr class="tr-0 center"><td>';
if (version_compare($apcversion, $match[1], '>=')) {
echo '<div class="ok">You are running the latest version of APC ('.$apcversion.')</div>';
$i = 3;
} else {
echo '<div class="failed">You are running an older version of APC ('.$apcversion.'),
newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APC/'.$match[1].'">
http://pecl.php.net/package/APC/'.$match[1].'</a>
</div>';
$i = -1;
}
echo '</td></tr>';
echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>';
preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match);
next($match[2]); next($match[2]);
while (list(,$v) = each($match[2])) {
list(,$ver) = explode(' ', $v, 2);
if ($i < 0 && version_compare($apcversion, $ver, '>=')) {
break;
} else if (!$i--) {
break;
}
echo "<b><a href=\"http://pecl.php.net/package/APC/$ver\">".htmlspecialchars($v, ENT_QUOTES, 'UTF-8')."</a></b><br><blockquote>";
echo nl2br(htmlspecialchars(current($match[2]), ENT_QUOTES, 'UTF-8'))."</blockquote>";
next($match[2]);
}
echo '</td></tr>';
}
echo <<< EOB
</tbody></table>
</div>
EOB;
break;
}
echo <<< EOB
</div>
EOB;
?>
<!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n"?> -->
<?php /*
</body>
</html>
*/
================================================
FILE: admin/codemirror/codemirror.css
================================================
.CodeMirror {
line-height: 1em;
font-family: monospace;
/* Necessary so the scrollbar can be absolutely positioned within the wrapper on Lion. */
position: relative;
/* This prevents unwanted scrollbars from showing up on the body and wrapper in IE. */
overflow: hidden;
}
.CodeMirror-scroll {
overflow-x: auto;
overflow-y: hidden;
height: 300px;
/* This is needed to prevent an IE[67] bug where the scrolled content
is visible outside of the scrolling box. */
position: relative;
outline: none;
}
/* Vertical scrollbar */
.CodeMirror-scrollbar {
float: right;
overflow-x: hidden;
overflow-y: scroll;
/* This corrects for the 1px gap introduced to the left of the scrollbar
by the rule for .CodeMirror-scrollbar-inner. */
margin-left: -1px;
}
.CodeMirror-scrollbar-inner {
/* This needs to have a nonzero width in order for the scrollbar to appear
in Firefox and IE9. */
width: 1px;
}
.CodeMirror-scrollbar.cm-sb-overlap {
/* Ensure that the scrollbar appears in Lion, and that it overlaps the content
rather than sitting to the right of it. */
position: absolute;
z-index: 1;
float: none;
right: 0;
min-width: 12px;
}
.CodeMirror-scrollbar.cm-sb-nonoverlap {
min-width: 12px;
}
.CodeMirror-scrollbar.cm-sb-ie7 {
min-width: 18px;
}
.CodeMirror-gutter {
position: absolute; left: 0; top: 0;
z-index: 10;
background-color: #f7f7f7;
border-right: 1px solid #eee;
min-width: 2em;
height: 100%;
}
.CodeMirror-gutter-text {
color: #aaa;
text-align: right;
padding: .4em .2em .4em .4em;
white-space: pre !important;
cursor: default;
}
.CodeMirror-lines {
padding: .4em;
white-space: pre;
cursor: text;
}
.CodeMirror-lines * {
/* Necessary for throw-scrolling to decelerate properly on Safari. */
pointer-events: none;
}
.CodeMirror pre {
-moz-border-radius: 0;
-webkit-border-radius: 0;
-o-border-radius: 0;
border-radius: 0;
border-width: 0; margin: 0; padding: 0; background: transparent;
font-family: inherit;
font-size: inherit;
padding: 0; margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;
}
.CodeMirror textarea {
outline: none !important;
}
.CodeMirror pre.CodeMirror-cursor {
z-index: 10;
position: absolute;
visibility: hidden;
border-left: 1px solid black;
border-right: none;
width: 0;
}
.cm-keymap-fat-cursor pre.CodeMirror-cursor {
width: auto;
border: 0;
background: transparent;
background: rgba(0, 200, 0, .4);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
}
/* Kludge to turn off filter in ie9+, which also accepts rgba */
.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
.CodeMirror-focused pre.CodeMirror-cursor {
visibility: visible;
}
div.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* Default theme */
.cm-s-default span.cm-keyword {color: #708;}
.cm-s-default span.cm-atom {color: #219;}
.cm-s-default span.cm-number {color: #164;}
.cm-s-default span.cm-def {color: #00f;}
.cm-s-default span.cm-variable {color: black;}
.cm-s-default span.cm-variable-2 {color: #05a;}
.cm-s-default span.cm-variable-3 {color: #085;}
.cm-s-default span.cm-property {color: black;}
.cm-s-default span.cm-operator {color: black;}
.cm-s-default span.cm-comment {color: #a50;}
.cm-s-default span.cm-string {color: #a11;}
.cm-s-default span.cm-string-2 {color: #f50;}
.cm-s-default span.cm-meta {color: #555;}
.cm-s-default span.cm-error {color: #f00;}
.cm-s-default span.cm-qualifier {color: #555;}
.cm-s-default span.cm-builtin {color: #30a;}
.cm-s-default span.cm-bracket {color: #cc7;}
.cm-s-default span.cm-tag {color: #170;}
.cm-s-default span.cm-attribute {color: #00c;}
.cm-s-default span.cm-header {color: blue;}
.cm-s-default span.cm-quote {color: #090;}
.cm-s-default span.cm-hr {color: #999;}
.cm-s-default span.cm-link {color: #00c;}
span.cm-header, span.cm-strong {font-weight: bold;}
span.cm-em {font-style: italic;}
span.cm-emstrong {font-style: italic; font-weight: bold;}
span.cm-link {text-decoration: underline;}
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
================================================
FILE: admin/codemirror/codemirror.js
================================================
var CodeMirror=function(){"use strict";function e(r,i){function un(e){if(s.onDragEvent&&s.onDragEvent(ln,I(e)))return;U(e)}function fn(e){return e>=0&&e<At.size}function cn(e){return D(At,e)}function hn(e,t){Vt=!0;var n=t-e.height;for(var r=e;r;r=r.parent)r.height+=n}function pn(e){var t={line:0,ch:0};Mn(t,{line:At.size-1,ch:cn(At.size-1).text.length},pt(e),t,t),qt=!0}function dn(e){var t=[];return At.iter(0,At.size,function(e){t.push(e.text)}),t.join(e||"\n")}function vn(e){R.scrollTop!=Bt&&(Bt=St.scrollTop=R.scrollTop,rr([]))}function mn(e){s.fixedGutter&&bt.style.left!=St.scrollLeft+"px"&&(bt.style.left=St.scrollLeft+"px"),St.scrollTop!=Bt&&(Bt=St.scrollTop,R.scrollTop!=Bt&&(R.scrollTop=Bt),rr([])),s.onScroll&&s.onScroll(ln)}function gn(e){function u(t){g&&(St.draggable=!1),jt=!1,l(),c(),Math.abs(e.clientX-t.clientX)+Math.abs(e.clientY-t.clientY)<10&&(q(t),hr(n.line,n.ch,!0),Qn())}function m(e){if(i=="single")fr(n,e);else if(i=="double"){var t=br(e);it(e,d)?fr(t.from,v):fr(d,t.to)}else i=="triple"&&(it(e,d)?fr(v,dr({line:e.line,ch:0})):fr(d,dr({line:e.line+1,ch:0})))}function y(e){var t=Zr(e,!0);if(t&&!rt(t,a)){Mt||An(),a=t,m(t),qt=!1;var n=nr();if(t.line>=n.to||t.line<n.from)f=setTimeout(hi(function(){y(e)}),150)}}function b(e){clearTimeout(f);var t=Zr(e);t&&m(t),q(e),Qn(),qt=!0,w(),l()}ar(X(e,"shiftKey"));for(var t=z(e);t!=xt;t=t.parentNode)if(t.parentNode==Et&&t!=wt)return;for(var t=z(e);t!=xt;t=t.parentNode)if(t.parentNode==yt)return s.onGutterClick&&s.onGutterClick(ln,ct(yt.childNodes,t)+Kt,e),q(e);var n=Zr(e);switch(W(e)){case 3:h&&ei(e);return;case 2:n&&hr(n.line,n.ch,!0),setTimeout(Qn,20),q(e);return}if(!n){z(e)==St&&q(e);return}Mt||An();var r=+(new Date),i="single";if(Ht&&Ht.time>r-400&&rt(Ht.pos,n))i="triple",q(e),setTimeout(Qn,20),wr(n.line);else if(Pt&&Pt.time>r-400&&rt(Pt.pos,n)){i="double",Ht={time:r,pos:n},q(e);var o=br(n);fr(o.from,o.to)}else Pt={time:r,pos:n};var a=n,f;if(s.dragDrop&&K&&!s.readOnly&&!rt(_t.from,_t.to)&&!it(n,_t.from)&&!it(_t.to,n)&&i=="single"){g&&(St.draggable=!0);var l=V(document,"mouseup",hi(u),!0),c=V(St,"drop",hi(u),!0);jt=!0,St.dragDrop&&St.dragDrop();return}q(e),i=="single"&&hr(n.line,n.ch,!0);var d=_t.from,v=_t.to,w=V(document,"mousemove",hi(function(e){clearTimeout(f),q(e),!p&&!W(e)?b(e):y(e)}),!0),l=V(document,"mouseup",hi(b),!0)}function yn(e){for(var t=z(e);t!=xt;t=t.parentNode)if(t.parentNode==yt)return q(e);q(e)}function bn(e){if(s.onDragEvent&&s.onDragEvent(ln,I(e)))return;q(e);var t=Zr(e,!0),n=e.dataTransfer.files;if(!t||s.readOnly)return;if(n&&n.length&&window.FileReader&&window.File){var r=n.length,i=Array(r),o=0,u=function(e,n){var s=new FileReader;s.onload=function(){i[n]=s.result,++o==r&&(t=dr(t),hi(function(){var e=qn(i.join(""),t,t);fr(t,e)})())},s.readAsText(e)};for(var a=0;a<r;++a)u(n[a],a)}else{if(jt&&!it(t,_t.from)&&!it(_t.to,t))return;try{var i=e.dataTransfer.getData("Text");i&&pi(function(){var e=_t.from,n=_t.to;fr(t,t),jt&&qn("",e,n),Rn(i),Qn()})}catch(e){}}}function wn(e){var t=Wn();e.dataTransfer.setData("Text",t);if(h||y||b){var n=ot("img");n.scr="data:image/gif;base64,R0lGODdhAgACAIAAAAAAAP///ywAAAAAAgACAAACAoRRADs=",e.dataTransfer.setDragImage(n,0,0)}}function En(e,t){if(typeof e=="string"){e=u[e];if(!e)return!1}var n=Dt;try{s.readOnly&&(It=!0),t&&(Dt=null),e(ln)}catch(r){if(r!=J)throw r;return!1}finally{Dt=n,It=!1}return!0}function xn(e){function u(){o=!0}var t=f(s.keyMap),n=t.auto;clearTimeout(Sn),n&&!c(e)&&(Sn=setTimeout(function(){f(s.keyMap)==t&&(s.keyMap=n.call?n.call(null,ln):n)},50));var r=vt[X(e,"keyCode")],i=!1;if(r==null||e.altGraphKey)return!1;X(e,"altKey")&&(r="Alt-"+r),X(e,"ctrlKey")&&(r="Ctrl-"+r),X(e,"metaKey")&&(r="Cmd-"+r);var o=!1;return X(e,"shiftKey")?i=l("Shift-"+r,s.extraKeys,s.keyMap,function(e){return En(e,!0)},u)||l(r,s.extraKeys,s.keyMap,function(e){if(typeof e=="string"&&/^go[A-Z]/.test(e))return En(e)},u):i=l(r,s.extraKeys,s.keyMap,En,u),o&&(i=!1),i&&(q(e),ti(),p&&(e.oldKeyCode=e.keyCode,e.keyCode=0)),i}function Tn(e,t){var n=l("'"+t+"'",s.extraKeys,s.keyMap,function(e){return En(e,!0)});return n&&(q(e),ti()),n}function Cn(e){Mt||An(),p&&e.keyCode==27&&(e.returnValue=!1),rn&&Jn()&&(rn=!1);if(s.onKeyEvent&&s.onKeyEvent(ln,I(e)))return;var t=X(e,"keyCode");ar(t==16||X(e,"shiftKey"));var r=xn(e);b&&(Nn=r?t:null,!r&&t==88&&X(e,n?"metaKey":"ctrlKey")&&Rn(""))}function kn(e){rn&&Jn();if(s.onKeyEvent&&s.onKeyEvent(ln,I(e)))return;var t=X(e,"keyCode"),n=X(e,"charCode");if(b&&t==Nn){Nn=null,q(e);return}if((b&&(!e.which||e.which<10)||E)&&xn(e))return;var r=String.fromCharCode(n==null?t:n);s.electricChars&&Lt.electricChars&&s.smartIndent&&!s.readOnly&&Lt.electricChars.indexOf(r)>-1&&setTimeout(hi(function(){Sr(_t.to.line,"smart")}),75);if(Tn(e,r))return;Vn()}function Ln(e){if(s.onKeyEvent&&s.onKeyEvent(ln,I(e)))return;X(e,"keyCode")==16&&(Dt=null)}function An(){if(s.readOnly=="nocursor")return;Mt||(s.onFocus&&s.onFocus(ln),Mt=!0,St.className.search(/\bCodeMirror-focused\b/)==-1&&(St.className+=" CodeMirror-focused"),Xt||Kn(!0)),Xn(),ti()}function On(){Mt&&(s.onBlur&&s.onBlur(ln),Mt=!1,Yt&&hi(function(){Yt&&(Yt(),Yt=null)})(),St.className=St.className.replace(" CodeMirror-focused","")),clearInterval(kt),setTimeout(function(){Mt||(Dt=null)},150)}function Mn(e,t,n,r,i){if(It)return;if(on){var o=[];At.iter(e.line,t.line+1,function(e){o.push(e.text)}),on.addChange(e.line,n.length,o);while(on.done.length>s.undoDepth)on.done.shift()}Hn(e,t,n,r,i)}function _n(e,t){if(!e.length)return;var n=e.pop(),r=[];for(var i=n.length-1;i>=0;i-=1){var s=n[i],o=[],u=s.start+s.added;At.iter(s.start,u,function(e){o.push(e.text)}),r.push({start:s.start,added:s.old.length,old:o});var a={line:s.start+s.old.length-1,ch:lt(o[o.length-1],s.old[s.old.length-1])};Hn({line:s.start,ch:0},{line:u-1,ch:cn(u-1).text.length},s.old,a,a)}qt=!0,t.push(r)}function Dn(){_n(on.done,on.undone)}function Pn(){_n(on.undone,on.done)}function Hn(e,t,n,r,i){function x(e){return e<=Math.min(t.line,t.line+g)?e:e+g}if(It)return;var o=!1,u=Zt.text.length;s.lineWrapping||At.iter(e.line,t.line+1,function(e){if(!e.hidden&&e.text.length==u)return o=!0,!0});if(e.line!=t.line||n.length>1)Vt=!0;var a=t.line-e.line,f=cn(e.line),l=cn(t.line);if(e.ch==0&&t.ch==0&&n[n.length-1]==""){var c=[],h=null;e.line?(h=cn(e.line-1),h.fixMarkEnds(l)):l.fixMarkStarts();for(var p=0,d=n.length-1;p<d;++p)c.push(A.inheritMarks(n[p],h));a&&At.remove(e.line,a,$t),c.length&&At.insert(e.line,c)}else if(f==l)if(n.length==1)f.replace(e.ch,t.ch,n[0]);else{l=f.split(t.ch,n[n.length-1]),f.replace(e.ch,null,n[0]),f.fixMarkEnds(l);var c=[];for(var p=1,d=n.length-1;p<d;++p)c.push(A.inheritMarks(n[p],f));c.push(l),At.insert(e.line+1,c)}else if(n.length==1)f.replace(e.ch,null,n[0]),l.replace(null,t.ch,""),f.append(l),At.remove(e.line+1,a,$t);else{var c=[];f.replace(e.ch,null,n[0]),l.replace(null,t.ch,n[n.length-1]),f.fixMarkEnds(l);for(var p=1,d=n.length-1;p<d;++p)c.push(A.inheritMarks(n[p],f));a>1&&At.remove(e.line+1,a-1,$t),At.insert(e.line+1,c)}if(s.lineWrapping){var v=Math.max(5,St.clientWidth/Qr()-3);At.iter(e.line,e.line+n.length,function(e){if(e.hidden)return;var t=Math.ceil(e.text.length/v)||1;t!=e.height&&hn(e,t)})}else At.iter(e.line,e.line+n.length,function(e){var t=e.text;!e.hidden&&t.length>u&&(Zt=e,u=t.length,tn=!0,o=!1)}),o&&(en=!0);var m=[],g=n.length-a-1;for(var p=0,y=Ot.length;p<y;++p){var b=Ot[p];b<e.line?m.push(b):b>t.line&&m.push(b+g)}var w=e.line+Math.min(n.length,500);oi(e.line,w),m.push(w),Ot=m,ai(100),Ut.push({from:e.line,to:t.line+1,diff:g});var E={from:e,to:t,text:n};if(zt){for(var S=zt;S.next;S=S.next);S.next=E}else zt=E;lr(dr(r),dr(i),x(_t.from.line),x(_t.to.line))}function Bn(){var e=At.height*$r()+2*Gr();return e-1>St.offsetHeight?e:!1}function jn(e){var t=Bn();R.style.display=t?"block":"none",t?(F.style.height=Et.style.minHeight=t+"px",R.style.height=St.clientHeight+"px",e!=null&&(R.scrollTop=St.scrollTop=e)):Et.style.minHeight="",wt.style.top=Jt*$r()+"px"}function Fn(){var e=ot("div",null,"CodeMirror-scrollbar-inner","height: 200px"),t=ot("div",[e],"CodeMirror-scrollbar","position: absolute; left: -9999px; height: 100px;");document.body.appendChild(t);var n=t.offsetWidth<=1;return document.body.removeChild(t),n}function In(){Zt=cn(0),tn=!0;var e=Zt.text.length;At.iter(1,At.size,function(t){var n=t.text;!t.hidden&&n.length>e&&(e=n.length,Zt=t)}),en=!1}function qn(e,t,n){function r(r){if(it(r,t))return r;if(!it(n,r))return i;var s=r.line+e.length-(n.line-t.line)-1,o=r.ch;return r.line==n.line&&(o+=e[e.length-1].length-(n.ch-(n.line==t.line?t.ch:0))),{line:s,ch:o}}t=dr(t),n?n=dr(n):n=t,e=pt(e);var i;return Un(e,t,n,function(e){return i=e,{from:r(_t.from),to:r(_t.to)}}),i}function Rn(e,t){Un(pt(e),_t.from,_t.to,function(e){return t=="end"?{from:e,to:e}:t=="start"?{from:_t.from,to:_t.from}:{from:_t.from,to:e}})}function Un(e,t,n,r){var i=e.length==1?e[0].length+t.ch:e[e.length-1].length,s=r({line:t.line+e.length-1,ch:i});Mn(t,n,e,s.from,s.to)}function zn(e,t,n){var r=e.line,i=t.line;if(r==i)return cn(r).text.slice(e.ch,t.ch);var s=[cn(r).text.slice(e.ch)];return At.iter(r+1,i,function(e){s.push(e.text)}),s.push(cn(i).text.slice(0,t.ch)),s.join(n||"\n")}function Wn(e){return zn(_t.from,_t.to,e)}function Xn(){if(rn)return;Nt.set(s.pollInterval,function(){fi(),Jn(),Mt&&Xn(),li()})}function Vn(){function t(){fi();var n=Jn();!n&&!e?(e=!0,Nt.set(60,t)):(rn=!1,Xn()),li()}var e=!1;rn=!0,Nt.set(20,t)}function Jn(){if(Xt||!Mt||dt(L)||s.readOnly)return!1;var e=L.value;if(e==$n)return!1;Dt=null;var t=0,n=Math.min($n.length,e.length);while(t<n&&$n[t]==e[t])++t;return t<$n.length?_t.from={line:_t.from.line,ch:_t.from.ch-($n.length-t)}:Ft&&rt(_t.from,_t.to)&&(_t.to={line:_t.to.line,ch:Math.min(cn(_t.to.line).text.length,_t.to.ch+(e.length-t))}),Rn(e.slice(t),"end"),e.length>1e3?L.value=$n="":$n=e,!0}function Kn(e){rt(_t.from,_t.to)?e&&($n=L.value=""):($n="",L.value=Wn(),nt(L))}function Qn(){s.readOnly!="nocursor"&&L.focus()}function Gn(){var e=Z.getBoundingClientRect();if(p&&e.top==e.bottom)return;var t=window.innerHeight||Math.max(document.body.offsetHeight,document.documentElement.offsetHeight);(e.top<0||e.bottom>t)&&Yn()}function Yn(){var e=Zn();er(e.x,e.y,e.x,e.yBot)}function Zn(){var e=Rr(_t.inverted?_t.from:_t.to),t=s.lineWrapping?Math.min(e.x,gt.offsetWidth):e.x;return{x:t,y:e.y,yBot:e.yBot}}function er(e,t,n,r){var i=tr(e,t,n,r);i.scrollLeft!=null&&(St.scrollLeft=i.scrollLeft),i.scrollTop!=null&&(R.scrollTop=St.scrollTop=i.scrollTop)}function tr(e,t,n,r){var i=Yr(),o=Gr();t+=o,r+=o,e+=i,n+=i;var u=St.clientHeight,a=R.scrollTop,f={},l=Bn()||Infinity,c=t<o+10,h=r+o>l-10;t<a?f.scrollTop=c?0:Math.max(0,t):r>a+u&&(f.scrollTop=(h?l:r)-u);var p=St.clientWidth,d=St.scrollLeft,v=s.fixedGutter?bt.clientWidth:0,m=e<v+i+10;return e<d+v||m?(m&&(e=0),f.scrollLeft=Math.max(0,e-10-v)):n>p+d-3&&(f.scrollLeft=n+10-p),f}function nr(e){var t=$r(),n=(e!=null?e:R.scrollTop)-Gr(),r=Math.max(0,Math.floor(n/t)),i=Math.ceil((n+St.clientHeight)/t);return{from:H(At,r),to:H(At,i)}}function rr(e,t,n){function d(){var e=Q.firstChild,t=!1;return At.iter(Kt,Qt,function(n){if(!e)return;if(!n.hidden){var r=Math.round(e.offsetHeight/c)||1;n.height!=r&&(hn(n,r),Vt=t=!0)}e=e.nextSibling}),t}if(!St.clientWidth){Kt=Qt=Jt=0;return}var r=nr(n);if(e!==!0&&e.length==0&&r.from>Kt&&r.to<Qt){jn(n);return}var i=Math.max(r.from-100,0),o=Math.min(At.size,r.to+100);Kt<i&&i-Kt<20&&(i=Kt),Qt>o&&Qt-o<20&&(o=Math.min(At.size,Qt));var u=e===!0?[]:ir([{from:Kt,to:Qt,domStart:0}],e),a=0;for(var f=0;f<u.length;++f){var l=u[f];l.from<i&&(l.domStart+=i-l.from,l.from=i),l.to>o&&(l.to=o),l.from>=l.to?u.splice(f--,1):a+=l.to-l.from}if(a==o-i&&i==Kt&&o==Qt){jn(n);return}u.sort(function(e,t){return e.domStart-t.domStart});var c=$r(),h=bt.style.display;Q.style.display="none",sr(i,o,u),Q.style.display=bt.style.display="";var p=i!=Kt||o!=Qt||Gt!=St.clientHeight+c;p&&(Gt=St.clientHeight+c),Kt=i,Qt=o,Jt=B(At,i);if(Q.childNodes.length!=Qt-Kt)throw new Error("BAD PATCH! "+JSON.stringify(u)+" size="+(Qt-Kt)+" nodes="+Q.childNodes.length);if(s.lineWrapping){d();var v=Bn(),m=v?"block":"none";R.style.display!=m&&(R.style.display=m,v&&(F.style.height=v+"px"),d())}return bt.style.display=h,(p||Vt)&&or()&&s.lineWrapping&&d()&&or(),jn(n),ur(),!t&&s.onUpdate&&s.onUpdate(ln),!0}function ir(e,t){for(var n=0,r=t.length||0;n<r;++n){var i=t[n],s=[],o=i.diff||0;for(var u=0,a=e.length;u<a;++u){var f=e[u];i.to<=f.from&&i.diff?s.push({from:f.from+o,to:f.to+o,domStart:f.domStart}):i.to<=f.from||i.from>=f.to?s.push(f):(i.from>f.from&&s.push({from:f.from,to:i.from,domStart:f.domStart}),i.to<f.to&&s.push({from:i.to+o,to:f.to+o,domStart:f.domStart+(i.to-f.from)}))}e=s}return e}function sr(e,t,n){function r(e){var t=e.nextSibling;return e.parentNode.removeChild(e),t}if(!n.length)ut(Q);else{var i=0,s=Q.firstChild,o;for(var u=0;u<n.length;++u){var a=n[u];while(a.domStart>i)s=r(s),i++;for(var f=0,l=a.to-a.from;f<l;++f)s=s.nextSibling,i++}while(s)s=r(s)}var c=n.shift(),s=Q.firstChild,f=e;At.iter(e,t,function(e){c&&c.to==f&&(c=n.shift());if(!c||c.from>f){if(e.hidden)var t=ot("pre");else{var t=e.getElement(Cr);e.className&&(t.className=e.className);if(e.bgClassName){var r=ot("pre","\u00a0",e.bgClassName,"position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2");t=ot("div",[r,t],null,"position: relative")}}Q.insertBefore(t,s)}else s=s.nextSibling;++f})}function or(){if(!s.gutter&&!s.lineNumbers)return;var e=wt.offsetHeight,t=St.clientHeight;bt.style.height=(e-t<2?t:e)+"px";var n=document.createDocumentFragment(),r=Kt,i;At.iter(Kt,Math.max(Qt,Kt+1),function(e){if(e.hidden)n.appendChild(ot("pre"));else{var t=e.gutterMarker,o=s.lineNumbers?s.lineNumberFormatter(r+s.firstLineNumber):null;t&&t.text?o=t.text.replace("%N%",o!=null?o:""):o==null&&(o="\u00a0");var u=n.appendChild(ot("pre",null,t&&t.style));u.innerHTML=o;for(var a=1;a<e.height;++a)u.appendChild(ot("br")),u.appendChild(document.createTextNode("\u00a0"));t||(i=r)}++r}),bt.style.display="none",at(yt,n);if(i!=null&&s.lineNumbers){var o=yt.childNodes[i-Kt],u=String(At.size).length,a=tt(o.firstChild),f="";while(a.length+f.length<u)f+="\u00a0";f&&o.insertBefore(document.createTextNode(f),o.firstChild)}bt.style.display="";var l=Math.abs((parseInt(gt.style.marginLeft)||0)-bt.offsetWidth)>2;return gt.style.marginLeft=bt.offsetWidth+"px",Vt=!1,l}function ur(){var e=rt(_t.from,_t.to),t=Rr(_t.from,!0),n=e?t:Rr(_t.to,!0),r=_t.inverted?t:n,i=$r(),o=et(xt),u=et(Q);O.style.top=Math.max(0,Math.min(St.offsetHeight,r.y+u.top-o.top))+"px",O.style.left=Math.max(0,Math.min(St.offsetWidth,r.x+u.left-o.left))+"px";if(e)Z.style.top=r.y+"px",Z.style.left=(s.lineWrapping?Math.min(r.x,gt.offsetWidth):r.x)+"px",Z.style.display="",Y.style.display="none";else{var a=t.y==n.y,f=document.createDocumentFragment(),l=gt.clientWidth||gt.offsetWidth,c=gt.clientHeight||gt.offsetHeight,h=function(e,t,n,r){var i=m?"width: "+(n?l-n-e:l)+"px":"right: "+n+"px";f.appendChild(ot("div",null,"CodeMirror-selected","position: absolute; left: "+e+"px; top: "+t+"px; "+i+"; height: "+r+"px"))};if(_t.from.ch&&t.y>=0){var p=a?l-n.x:0;h(t.x,t.y,p,i)}var d=Math.max(0,t.y+(_t.from.ch?i:0)),v=Math.min(n.y,c)-d;v>.2*i&&h(0,d,0,v),(!a||!_t.from.ch)&&n.y<c-.5*i&&h(0,n.y,l-n.x,i),at(Y,f),Z.style.display="none",Y.style.display=""}}function ar(e){e?Dt=Dt||(_t.inverted?_t.to:_t.from):Dt=null}function fr(e,t){var n=Dt&&dr(Dt);n&&(it(n,e)?e=n:it(t,n)&&(t=n)),lr(e,t),Rt=!0}function lr(e,t,n,r){sn=null,n==null&&(n=_t.from.line,r=_t.to.line);if(rt(_t.from,e)&&rt(_t.to,t))return;if(it(t,e)){var i=t;t=e,e=i}if(e.line!=n){var o=cr(e,n,_t.from.ch);o?e=o:jr(e.line,!1)}t.line!=r&&(t=cr(t,r,_t.to.ch)),rt(e,t)?_t.inverted=!1:rt(e,_t.to)?_t.inverted=!1:rt(t,_t.from)&&(_t.inverted=!0);if(s.autoClearEmptyLines&&rt(_t.from,_t.to)){var u=_t.inverted?e:t;if(u.line!=_t.from.line&&_t.from.line<At.size){var a=cn(_t.from.line);/^\s+$/.test(a.text)&&setTimeout(hi(function(){if(a.parent&&/^\s+$/.test(a.text)){var e=P(a);qn("",{line:e,ch:0},{line:e,ch:a.text.length})}},10))}}_t.from=e,_t.to=t,Wt=!0}function cr(e,t,n){function r(t){var r=e.line+t,i=t==1?At.size:-1;while(r!=i){var o=cn(r);if(!o.hidden){var u=e.ch;if(s||u>n||u>o.text.length)u=o.text.length;return{line:r,ch:u}}r+=t}}var i=cn(e.line),s=e.ch==i.text.length&&e.ch!=n;return i.hidden?e.line>=t?r(1)||r(-1):r(-1)||r(1):e}function hr(e,t,n){var r=dr({line:e,ch:t||0});(n?fr:lr)(r,r)}function pr(e){return Math.max(0,Math.min(e,At.size-1))}function dr(e){if(e.line<0)return{line:0,ch:0};if(e.line>=At.size)return{line:At.size-1,ch:cn(At.size-1).text.length};var t=e.ch,n=cn(e.line).text.length;return t==null||t>n?{line:e.line,ch:n}:t<0?{line:e.line,ch:0}:e}function vr(e,t){function o(){for(var t=r+e,n=e<0?-1:At.size;t!=n;t+=e){var i=cn(t);if(!i.hidden)return r=t,s=i,!0}}function u(t){if(i==(e<0?0:s.text.length)){if(!!t||!o())return!1;i=e<0?s.text.length:0}else i+=e;return!0}var n=_t.inverted?_t.from:_t.to,r=n.line,i=n.ch,s=cn(r);if(t=="char")u();else if(t=="column")u(!0);else if(t=="word"){var a=!1;for(;;){if(e<0&&!u())break;if(ht(s.text.charAt(i)))a=!0;else if(a){e<0&&(e=1,u());break}if(e>0&&!u())break}}return{line:r,ch:i}}function mr(e,t){var n=e<0?_t.from:_t.to;if(Dt||rt(_t.from,_t.to))n=vr(e,t);hr(n.line,n.ch,!0)}function gr(e,t){rt(_t.from,_t.to)?e<0?qn("",vr(e,t),_t.to):qn("",_t.from,vr(e,t)):qn("",_t.from,_t.to),Rt=!0}function yr(e,t){var n=0,r=Rr(_t.inverted?_t.from:_t.to,!0);sn!=null&&(r.x=sn),t=="page"?n=Math.min(St.clientHeight,window.innerHeight||document.documentElement.clientHeight):t=="line"&&(n=$r());var i=Ur(r.x,r.y+n*e+2);t=="page"&&(R.scrollTop+=Rr(i,!0).y-r.y),hr(i.line,i.ch,!0),sn=r.x}function br(e){var t=cn(e.line).text,n=e.ch,r=e.ch;if(t){e.after===!1||r==t.length?--n:++r;var i=t.charAt(n),s=ht(i)?ht:/\s/.test(i)?function(e){return/\s/.test(e)}:function(e){return!/\s/.test(e)&&!ht(e)};while(n>0&&s(t.charAt(n-1)))--n;while(r<t.length&&s(t.charAt(r)))++r}return{from:{line:e.line,ch:n},to:{line:e.line,ch:r}}}function wr(e){fr({line:e,ch:0},dr({line:e+1,ch:0}))}function Er(e){if(rt(_t.from,_t.to))return Sr(_t.from.line,e);var t=_t.to.line-(_t.to.ch?0:1);for(var n=_t.from.line;n<=t;++n)Sr(n,e)}function Sr(e,t){t||(t="add");if(t=="smart")if(!Lt.indent)t="prev";else var n=si(e);var r=cn(e),i=r.indentation(s.tabSize),o=r.text.match(/^\s*/)[0],u;t=="smart"&&(u=Lt.indent(n,r.text.slice(o.length),r.text),u==J&&(t="prev")),t=="prev"?e?u=cn(e-1).indentation(s.tabSize):u=0:t=="add"?u=i+s.indentUnit:t=="subtract"&&(u=i-s.indentUnit),u=Math.max(0,u);var a=u-i,f="",l=0;if(s.indentWithTabs)for(var c=Math.floor(u/s.tabSize);c;--c)l+=s.tabSize,f+=" ";while(l<u)++l,f+=" ";qn(f,{line:e,ch:0},{line:e,ch:o.length})}function xr(){Lt=e.getMode(s,s.mode),At.iter(0,At.size,function(e){e.stateAfter=null}),Ot=[0],ai()}function Tr(){var e=s.gutter||s.lineNumbers;bt.style.display=e?"":"none",e?Vt=!0:Q.parentNode.style.marginLeft=0}function Nr(e,t){if(s.lineWrapping){xt.className+=" CodeMirror-wrap";var n=St.clientWidth/Qr()-3;At.iter(0,At.size,function(e){if(e.hidden)return;var t=Math.ceil(e.text.length/n)||1;t!=1&&hn(e,t)}),gt.style.minWidth=ft.style.left=""}else xt.className=xt.className.replace(" CodeMirror-wrap",""),In(),At.iter(0,At.size,function(e){e.height!=1&&!e.hidden&&hn(e,1)});Ut.push({from:0,to:At.size})}function Cr(e){var t=s.tabSize-e%s.tabSize,n=nn[t];if(n)return n;for(var r="",i=0;i<t;++i)r+=" ";var o=ot("span",r,"cm-tab");return nn[t]={element:o,width:t}}function kr(){St.className=St.className.replace(/\s*cm-s-\S+/g,"")+s.theme.replace(/(^|\s)\s*/g," cm-s-")}function Lr(){var e=a[s.keyMap].style;xt.className=xt.className.replace(/\s*cm-keymap-\S+/g,"")+(e?" cm-keymap-"+e:"")}function Ar(){this.set=[]}function Or(e,t,n){function i(e,t,n,i){cn(e).addMark(new C(t,n,i,r))}e=dr(e),t=dr(t);var r=new Ar;if(!it(e,t))return r;if(e.line==t.line)i(e.line,e.ch,t.ch,n);else{i(e.line,e.ch,null,n);for(var s=e.line+1,o=t.line;s<o;++s)i(s,null,null,n);i(t.line,null,t.ch,n)}return Ut.push({from:e.line,to:t.line+1}),r}function Mr(e){e=dr(e);var t=new k(e.ch);return cn(e.line).addMark(t),t}function _r(e){e=dr(e);var t=[],n=cn(e.line).marked;if(!n)return t;for(var r=0,i=n.length;r<i;++r){var s=n[r];(s.from==null||s.from<=e.ch)&&(s.to==null||s.to>=e.ch)&&t.push(s.marker||s)}return t}function Dr(e,t,n){return typeof e=="number"&&(e=cn(pr(e))),e.gutterMarker={text:t,style:n},Vt=!0,e}function Pr(e){typeof e=="number"&&(e=cn(pr(e))),e.gutterMarker=null,Vt=!0}function Hr(e,t){var n=e,r=e;return typeof e=="number"?r=cn(pr(e)):n=P(e),n==null?null:t(r,n)?(Ut.push({from:n,to:n+1}),r):null}function Br(e,t,n){return Hr(e,function(e){if(e.className!=t||e.bgClassName!=n)return e.className=t,e.bgClassName=n,!0})}function jr(e,t){return Hr(e,function(e,n){if(e.hidden!=t){e.hidden=t,s.lineWrapping||(t&&e.text.length==Zt.text.length?en=!0:!t&&e.text.length>Zt.text.length&&(Zt=e,en=!1)),hn(e,t?0:1);var r=_t.from.line,i=_t.to.line;if(t&&(r==n||i==n)){var o=r==n?cr({line:r,ch:0},r,0):_t.from,u=i==n?cr({line:i,ch:0},i,0):_t.to;if(!u)return;lr(o,u)}return Vt=!0}})}function Fr(e){if(typeof e=="number"){if(!fn(e))return null;var t=e;e=cn(e);if(!e)return null}else{var t=P(e);if(t==null)return null}var n=e.gutterMarker;return{line:t,handle:e,text:e.text,markerText:n&&n.text,markerClass:n&&n.style,lineClass:e.className,bgClass:e.bgClassName}}function Ir(e,t){function i(e){return qr(n,e).left}if(t<=0)return 0;var n=cn(e),r=n.text,s=0,o=0,u=r.length,a,f=Math.min(u,Math.ceil(t/Qr()));for(;;){var l=i(f);if(!(l<=t&&f<u)){a=l,u=f;break}f=Math.min(u,Math.ceil(f*1.2))}if(t>a)return u;f=Math.floor(u*.8),l=i(f),l<t&&(s=f,o=l);for(;;){if(u-s<=1)return a-t>t-o?s:u;var c=Math.ceil((s+u)/2),h=i(c);h>t?(u=c,a=h):(s=c,o=h)}}function qr(e,t){if(t==0)return{top:0,left:0};var n=s.lineWrapping&&t<e.text.length&&G.test(e.text.slice(t-1,t+1)),r=e.getElement(Cr,t,n);at(mt,r);var i=r.anchor,o=i.offsetTop,u=i.offsetLeft;if(p&&o==0&&u==0){var a=ot("span","x");i.parentNode.insertBefore(a,i.nextSibling),o=a.offsetTop}return{top:o,left:u}}function Rr(e,t){var n,r=$r(),i=r*(B(At,e.line)-(t?Jt:0));if(e.ch==0)n=0;else{var o=qr(cn(e.line),e.ch);n=o.left,s.lineWrapping&&(i+=Math.max(0,o.top))}return{x:n,y:i,yBot:i+r}}function Ur(e,t){function h(e){var t=qr(u,e);if(f){var r=Math.round(t.top/n);return c=r!=l,Math.max(0,t.left+(r-l)*St.clientWidth)}return t.left}if(t<0)return{line:0,ch:0};var n=$r(),r=Qr(),i=Jt+Math.floor(t/n),o=H(At,i);if(o>=At.size)return{line:At.size-1,ch:cn(At.size-1).text.length};var u=cn(o),a=u.text,f=s.lineWrapping,l=f?i-B(At,o):0;if(e<=0&&l==0)return{line:o,ch:0};var c=!1,p=0,d=0,v=a.length,m,g=Math.min(v,Math.ceil((e+l*St.clientWidth*.9)/r));for(;;){var y=h(g);if(!(y<=e&&g<v)){m=y,v=g;break}g=Math.min(v,Math.ceil(g*1.2))}if(e>m)return{line:o,ch:v};g=Math.floor(v*.8),y=h(g),y<e&&(p=g,d=y);for(;;){if(v-p<=1){var b=e-d<m-e;return{line:o,ch:b?p:v,after:b}}var w=Math.ceil((p+v)/2),E=h(w);E>e?(v=w,m=E,c&&(m+=1e3)):(p=w,d=E)}}function zr(e){var t=Rr(e,!0),n=et(gt);return{x:n.left+t.x,y:n.top+t.y,yBot:n.top+t.yBot}}function $r(){if(Vr==null){Vr=ot("pre");for(var e=0;e<49;++e)Vr.appendChild(document.createTextNode("x")),Vr.appendChild(ot("br"));Vr.appendChild(document.createTextNode("x"))}var t=Q.clientHeight;return t==Xr?Wr:(Xr=t,at(mt,Vr.cloneNode(!0)),Wr=mt.firstChild.offsetHeight/50||1,ut(mt),Wr)}function Qr(){if(St.clientWidth==Kr)return Jr;Kr=St.clientWidth;var e=ot("span","x"),t=ot("pre",[e]);return at(mt,t),Jr=e.offsetWidth||10}function Gr(){return gt.offsetTop}function Yr(){return gt.offsetLeft}function Zr(e,t){var n=et(St,!0),r,i;try{r=e.clientX,i=e.clientY}catch(e){return null}if(!t&&(r-n.left>St.clientWidth||i-n.top>St.clientHeight))return null;var s=et(gt,!0);return Ur(r-s.left,i-s.top)}function ei(e){function o(){var e=pt(L.value).join("\n");e!=i&&!s.readOnly&&hi(Rn)(e,"end"),O.style.position="relative",L.style.cssText=r,v&&(R.scrollTop=n),Xt=!1,Kn(!0),Xn()}var t=Zr(e),n=R.scrollTop;if(!t||b)return;(rt(_t.from,_t.to)||it(t,_t.from)||!it(t,_t.to))&&hi(hr)(t.line,t.ch);var r=L.style.cssText;O.style.position="absolute",L.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(e.clientY-5)+"px; left: "+(e.clientX-5)+"px; z-index: 1000; background: white; "+"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",Xt=!0;var i=L.value=Wn();Qn(),nt(L);if(h){U(e);var u=V(window,"mouseup",function(){u(),setTimeout(o,20)},!0)}else setTimeout(o,50)}function ti(){clearInterval(kt);var e=!0;Z.style.visibility="",kt=setInterval(function(){Z.style.visibility=(e=!e)?"":"hidden"},650)}function ri(e){function v(e,t,n){if(!e.text)return;var r=e.styles,i=o?0:e.text.length-1,s;for(var a=o?0:r.length-2,f=o?r.length:-2;a!=f;a+=2*u){var l=r[a];if(r[a+1]!=h){i+=u*l.length;continue}for(var c=o?0:l.length-1,v=o?l.length:-1;c!=v;c+=u,i+=u)if(i>=t&&i<n&&d.test(s=l.charAt(c))){var m=ni[s];if(m.charAt(1)==">"==o)p.push(s);else{if(p.pop()!=m.charAt(0))return{pos:i,match:!1};if(!p.length)return{pos:i,match:!0}}}}}var t=_t.inverted?_t.from:_t.to,n=cn(t.line),r=t.ch-1,i=r>=0&&ni[n.text.charAt(r)]||ni[n.text.charAt(++r)];if(!i)return;var s=i.charAt(0),o=i.charAt(1)==">",u=o?1:-1,a=n.styles;for(var f=r+1,l=0,c=a.length;l<c;l+=2)if((f-=a[l].length)<=0){var h=a[l+1];break}var p=[n.text.charAt(r)],d=/[(){}[\]]/;for(var l=t.line,c=o?Math.min(l+100,At.size):Math.max(-1,l-100);l!=c;l+=u){var n=cn(l),m=l==t.line,g=v(n,m&&o?r+1:0,m&&!o?r:n.text.length);if(g)break}g||(g={pos:null,match:!1});var h=g.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket",y=Or({line:t.line,ch:r},{line:t.line,ch:r+1},h),b=g.pos!=null&&Or({line:l,ch:g.pos},{line:l,ch:g.pos+1},h),w=hi(function(){y.clear(),b&&b.clear()});e?setTimeout(w,800):Yt=w}function ii(e){var t,n;for(var r=e,i=e-40;r>i;--r){if(r==0)return 0;var o=cn(r-1);if(o.stateAfter)return r;var u=o.indentation(s.tabSize);if(n==null||t>u)n=r-1,t=u}return n}function si(e){var t=ii(e),n=t&&cn(t-1).stateAfter;return n?n=x(Lt,n):n=T(Lt),At.iter(t,e,function(e){e.highlight(Lt,n,s.tabSize),e.stateAfter=x(Lt,n)}),t<e&&Ut.push({from:t,to:e}),e<At.size&&!cn(e).stateAfter&&Ot.push(e),n}function oi(e,t){var n=si(e);At.iter(e,t,function(e){e.highlight(Lt,n,s.tabSize),e.stateAfter=x(Lt,n)})}function ui(){var e=+(new Date)+s.workTime,t=Ot.length;while(Ot.length){if(!cn(Kt).stateAfter)var n=Kt;else var n=Ot.pop();if(n>=At.size)continue;var r=ii(n),i=r&&cn(r-1).stateAfter;i?i=x(Lt,i):i=T(Lt);var o=0,u=Lt.compareStates,a=!1,f=r,l=!1;At.iter(f,At.size,function(t){var r=t.stateAfter;if(+(new Date)>e)return Ot.push(f),ai(s.workDelay),a&&Ut.push({from:n,to:f+1}),l=!0;var c=t.highlight(Lt,i,s.tabSize);c&&(a=!0),t.stateAfter=x(Lt,i);var h=null;if(u){var p=r&&u(r,i);p!=J&&(h=!!p)}h==null&&(c!==!1||!r?o=0:++o>3&&(!Lt.indent||Lt.indent(r,"")==Lt.indent(i,""))&&(h=!0));if(h)return!0;++f});if(l)return;a&&Ut.push({from:n,to:f+1})}t&&s.onHighlightComplete&&s.onHighlightComplete(ln)}function ai(e){if(!Ot.length)return;Ct.set(e,hi(ui))}function fi(){qt=Rt=zt=null,Ut=[],Wt=!1,$t=[]}function li(){en&&In();if(tn&&!s.lineWrapping){var e=ft.offsetWidth,t=qr(Zt,Zt.text.length).left;ft.style.left=t+"px",gt.style.minWidth=t+e+"px",tn=!1}var n,r;if(Wt){var i=Zn();n=tr(i.x,i.y,i.x,i.yBot)}if(Ut.length||n&&n.scrollTop!=null)r=rr(Ut,!0,n&&n.scrollTop);r||(Wt&&ur(),Vt&&or()),n&&Yn(),Wt&&(Gn(),ti()),Mt&&!Xt&&(qt===!0||qt!==!1&&Wt)&&Kn(Rt),Wt&&s.matchBrackets&&setTimeout(hi(function(){Yt&&(Yt(),Yt=null),rt(_t.from,_t.to)&&ri(!1)}),20);var o=Wt,u=$t;zt&&s.onChange&&ln&&s.onChange(ln,zt),o&&s.onCursorActivity&&s.onCursorActivity(ln);for(var a=0;a<u.length;++a)u[a](ln);r&&s.onUpdate&&s.onUpdate(ln)}function hi(e){return function(){ci++||fi();try{var t=e.apply(this,arguments)}finally{--ci||li()}return t}}function pi(e){on.startCompound();try{return e()}finally{on.endCompound()}}var s={},w=e.defaults;for(var N in w)w.hasOwnProperty(N)&&(s[N]=(i&&i.hasOwnProperty(N)?i:w)[N]);var L=ot("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em");L.setAttribute("wrap","off"),L.setAttribute("autocorrect","off"),L.setAttribute("autocapitalize","off");var O=ot("div",[L],null,"overflow: hidden; position: relative; width: 3px; height: 0px;"),F=ot("div",null,"CodeMirror-scrollbar-inner"),R=ot("div",[F],"CodeMirror-scrollbar"),Q=ot("div"),Y=ot("div",null,null,"position: relative; z-index: -1"),Z=ot("pre","\u00a0","CodeMirror-cursor"),ft=ot("pre","\u00a0","CodeMirror-cursor","visibility: hidden"),mt=ot("div",null,null,"position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden;"),gt=ot("div",[mt,Z,ft,Y,Q],null,"position: relative; z-index: 0"),yt=ot("div",null,"CodeMirror-gutter-text"),bt=ot("div",[yt],"CodeMirror-gutter"),wt=ot("div",[bt,ot("div",[gt],"CodeMirror-lines")],null,"position: relative"),Et=ot("div",[wt],null,"position: relative"),St=ot("div",[Et],"CodeMirror-scroll");St.setAttribute("tabIndex","-1");var xt=ot("div",[O,R,St],"CodeMirror"+(s.lineWrapping?" CodeMirror-wrap":""));r.appendChild?r.appendChild(xt):r(xt),kr(),Lr(),t&&(L.style.width="0px"),g||(St.draggable=!0),gt.style.outline="none",s.tabindex!=null&&(L.tabIndex=s.tabindex),s.autofocus&&Qn(),!s.gutter&&!s.lineNumbers&&(bt.style.display="none"),E&&(O.style.height="1px",O.style.position="absolute"),S?R.className+=Fn()?" cm-sb-overlap":" cm-sb-nonoverlap":d&&(R.className+=" cm-sb-ie7");try{Qr()}catch(Tt){throw Tt.message.match(/runtime/i)&&(Tt=new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)")),Tt}var Nt=new $,Ct=new $,kt,Lt,At=new _([new M([new A("")])]),Ot,Mt;xr();var _t={from:{line:0,ch:0},to:{line:0,ch:0},inverted:!1},Dt,Pt,Ht,Bt=0,jt,Ft=!1,It=!1,qt,Rt,Ut,zt,Wt,Xt,Vt,$t,Jt=0,Kt=0,Qt=0,Gt=0,Yt,Zt=cn(0),en=!1,tn=!0,nn={},rn=!1,sn=null;hi(function(){pn(s.value||""),qt=!1})();var on=new j;V(St,"mousedown",hi(gn)),V(St,"dblclick",hi(yn)),V(gt,"selectstart",q),h||V(St,"contextmenu",ei),V(St,"scroll",mn),V(R,"scroll",vn),V(R,"mousedown",function(){Mt&&setTimeout(Qn,0)}),V(window,"resize",function(){rr(!0)}),V(L,"keyup",hi(Ln)),V(L,"input",Vn),V(L,"keydown",hi(Cn)),V(L,"keypress",hi(kn)),V(L,"focus",An),V(L,"blur",On),s.dragDrop&&(V(St,"dragstart",wn),V(St,"dragenter",un),V(St,"dragover",un),V(St,"drop",hi(bn))),V(St,"paste",function(){Qn(),Vn()}),V(L,"paste",Vn),V(L,"cut",hi(function(){s.readOnly||Rn("")})),E&&V(Et,"mouseup",function(){document.activeElement==L&&L.blur(),Qn()});var an;try{an=document.activeElement==L}catch(Tt){}an||s.autofocus?setTimeout(An,20):On();var ln=xt.CodeMirror={getValue:dn,setValue:hi(pn),getSelection:Wn,replaceSelection:hi(Rn),focus:function(){window.focus(),Qn(),An(),Vn()},setOption:function(e,t){var n=s[e];s[e]=t,e=="mode"||e=="indentUnit"?xr():e=="readOnly"&&t=="nocursor"?(On(),L.blur()):e=="readOnly"&&!t?Kn(!0):e=="theme"?kr():e=="lineWrapping"&&n!=t?hi(Nr)():e=="tabSize"?rr(!0):e=="keyMap"&&Lr();if(e=="lineNumbers"||e=="gutter"||e=="firstLineNumber"||e=="theme"||e=="lineNumberFormatter")Tr(),rr(!0)},getOption:function(e){return s[e]},undo:hi(Dn),redo:hi(Pn),indentLine:hi(function(e,t){typeof t!="string"&&(t==null?t=s.smartIndent?"smart":"prev":t=t?"add":"subtract"),fn(e)&&Sr(e,t)}),indentSelection:hi(Er),historySize:function(){return{undo:on.done.length,redo:on.undone.length}},clearHistory:function(){on=new j},setHistory:function(e){on=new j,on.done=e.done,on.undone=e.undone},getHistory:function(){return on.time=0,{done:on.done.concat([]),undone:on.undone.concat([])}},matchBrackets:hi(function(){ri(!0)}),getTokenAt:hi(function(e){return e=dr(e),cn(e.line).getTokenAt(Lt,si(e.line),e.ch)}),getStateAfter:function(e){return e=pr(e==null?At.size-1:e),si(e+1)},cursorCoords:function(e,t){return e==null&&(e=_t.inverted),this.charCoords(e?_t.from:_t.to,t)},charCoords:function(e,t){return e=dr(e),t=="local"?Rr(e,!1):t=="div"?Rr(e,!0):zr(e)},coordsChar:function(e){var t=et(gt);return Ur(e.x-t.left,e.y-t.top)},markText:hi(Or),setBookmark:Mr,findMarksAt:_r,setMarker:hi(Dr),clearMarker:hi(Pr),setLineClass:hi(Br),hideLine:hi(function(e){return jr(e,!0)}),showLine:hi(function(e){return jr(e,!1)}),onDeleteLine:function(e,t){if(typeof e=="number"){if(!fn(e))return null;e=cn(e)}return(e.handlers||(e.handlers=[])).push(t),e},lineInfo:Fr,addWidget:function(e,t,n,r,i){e=Rr(dr(e));var s=e.yBot,o=e.x;t.style.position="absolute",Et.appendChild(t);if(r=="over")s=e.y;else if(r=="near"){var u=Math.max(St.offsetHeight,At.height*$r()),a=Math.max(Et.clientWidth,gt.clientWidth)-Yr();e.yBot+t.offsetHeight>u&&e.y>t.offsetHeight&&(s=e.y-t.offsetHeight),o+t.offsetWidth>a&&(o=a-t.offsetWidth)}t.style.top=s+Gr()+"px",t.style.left=t.style.right="",i=="right"?(o=Et.clientWidth-t.offsetWidth,t.style.right="0px"):(i=="left"?o=0:i=="middle"&&(o=(Et.clientWidth-t.offsetWidth)/2),t.style.left=o+Yr()+"px"),n&&er(o,s,o+t.offsetWidth,s+t.offsetHeight)},lineCount:function(){return At.size},clipPos:dr,getCursor:function(e){return e==null&&(e=_t.inverted),st(e?_t.from:_t.to)},somethingSelected:function(){return!rt(_t.from,_t.to)},setCursor:hi(function(e,t,n){t==null&&typeof e.line=="number"?hr(e.line,e.ch,n):hr(e,t,n)}),setSelection:hi(function(e,t,n){(n?fr:lr)(dr(e),dr(t||e))}),getLine:function(e){if(fn(e))return cn(e).text},getLineHandle:function(e){if(fn(e))return cn(e)},setLine:hi(function(e,t){fn(e)&&qn(t,{line:e,ch:0},{line:e,ch:cn(e).text.length})}),removeLine:hi(function(e){fn(e)&&qn("",{line:e,ch:0},dr({line:e+1,ch:0}))}),replaceRange:hi(qn),getRange:function(e,t,n){return zn(dr(e),dr(t),n)},triggerOnKeyDown:hi(Cn),execCommand:function(e){return u[e](ln)},moveH:hi(mr),deleteH:hi(gr),moveV:hi(yr),toggleOverwrite:function(){Ft?(Ft=!1,Z.className=Z.className.replace(" CodeMirror-overwrite","")):(Ft=!0,Z.className+=" CodeMirror-overwrite")},posFromIndex:function(e){var t=0,n;return At.iter(0,At.size,function(r){var i=r.text.length+1;if(i>e)return n=e,!0;e-=i,++t}),dr({line:t,ch:n})},indexFromPos:function(e){if(e.line<0||e.ch<0)return 0;var t=e.ch;return At.iter(0,e.line,function(e){t+=e.text.length+1}),t},scrollTo:function(e,t){e!=null&&(St.scrollLeft=e),t!=null&&(R.scrollTop=St.scrollTop=t),rr([])},getScrollInfo:function(){return{x:St.scrollLeft,y:R.scrollTop,height:R.scrollHeight,width:St.scrollWidth}},setSize:function(e,t){function n(e){return e=String(e),/^\d+$/.test(e)?e+"px":e}e!=null&&(xt.style.width=n(e)),t!=null&&(St.style.height=n(t)),ln.refresh()},operation:function(e){return hi(e)()},compoundChange:function(e){return pi(e)},refresh:function(){rr(!0,null,Bt),R.scrollHeight>Bt&&(R.scrollTop=Bt)},getInputField:function(){return L},getWrapperElement:function(){return xt},getScrollerElement:function(){return St},getGutterElement:function(){return bt}},Sn,Nn=null,$n="";Ar.prototype.clear=hi(function(){var e=Infinity,t=-Infinity;for(var n=0,r=this.set.length;n<r;++n){var i=this.set[n],s=i.marked;if(!s||!i.parent)continue;var o=P(i);e=Math.min(e,o),t=Math.max(t,o);for(var u=0;u<s.length;++u)s[u].marker==this&&s.splice(u--,1)}e!=Infinity&&Ut.push({from:e,to:t+1})}),Ar.prototype.find=function(){var e,t;for(var n=0,r=this.set.length;n<r;++n){var i=this.set[n],s=i.marked;for(var o=0;o<s.length;++o){var u=s[o];if(u.marker==this)if(u.from!=null||u.to!=null){var a=P(i);a!=null&&(u.from!=null&&(e={line:a,ch:u.from}),u.to!=null&&(t={line:a,ch:u.to}))}}}return{from:e,to:t}};var Wr,Xr,Vr,Jr,Kr=0,ni={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},ci=0;for(var di in o)o.propertyIsEnumerable(di)&&!ln.propertyIsEnumerable(di)&&(ln[di]=o[di]);return ln}function f(e){return typeof e=="string"?a[e]:e}function l(e,t,n,r,i){function s(t){t=f(t);var n=t[e];if(n===!1)return i&&i(),!0;if(n!=null&&r(n))return!0;if(t.nofallthrough)return i&&i(),!0;var o=t.fallthrough;if(o==null)return!1;if(Object.prototype.toString.call(o)!="[object Array]")return s(o);for(var u=0,a=o.length;u<a;++u)if(s(o[u]))return!0;return!1}return t&&s(t)?!0:s(n)}function c(e){var t=vt[X(e,"keyCode")];return t=="Ctrl"||t=="Alt"||t=="Shift"||t=="Mod"}function x(e,t){if(t===!0)return t;if(e.copyState)return e.copyState(t);var n={};for(var r in t){var i=t[r];i instanceof Array&&(i=i.concat([])),n[r]=i}return n}function T(e,t,n){return e.startState?e.startState(t,n):!0}function N(e,t){this.pos=this.start=0,this.string=e,this.tabSize=t||8}function C(e,t,n,r){this.from=e,this.to=t,this.style=n,this.marker=r}function k(e){this.from=e,this.to=e,this.line=null}function A(e,t){this.styles=t||[e,null],this.text=e,this.height=1}function O(e,t,n,r){for(var i=0,s=0,o=0;s<t;i+=2){var u=n[i],a=s+u.length;o==0?(a>e&&r.push(u.slice(e-s,Math.min(u.length,t-s)),n[i+1]),a>=e&&(o=1)):o==1&&(a>t?r.push(u.slice(0,t-s),n[i+1]):r.push(u,n[i+1])),s=a}}function M(e){this.lines=e,this.parent=null;for(var t=0,n=e.length,r=0;t<n;++t)e[t].parent=this,r+=e[t].height;this.height=r}function _(e){this.children=e;var t=0,n=0;for(var r=0,i=e.length;r<i;++r){var s=e[r];t+=s.chunkSize(),n+=s.height,s.parent=this}this.size=t,this.height=n,this.parent=null}function D(e,t){while(!e.lines)for(var n=0;;++n){var r=e.children[n],i=r.chunkSize();if(t<i){e=r;break}t-=i}return e.lines[t]}function P(e){if(e.parent==null)return null;var t=e.parent,n=ct(t.lines,e);for(var r=t.parent;r;t=r,r=r.parent)for(var i=0,s=r.children.length;;++i){if(r.children[i]==t)break;n+=r.children[i].chunkSize()}return n}function H(e,t){var n=0;e:do{for(var r=0,i=e.children.length;r<i;++r){var s=e.children[r],o=s.height;if(t<o){e=s;continue e}t-=o,n+=s.chunkSize()}return n}while(!e.lines);for(var r=0,i=e.lines.length;r<i;++r){var u=e.lines[r],a=u.height;if(t<a)break;t-=a}return n+r}function B(e,t){var n=0;e:do{for(var r=0,i=e.children.length;r<i;++r){var s=e.children[r],o=s.chunkSize();if(t<o){e=s;continue e}t-=o,n+=s.height}return n}while(!e.lines);for(var r=0;r<t;++r)n+=e.lines[r].height;return n}function j(){this.time=0,this.done=[],this.undone=[],this.compound=0,this.closed=!1}function F(){U(this)}function I(e){return e.stop||(e.stop=F),e}function q(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function R(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function U(e){q(e),R(e)}function z(e){return e.target||e.srcElement}function W(e){var t=e.which;return t==null&&(e.button&1?t=1:e.button&2?t=3:e.button&4&&(t=2)),n&&e.ctrlKey&&t==1&&(t=3),t}function X(e,t){var n=e.override&&e.override.hasOwnProperty(t);return n?e.override[t]:e[t]}function V(e,t,n,r){if(typeof e.addEventListener=="function"){e.addEventListener(t,n,!1);if(r)return function(){e.removeEventListener(t,n,!1)}}else{var i=function(e){n(e||window.event)};e.attachEvent("on"+t,i);if(r)return function(){e.detachEvent("on"+t,i)}}}function $(){this.id=null}function Y(e,t,n){t==null&&(t=e.search(/[^\s\u00a0]/),t==-1&&(t=e.length));for(var r=0,i=0;r<t;++r)e.charAt(r)==" "?i+=n-i%n:++i;return i}function Z(e){return e.currentStyle?e.currentStyle:window.getComputedStyle(e,null)}function et(e,t){try{var n=e.getBoundingClientRect();n={top:n.top,left:n.left}}catch(r){n={top:0,left:0}}if(!t)if(window.pageYOffset==null){var i=document.documentElement||document.body.parentNode;i.scrollTop==null&&(i=document.body),n.top+=i.scrollTop,n.left+=i.scrollLeft}else n.top+=window.pageYOffset,n.left+=window.pageXOffset;return n}function tt(e){return e.textContent||e.innerText||e.nodeValue||""}function nt(e){t?(e.selectionStart=0,e.selectionEnd=e.value.length):e.select()}function rt(e,t){return e.line==t.line&&e.ch==t.ch}function it(e,t){return e.line<t.line||e.line==t.line&&e.ch<t.ch}function st(e){return{line:e.line,ch:e.ch}}function ot(e,t,n,r){var i=document.createElement(e);n&&(i.className=n),r&&(i.style.cssText=r);if(typeof t=="string")ft(i,t);else if(t)for(var s=0;s<t.length;++s)i.appendChild(t[s]);return i}function ut(e){return e.innerHTML="",e}function at(e,t){ut(e).appendChild(t)}function ft(e,t){v?(e.innerHTML="",e.appendChild(document.createTextNode(t))):e.textContent=t}function lt(e,t){if(!t)return 0;if(!e)return t.length;for(var n=e.length,r=t.length;n>=0&&r>=0;--n,--r)if(e.charAt(n)!=t.charAt(r))break;return r+1}function ct(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length;n<r;++n)if(e[n]==t)return n;return-1}function ht(e){return/\w/.test(e)||e.toUpperCase()!=e.toLowerCase()}e.defaults={value:"",mode:null,theme:"default",indentUnit:2,indentWithTabs:!1,smartIndent:!0,tabSize:4,keyMap:"default",extraKeys:null,electricChars:!0,autoClearEmptyLines:!1,onKeyEvent:null,onDragEvent:null,lineWrapping:!1,lineNumbers:!1,gutter:!1,fixedGutter:!1,firstLineNumber:1,readOnly:!1,dragDrop:!0,onChange:null,onCursorActivity:null,onGutterClick:null,onHighlightComplete:null,onUpdate:null,onFocus:null,onBlur:null,onScroll:null,matchBrackets:!1,workTime:100,workDelay:200,pollInterval:100,undoDepth:40,tabindex:null,autofocus:null,lineNumberFormatter:function(e){return e}};var t=/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent),n=t||/Mac/.test(navigator.platform),r=/Win/.test(navigator.platform),i=e.modes={},s=e.mimeModes={};e.defineMode=function(t,n){!e.defaults.mode&&t!="null"&&(e.defaults.mode=t);if(arguments.length>2){n.dependencies=[];for(var r=2;r<arguments.length;++r)n.dependencies.push(arguments[r])}i[t]=n},e.defineMIME=function(e,t){s[e]=t},e.resolveMode=function(t){if(typeof t=="string"&&s.hasOwnProperty(t))t=s[t];else if(typeof t=="string"&&/^[\w\-]+\/[\w\-]+\+xml$/.test(t))return e.resolveMode("application/xml");return typeof t=="string"?{name:t}:t||{name:"null"}},e.getMode=function(t,n){var n=e.resolveMode(n),r=i[n.name];return r?r(t,n):e.getMode(t,"text/plain")},e.listModes=function(){var e=[];for(var t in i)i.propertyIsEnumerable(t)&&e.push(t);return e},e.listMIMEs=function(){var e=[];for(var t in s)s.propertyIsEnumerable(t)&&e.push({mime:t,mode:s[t]});return e};var o=e.extensions={};e.defineExtension=function(e,t){o[e]=t};var u=e.commands={selectAll:function(e){e.setSelection({line:0,ch:0},{line:e.lineCount()-1})},killLine:function(e){var t=e.getCursor(!0),n=e.getCursor(!1),r=!rt(t,n);!r&&e.getLine(t.line).length==t.ch?e.replaceRange("",t,{line:t.line+1,ch:0}):e.replaceRange("",t,r?n:{line:t.line})},deleteLine:function(e){var t=e.getCursor().line;e.replaceRange("",{line:t,ch:0},{line:t})},undo:function(e){e.undo()},redo:function(e){e.redo()},goDocStart:function(e){e.setCursor(0,0,!0)},goDocEnd:function(e){e.setSelection({line:e.lineCount()-1},null,!0)},goLineStart:function(e){e.setCursor(e.getCursor().line,0,!0)},goLineStartSmart:function(e){var t=e.getCursor(),n=e.getLine(t.line),r=Math.max(0,n.search(/\S/));e.setCursor(t.line,t.ch<=r&&t.ch?0:r,!0)},goLineEnd:function(e){e.setSelection({line:e.getCursor().line},null,!0)},goLineUp:function(e){e.moveV(-1,"line")},goLineDown:function(e){e.moveV(1,"line")},goPageUp:function(e){e.moveV(-1,"page")},goPageDown:function(e){e.moveV(1,"page")},goCharLeft:function(e){e.moveH(-1,"char")},goCharRight:function(e){e.moveH(1,"char")},goColumnLeft:function(e){e.moveH(-1,"column")},goColumnRight:function(e){e.moveH(1,"column")},goWordLeft:function(e){e.moveH(-1,"word")},goWordRight:function(e){e.moveH(1,"word")},delCharLeft:function(e){e.deleteH(-1,"char")},delCharRight:function(e){e.deleteH(1,"char")},delWordLeft:function(e){e.deleteH(-1,"word")},delWordRight:function(e){e.deleteH(1,"word")},indentAuto:function(e){e.indentSelection("smart")},indentMore:function(e){e.indentSelection("add")},indentLess:function(e){e.indentSelection("subtract")},insertTab:function(e){e.replaceSelection(" ","end")},defaultTab:function(e){e.somethingSelected()?e.indentSelection("add"):e.replaceSelection(" ","end")},transposeChars:function(e){var t=e.getCursor(),n=e.getLine(t.line);t.ch>0&&t.ch<n.length-1&&e.replaceRange(n.charAt(t.ch)+n.charAt(t.ch-1),{line:t.line,ch:t.ch-1},{line:t.line,ch:t.ch+1})},newlineAndIndent:function(e){e.replaceSelection("\n","end"),e.indentLine(e.getCursor().line)},toggleOverwrite:function(e){e.toggleOverwrite()}},a=e.keyMap={};a.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharRight",Backspace:"delCharLeft",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite"},a.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Alt-Up":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Down":"goDocEnd","Ctrl-Left":"goWordLeft","Ctrl-Right":"goWordRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delWordLeft","Ctrl-Delete":"delWordRight","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore",fallthrough:"basic"},a.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goWordLeft","Alt-Right":"goWordRight","Cmd-Left":"goLineStart","Cmd-Right":"goLineEnd","Alt-Backspace":"delWordLeft","Ctrl-Alt-Backspace":"delWordRight","Alt-Delete":"delWordRight","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore",fallthrough:["basic","emacsy"]},a["default"]=n?a.macDefault:a.pcDefault,a.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageUp","Shift-Ctrl-V":"goPageDown","Ctrl-D":"delCharRight","Ctrl-H":"delCharLeft","Alt-D":"delWordRight","Alt-Backspace":"delWordLeft","Ctrl-K":"killLine","Ctrl-T":"transposeChars"},e.fromTextArea=function(t,n){function r(){t.value=o.getValue()}n||(n={}),n.value=t.value,!n.tabindex&&t.tabindex&&(n.tabindex=t.tabindex),n.autofocus==null&&t.getAttribute("autofocus")!=null&&(n.autofocus=!0);if(t.form){var i=V(t.form,"submit",r,!0);if(typeof t.form.submit=="function"){var s=t.form.submit;t.form.submit=function u(){r(),t.form.submit=s,t.form.submit(),t.form.submit=u}}}t.style.display="none";var o=e(function(e){t.parentNode.insertBefore(e,t.nextSibling)},n);return o.save=r,o.getTextArea=function(){return t},o.toTextArea=function(){r(),t.parentNode.removeChild(o.getWrapperElement()),t.style.display="",t.form&&(i(),typeof t.form.submit=="function"&&(t.form.submit=s))},o};var h=/gecko\/\d{7}/i.test(navigator.userAgent),p=/MSIE \d/.test(navigator.userAgent),d=/MSIE [1-7]\b/.test(navigator.userAgent),v=/MSIE [1-8]\b/.test(navigator.userAgent),m=p&&document.documentMode==5,g=/WebKit\//.test(navigator.userAgent),y=/Chrome\//.test(navigator.userAgent),b=/Opera\//.test(navigator.userAgent),w=/Apple Computer/.test(navigator.vendor),E=/KHTML\//.test(navigator.userAgent),S=/Mac OS X 10\D([7-9]|\d\d)\D/.test(navigator.userAgent);e.copyState=x,e.startState=T,N.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.pos<this.string.length)return this.string.charAt(this.pos++)},eat:function(e){var t=this.string.charAt(this.pos);if(typeof e=="string")var n=t==e;else var n=t&&(e.test?e.test(t):e(t));if(n)return++this.pos,t},eatWhile:function(e){var t=this.pos;while(this.eat(e));return this.pos>t},eatSpace:function(){var e=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos)))++this.pos;return this.pos>e},skipToEnd:function(){this.pos=this.string.length},skipTo:function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},backUp:function(e){this.pos-=e},column:function(){return Y(this.string,this.start,this.tabSize)},indentation:function(){return Y(this.string,null,this.tabSize)},match:function(e,t,n){if(typeof e!="string"){var i=this.string.slice(this.pos).match(e);return i&&t!==!1&&(this.pos+=i[0].length),i}var r=function(e){return n?e.toLowerCase():e};if(r(this.string).indexOf(r(e),this.pos)==this.pos)return t!==!1&&(this.pos+=e.length),!0},current:function(){return this.string.slice(this.start,this.pos)}},e.StringStream=N,C.prototype={attach:function(e){this.marker.set.push(e)},detach:function(e){var t=ct(this.marker.set,e);t>-1&&this.marker.set.splice(t,1)},split:function(e,t){if(this.to<=e&&this.to!=null)return null;var n=this.from<e||this.from==null?null:this.from-e+t,r=this.to==null?null:this.to-e+t;return new C(n,r,this.style,this.marker)},dup:function(){return new C(null,null,this.style,this.marker)},clipTo:function(e,t,n,r,i){e&&r>this.from&&(r<this.to||this.to==null)?this.from=null:this.from!=null&&this.from>=t&&(this.from=Math.max(r,this.from)+i),n&&(t<this.to||this.to==null)&&(t>this.from||this.from==null)?this.to=null:this.to!=null&&this.to>t&&(this.to=r<this.to?this.to+i:t)},isDead:function(){return this.from!=null&&this.to!=null&&this.from>=this.to},sameSet:function(e){return this.marker==e.marker}},k.prototype={attach:function(e){this.line=e},detach:function(e){this.line==e&&(this.line=null)},split:function(e,t){if(e<this.from)return this.from=this.to=this.from-e+t,this},isDead:function(){return this.from>this.to},clipTo:function(e,t,n,r,i){(e||t<this.from)&&(n||r>this.to)?(this.from=0,this.to=-1):this.from>t&&(this.from=this.to=Math.max(r,this.from)+i)},sameSet:function(e){return!1},find:function(){return!this.line||!this.line.parent?null:{line:P(this.line),ch:this.from}},clear:function(){if(this.line){var e=ct(this.line.marked,this);e!=-1&&this.line.marked.splice(e,1),this.line=null}}};var L=" ";h||p&&!d?L="\u200b":b&&(L=""),A.inheritMarks=function(e,t){var n=new A(e),r=t&&t.marked;if(r)for(var i=0;i<r.length;++i)if(r[i].to==null&&r[i].style){var s=n.marked||(n.marked=[]),o=r[i],u=o.dup();s.push(u),u.attach(n)}return n},A.prototype={replace:function(e,t,n){var r=[],i=this.marked,s=t==null?this.text.length:t;O(0,e,this.styles,r),n&&r.push(n,null),O(s,this.text.length,this.styles,r),this.styles=r,this.text=this.text.slice(0,e)+n+this.text.slice(s),this.stateAfter=null;if(i){var o=n.length-(s-e);for(var u=0;u<i.length;++u){var a=i[u];a.clipTo(e==null,e||0,t==null,s,o),a.isDead()&&(a.detach(this),i.splice(u--,1))}}},split:function(e,t){var n=[t,null],r=this.marked;O(e,this.text.length,this.styles,n);var i=new A(t+this.text.slice(e),n);if(r)for(var s=0;s<r.length;++s){var o=r[s],u=o.split(e,t.length);u&&(i.marked||(i.marked=[]),i.marked.push(u),u.attach(i),u==o&&r.splice(s--,1))}return i},append:function(e){var t=this.text.length,n=e.marked,r=this.marked;this.text+=e.text,O(0,e.text.length,e.styles,this.styles);if(r)for(var i=0;i<r.length;++i)r[i].to==null&&(r[i].to=t);if(n&&n.length){r||(this.marked=r=[]);e:for(var i=0;i<n.length;++i){var s=n[i];if(!s.from)for(var o=0;o<r.length;++o){var u=r[o];if(u.to==t&&u.sameSet(s)){u.to=s.to==null?null:s.to+t,u.isDead()&&(u.detach(this),n.splice(i--,1));continue e}}r.push(s),s.attach(this),s.from+=t,s.to!=null&&(s.to+=t)}}},fixMarkEnds:function(e){var t=this.marked,n=e.marked;if(!t)return;e:for(var r=0;r<t.length;++r){var i=t[r],s=i.to==null;if(s&&n)for(var o=0;o<n.length;++o){var u=n[o];if(!u.sameSet(i)||u.from!=null)continue;if(i.from==this.text.length&&u.to==0){n.splice(o,1),t.splice(r--,1);continue e}s=!1;break}s&&(i.to=this.text.length)}},fixMarkStarts:function(){var e=this.marked;if(!e)return;for(var t=0;t<e.length;++t)e[t].from==null&&(e[t].from=0)},addMark:function(e){e.attach(this),this.marked==null&&(this.marked=[]),this.marked.push(e),this.marked.sort(function(e,t){return(e.from||0)-(t.from||0)})},highlight:function(e,t,n){var r=new N(this.text,n),i=this.styles,s=0,o=!1,u=i[0],a;this.text==""&&e.blankLine&&e.blankLine(t);while(!r.eol()){var f=e.token(r,t),l=this.text.slice(r.start,r.pos);r.start=r.pos,s&&i[s-1]==f?i[s-2]+=l:l&&(!o&&(i[s+1]!=f||s&&i[s-2]!=a)&&(o=!0),i[s++]=l,i[s++]=f,a=u,u=i[s]);if(r.pos>5e3){i[s++]=this.text.slice(r.pos),i[s++]=null;break}}return i.length!=s&&(i.length=s,o=!0),s&&i[s-2]!=a&&(o=!0),o||(i.length<5&&this.text.length<10?null:!1)},getTokenAt:function(e,t,n){var r=this.text,i=new N(r);while(i.pos<n&&!i.eol()){i.start=i.pos;var s=e.token(i,t)}return{start:i.start,end:i.pos,string:i.current(),className:s||null,state:t}},indentation:function(e){return Y(this.text,null,e)},getElement:function(e,t,n){function u(t,n,o){if(!n)return;r&&p&&n.charAt(0)==" "&&(n="\u00a0"+n.slice(1)),r=!1;if(!s.test(n)){i+=n.length;var u=document.createTextNode(n)}else{var u=document.createDocumentFragment(),a=0;for(;;){s.lastIndex=a;var f=s.exec(n),l=f?f.index-a:n.length-a;l&&(u.appendChild(document.createTextNode(n.slice(a,a+l))),i+=l);if(!f)break;a+=l+1;if(f[0]==" "){var c=e(i);u.appendChild(c.element.cloneNode(!0)),i+=c.width}else{var h=ot("span","\u2022","cm-invalidchar");h.title="\\u"+f[0].charCodeAt(0).toString(16),u.appendChild(h),i+=1}}}o?t.appendChild(ot("span",[u],o)):t.appendChild(u)}function m(e){return e?"cm-"+e.replace(/ +/g," cm-"):null}var r=!0,i=0,s=/[\t\u0000-\u0019\u200b\u2028\u2029\uFEFF]/g,o=ot("pre"),a=u;if(t!=null){var f=0,l=o.anchor=ot("span");a=function(e,r,i){var s=r.length;if(t>=f&&t<f+s){t>f&&(u(e,r.slice(0,t-f),i),n&&e.appendChild(ot("wbr"))),e.appendChild(l);var o=t-f;u(l,b?r.slice(o,o+1):r.slice(o),i),b&&u(e,r.slice(o+1),i),t--,f+=s}else f+=s,u(e,r,i),f==t&&f==v?(ft(l,L),e.appendChild(l)):f>t+10&&/\s/.test(r)&&(a=function(){})}}var c=this.styles,h=this.text,d=this.marked,v=h.length;if(!h&&t==null)a(o," ");else if(!d||!d.length)for(var g=0,y=0;y<v;g+=2){var w=c[g],E=c[g+1],S=w.length;y+S>v&&(w=w.slice(0,v-y)),y+=S,a(o,w,m(E))}else{var x=0,g=0,T="",E,N=0,C=d[0].from||0,k=[],A=0,O=function(){var e;while(A<d.length&&((e=d[A]).from==x||e.from==null))e.style!=null&&k.push(e),++A;C=A<d.length?d[A].from:Infinity;for(var t=0;t<k.length;++t){var n=k[t].to;n==null&&(n=Infinity),n==x?k.splice(t--,1):C=Math.min(n,C)}},M=0;while(x<v){C==x&&O();var _=Math.min(v,C);for(;;){if(T){var D=x+T.length,P=E;for(var H=0;H<k.length;++H)P=(P?P+" ":"")+k[H].style;a(o,D>_?T.slice(0,_-x):T,P);if(D>=_){T=T.slice(_-x),x=_;break}x=D}T=c[g++],E=m(c[g++])}}}return o},cleanUp:function(){this.parent=null;if(this.marked)for(var e=0,t=this.marked.length;e<t;++e)this.marked[e].detach(this)}},M.prototype={chunkSize:function(){return this.lines.length},remove:function(e,t,n){for(var r=e,i=e+t;r<i;++r){var s=this.lines[r];this.height-=s.height,s.cleanUp();if(s.handlers)for(var o=0;o<s.handlers.length;++o)n.push(s.handlers[o])}this.lines.splice(e,t)},collapse:function(e){e.splice.apply(e,[e.length,0].concat(this.lines))},insertHeight:function(e,t,n){this.height+=n,this.lines=this.lines.slice(0,e).concat(t).concat(this.lines.slice(e));for(var r=0,i=t.length;r<i;++r)t[r].parent=this},iterN:function(e,t,n){for(var r=e+t;e<r;++e)if(n(this.lines[e]))return!0}},_.prototype={chunkSize:function(){return this.size},remove:function(e,t,n){this.size-=t;for(var r=0;r<this.children.length;++r){var i=this.children[r],s=i.chunkSize();if(e<s){var o=Math.min(t,s-e),u=i.height;i.remove(e,o,n),this.height-=u-i.height,s==o&&(this.children.splice(r--,1),i.parent=null);if((t-=o)==0)break;e=0}else e-=s}if(this.size-t<25){var a=[];this.collapse(a),this.children=[new M(a)],this.children[0].parent=this}},collapse:function(e){for(var t=0,n=this.children.length;t<n;++t)this.children[t].collapse(e)},insert:function(e,t){var n=0;for(var r=0,i=t.length;r<i;++r)n+=t[r].height;this.insertHeight(e,t,n)},insertHeight:function(e,t,n){this.size+=t.length,this.height+=n;for(var r=0,i=this.children.length;r<i;++r){var s=this.children[r],o=s.chunkSize();if(e<=o){s.insertHeight(e,t,n);if(s.lines&&s.lines.length>50){while(s.lines.length>50){var u=s.lines.splice(s.lines.length-25,25),a=new M(u);s.height-=a.height,this.children.splice(r+1,0,a),a.parent=this}this.maybeSpill()}break}e-=o}},maybeSpill:function(){if(this.children.length<=10)return;var e=this;do{var t=e.children.splice(e.children.length-5,5),n=new _(t);if(!e.parent){var r=new _(e.children);r.parent=e,e.children=[r,n],e=r}else{e.size-=n.size,e.height-=n.height;var i=ct(e.parent.children,e);e.parent.children.splice(i+1,0,n)}n.parent=e.parent}while(e.children.length>10);e.parent.maybeSpill()},iter:function(e,t,n){this.iterN(e,t-e,n)},iterN:function(e,t,n){for(var r=0,i=this.children.length;r<i;++r){var s=this.children[r],o=s.chunkSize();if(e<o){var u=Math.min(t,o-e);if(s.iterN(e,u,n))return!0;if((t-=u)==0)break;e=0}else e-=o}}},j.prototype={addChange:function(e,t,n){this.undone.length=0;var r=+(new Date),i=this.done[this.done.length-1],s=i&&i[i.length-1],o=r-this.time;if(this.compound&&i&&!this.closed)i.push({start:e,added:t,old:n});else if(o>400||!s||this.closed||s.start>e+n.length||s.start+s.added<e)this.done.push([{start:e,added:t,old:n}]),this.closed=!1;else{var u=Math.max(0,s.start-e),a=Math.max(0,e+n.length-(s.start+s.added));for(var f=u;f>0;--f)s.old.unshift(n[f-1]);for(var f=a;f>0;--f)s.old.push(n[n.length-f]);u&&(s.start=e),s.added+=t-(n.length-u-a)}this.time=r},startCompound:function(){this.compound++||(this.closed=!0)},endCompound:function(){--this.compound||(this.closed=!0)}},e.e_stop=U,e.e_preventDefault=q,e.e_stopPropagation=R,e.connect=V,$.prototype={set:function(e,t){clearTimeout(this.id),this.id=setTimeout(t,e)}};var J=e.Pass={toString:function(){return"CodeMirror.Pass"}},K=function(){if(v)return!1;var e=ot("div");return"draggable"in e||"dragDrop"in e}(),Q=function(){var e=ot("textarea");return e.value="foo\nbar",e.value.indexOf("\r")>-1?"\r\n":"\n"}(),G=/^$/;h?G=/$'/:w?G=/\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/:y&&(G=/\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/),e.setTextContent=ft;var pt="\n\nb".split(/\n/).length!=3?function(e){var t=0,n=[],r=e.length;while(t<=r){var i=e.indexOf("\n",t);i==-1&&(i=e.length);var s=e.slice(t,e.charAt(i-1)=="\r"?i-1:i),o=s.indexOf("\r");o!=-1?(n.push(s.slice(0,o)),t+=o+1):(n.push(s),t=i+1)}return n}:function(e){return e.split(/\r\n?|\n/)};e.splitLines=pt;var dt=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch(t){return!1}}:function(e){try{var t=e.ownerDocument.selection.createRange()}catch(n){}return!t||t.parentElement()!=e?!1:t.compareEndPoints("StartToEnd",t)!=0};e.defineMode("null",function(){return{token:function(e){e.skipToEnd()}}}),e.defineMIME("text/plain","null");var vt={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",91:"Mod",92:"Mod",93:"Mod",109:"-",107:"=",127:"Delete",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63276:"PageUp",63277:"PageDown",63275:"End",63273:"Home",63234:"Left",63232:"Up",63235:"Right",63233:"Down",63302:"Insert",63272:"Delete"};return e.keyNames=vt,function(){for(var e=0;e<10;e++)vt[e+48]=String(e);for(var e=65;e<=90;e++)vt[e]=String.fromCharCode(e);for(var e=1;e<=12;e++)vt[e+111]=vt[e+63235]="F"+e}(),e}();CodeMirror.defineMode("properties",function(){return{token:function(e,t){var n=e.sol()||t.afterSection,r=e.eol();t.afterSection=!1,n&&(t.nextMultiline?(t.inMultiline=!0,t.nextMultiline=!1):t.position="def"),r&&!t.nextMultiline&&(t.inMultiline=!1,t.position="def");if(n)while(e.eatSpace());var i=e.next();return!n||i!=="#"&&i!=="!"&&i!==";"?n&&i==="["?(t.afterSection=!0,e.skipTo("]"),e.eat("]"),"header"):i==="="||i===":"?(t.position="quote",null):(i==="\\"&&t.position==="quote"&&e.next()!=="u"&&(t.nextMultiline=!0),t.position):(t.position="comment",e.skipToEnd(),"comment")},startState:function(){return{position:"def",nextMultiline:!1,inMultiline:!1,afterSection:!1}}}}),CodeMirror.defineMIME("text/x-properties","properties"),CodeMirror.defineMIME("text/x-ini","properties")
================================================
FILE: admin/codemirror/properties.js
================================================
CodeMirror.defineMode("properties", function() {
return {
token: function(stream, state) {
var sol = stream.sol() || state.afterSection;
var eol = stream.eol();
state.afterSection = false;
if (sol) {
if (state.nextMultiline) {
state.inMultiline = true;
state.nextMultiline = false;
} else {
state.position = "def";
}
}
if (eol && ! state.nextMultiline) {
state.inMultiline = false;
state.position = "def";
}
if (sol) {
while(stream.eatSpace());
}
var ch = stream.next();
if (sol && (ch === "#")) {
state.position = "comment";
stream.skipToEnd();
return "comment";
} else if (sol && ch === "[") {
state.afterSection = true;
stream.skipTo("]"); stream.eat("]");
return "header";
} else if (ch === ":") {
state.position = "quote";
return null;
} else if (ch === "\\" && state.position === "quote") {
if (stream.next() !== "u") { // u = Unicode sequence \u1234
// Multiline value
state.nextMultiline = true;
}
}
return state.position;
},
startState: function() {
return {
position : "def", // Current position, "def", "quote" or "comment"
nextMultiline : false, // Is the next line multiline value
inMultiline : false, // Is the current line a multiline value
afterSection : false // Did we just open a section
};
}
};
});
CodeMirror.defineMIME("text/x-properties", "properties");
CodeMirror.defineMIME("text/x-ini", "properties");
================================================
FILE: admin/edit-pattern.php
================================================
<?php
// Edit site config files for Full-Text RSS
// Author: Keyvan Minoukadeh
// Copyright (c) 2013 Keyvan Minoukadeh
// License: AGPLv3
// Date: 2013-05-09
// More info: http://fivefilters.org/content-only/
// Help: http://help.fivefilters.org
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Usage
// -----
// Access this file in your browser and follow the instructions to update your site config files.
error_reporting(E_ALL ^ E_NOTICE);
ini_set("display_errors", 1);
@set_time_limit(120);
if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][stripslashes($k)] = $v;
$process[] = &$process[$key][stripslashes($k)];
} else {
$process[$key][stripslashes($k)] = stripslashes($v);
}
}
}
unset($process);
}
require_once '../libraries/content-extractor/SiteConfig.php';
////////////////////////////////
// Load config file
////////////////////////////////
$admin_page = 'edit-pattern';
require_once('../config.php');
require_once('require_login.php');
require_once('template.php');
tpl_header('Edit site patterns');
$version = file_get_contents('../site_config/standard/version.txt');
function filter_only_text($filename) {
return (strtolower(substr($filename, -4)) == '.txt');
}
function is_valid_hostname($host) {
return preg_match('!^[a-z0-9_.-]+$!i', $host);
}
/////////////////////////////////
// Process changes
/////////////////////////////////
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// DELETE
if (@$_POST['delete'] != '' && @$_POST['delete_dir'] != '') {
if (is_valid_hostname($_POST['delete'])) {
$delete = $_POST['delete'];
if ($_POST['delete_dir'] == 'standard') {
$delete = '../site_config/standard/'.$delete;
} else {
$delete = '../site_config/custom/'.$delete;
}
if (@unlink($delete)) {
echo 'Deleted <strong>'.$delete.'</strong>';
} else {
echo 'Failed to delete <strong>'.$delete.'</strong>';
}
}
exit;
}
// SAVE
if (@$_POST['save'] != '' && isset($_POST['contents'])) {
if (is_valid_hostname(trim($_POST['save']))) {
$save = strtolower(trim($_POST['save']));
if (@$_POST['save_dir'] == 'standard') {
$savepath = '../site_config/standard/'.$save.'.txt';
} else {
$savepath = '../site_config/custom/'.$save.'.txt';
}
// TODO: check if file exists, if it does, prompt user whether to overwrite
if (file_put_contents($savepath, $_POST['contents']) !== false) {
echo '<p>Saved to <strong>'.$savepath.'</strong></p>';
// check caching
if ($options->caching) {
echo '<p>Note: caching is enabled — you may have to disable caching or delete cache files to see changes.<p>';
}
if ($options->apc && function_exists('apc_delete') && function_exists('apc_cache_info')) {
$_apc_data = apc_cache_info('user');
foreach ($_apc_data['cache_list'] as $_apc_item) {
if (substr($_apc_item['info'], 0, 3) == 'sc.') {
apc_delete($_apc_item['info']);
}
}
echo '<p>Cleared site config cache in APC.</p>';
}
SiteConfig::set_config_path(dirname($savepath));
$sconfig = SiteConfig::build($save, $exact_host_match=true);
if ($sconfig) {
if (!empty($sconfig->test_url)) {
echo '<h4>Test URLs</h4>';
echo '<ul>';
foreach ($sconfig->test_url as $test_url) {
$ftr_test_url = $test_url;
if (strtolower(substr($ftr_test_url, 0, 7)) == 'http://') {
$ftr_test_url = substr($ftr_test_url, 7);
}
$ftr_test_url = '../makefulltextfeed.php?url='.urlencode($ftr_test_url);
echo '<li>';
echo '<a href="'.htmlspecialchars($test_url).'" target="_blank">'.htmlspecialchars($test_url).'</a>';
echo ' | <a href="'.$ftr_test_url.'" target="_blank">Full-Text RSS result</a>';
echo ' | <a href="'.$ftr_test_url.'&debug" target="_blank">Debug</a>';
echo '</li>';
}
echo '</ul>';
} else {
echo '<p>No test URLs found in config, if you supply one we\'ll give you a link to test how Full-Text RSS will extract it</p>';
}
} else {
echo '<p>Could not load/parse config file</p>';
}
} else {
echo 'Failed to save <strong>'.$savepath.'</strong>. Make sure the directory is writable.';
}
}
exit;
}
}
/////////////////////////////////
// Show list of site config files
/////////////////////////////////
if (!isset($_REQUEST['url']) || trim($_REQUEST['url']) == '') {
$sc_files = array_merge(scandir('../site_config/standard/'), scandir('../site_config/custom/'));
$sc_files = array_unique(array_filter($sc_files, 'filter_only_text'));
?>
<p><strong>Note:</strong> This feature is for advanced users familiar with XPath. It allows you to override automatic article extraction and specify what Full-Text RSS should extract from specific domains. If you're uncomfortable writing your own, you can <a href="http://fivefilters.org/content-only/custom_site_patterns.php">request one</a> from us.</p>
<form class="well form-search" action="edit-pattern.php">
<input id="search" type="text" name="url" class="span8" placeholder="Enter a host name or URL, e.g. http://www.example.org/article-123.html">
<button type="submit" class="btn">Search or add</button>
</form>
<?php
echo '<ul style="-webkit-column-count: 3; -moz-column-count: 3; column-count: 3" id="list">';
foreach ($sc_files as $file) {
$file = basename($file, '.txt');
echo '<li><a href="edit-pattern.php?url='.urlencode($file).'">'.htmlspecialchars($file).'</a></li>';
}
echo '</ul>';
// adapted from http://stackoverflow.com/a/11022738/407938 ...
?>
<script>
$('input#search').bind('keyup',function(){
var inputString = $(this).val();
var items = $('ul#list li');
items.hide();
items.each(function(){
var item = $(this).text().toString();
if (item.indexOf(inputString)>=0)
$(this).show();
});
});
</script>
<?php
exit;
}
//////////////////////////////////
// Check if primary or secondary
// folder specified
//////////////////////////////////
$lookin = null;
if (isset($_REQUEST['lookin']) && in_array($_REQUEST['lookin'], array('standard', 'custom'))) {
$lookin = $_REQUEST['lookin'];
}
//////////////////////////////////
// Find file and display
//////////////////////////////////
$hostname = false;
if (is_valid_hostname($_REQUEST['url'])) {
$hostname = $_REQUEST['url'];
} else {
if ($_host = parse_url($_REQUEST['url'], PHP_URL_HOST)) {
if (is_valid_hostname($_host)) {
$hostname = $_host;
}
}
}
if (!$hostname) die('Invalid URL');
$hostname_base = ltrim($hostname, '.');
if (strtolower(substr($hostname, 0, 4)) == 'www.') {
$hostname = substr($hostname, 4);
$hostname_base = $hostname;
}
$check = array(
'../site_config/standard/'.$hostname_base.'.txt',
'../site_config/standard/.'.$hostname_base.'.txt',
'../site_config/custom/'.$hostname_base.'.txt',
'../site_config/custom/.'.$hostname_base.'.txt'
);
$related = array();
$matched = array();
$exact_match = false;
foreach ($check as $filename) {
if (file_exists($filename)) {
$related[$filename] = file_get_contents($filename);
if ($lookin === null || strpos($filename, "/$lookin/") !== false) {
$matched[$filename] = file_get_contents($filename);
if (strpos($filename, "/$hostname") !== false) $exact_match = $filename;
}
}
}
if (empty($matched)) {
$contents = "# No matching files found, you can write yours here\n\n# body: //div[@id='body']\n\n# test_url: http://...";
echo '<p>No matching files found...</p>';
} elseif ($exact_match) {
$contents = $matched[$exact_match];
$file_location = $exact_match;
echo '<p style="position: absolute;">Loaded <strong>'.htmlspecialchars($exact_match).'</strong></p>';
} else {
$contents = end($matched);
$file_location = array_pop(array_keys($matched));
echo '<p style="position: absolute;">Loaded <strong>'.htmlspecialchars($file_location).'</strong></p>';
}
if (isset($file_location)) unset($related[$file_location]);
$save_locations = array(
'custom' => 'custom (recommended)',
'standard' => 'standard'
);
echo '<form method="POST" action="edit-pattern.php">';
echo '<div style="text-align: right; margin-top: 10px; margin-bottom: 5px;"><a href="http://help.fivefilters.org/customer/portal/articles/223153-site-patterns" target="_blank">Need help?</a></div>';
echo '<textarea name="contents" class="span8" style="height: 400px;" id="config">'.htmlspecialchars($contents).'</textarea>';
echo '<div style="margin-top: 8px; margin-bottom: 4px;">';
echo '<label>Save as</label> <input type="text" name="save" value="'.htmlspecialchars($hostname).'" />.txt';
echo '<br />';
echo '<label>In directory</label> ';
echo '<select name="save_dir">';
foreach ($save_locations as $_sl_val => $_sl_display) {
echo "<option value=\"$_sl_val\">$_sl_display</option>";
}
echo '</select>';
echo '</div>';
echo '<input type="submit" class="btn btn-primary" value="Save" /> ';
echo 'or <a href="edit-pattern.php" class="btn" >Cancel and return to listing</a>';
echo '</form>';
// DELETE option
if (!empty($matched)) {
echo '<hr /><h3>Delete file?</h3>';
echo '<p>Delete <strong>'.htmlspecialchars($file_location).'</strong></p>';
echo '<form method="POST" action="edit-pattern.php" onsubmit="return confirm(\'Are you sure?\');">';
echo '<input type="hidden" name="delete" value="'.htmlspecialchars(basename($file_location)).'" />';
echo '<input type="hidden" name="delete_dir" value="'.(strpos($file_location, '/standard/') ? 'standard' : 'custom').'" />';
echo '<input type="submit" value="Delete" class="btn btn-danger" />';
echo '</form>';
}
// TEST URLs
if (!empty($matched)) {
if ($sconfig = SiteConfig::build_from_array(explode("\n", $contents))) {
if (!empty($sconfig->test_url)) {
echo '<hr /><h3>Test URLs</h3>';
echo '<ul>';
foreach ($sconfig->test_url as $test_url) {
$ftr_test_url = $test_url;
if (strtolower(substr($ftr_test_url, 0, 7)) == 'http://') {
$ftr_test_url = substr($ftr_test_url, 7);
}
$ftr_test_url = '../makefulltextfeed.php?url='.urlencode($ftr_test_url);
echo '<li>';
echo '<a href="'.htmlspecialchars($test_url).'" target="_blank">'.htmlspecialchars($test_url).'</a>';
echo ' | <a href="'.$ftr_test_url.'" target="_blank">Full-Text RSS result</a>';
echo ' | <a href="'.$ftr_test_url.'&debug" target="_blank">Debug</a>';
echo '</li>';
}
echo '</ul>';
}
}
}
// RELATED files
if (!empty($related)) {
echo '<hr /><h3>Related files</h3>';
echo '<ul>';
foreach (array_keys($related) as $_m_file) {
preg_match('!/(standard|custom)/(.+?)\.txt$!', $_m_file, $_m);
echo '<li><a href="edit-pattern.php?lookin='.$_m[1].'&url='.urlencode($_m[2]).'">'.htmlspecialchars($_m_file).'</a></li>';
}
echo '</ul>';
}
?>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("config"), {
lineNumbers: true,
theme: 'default',
lineWrapping: true
});
</script>
================================================
FILE: admin/index.php
================================================
<?php
// Admin page for Full-Text RSS
// Author: Keyvan Minoukadeh
// Copyright (c) 2012 Keyvan Minoukadeh
// License: AGPLv3
// Date: 2012-04-29
// More info: http://fivefilters.org/content-only/
// Help: http://help.fivefilters.org
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Usage
// -----
// Access this file in your browser
error_reporting(E_ALL ^ E_NOTICE);
ini_set("display_errors", 1);
@set_time_limit(120);
////////////////////////////////
// Load config file
////////////////////////////////
require_once('../config.php');
require_once('require_login.php');
require_once('template.php');
tpl_header('Admin');
?>
<p>The admin pages are intended to help you manage your copy of Full-Text RSS more easily.</p>
<ul>
<li><a href="update.php">Update patterns</a>: an easy way to keep site config files up to date.</li>
<li><a href="edit-pattern.php">Edit patterns</a>: need to fine-tune extraction for a certain site? Use this tool.</li>
<li><a href="apc.php?OB=3">APC</a>: If APC is enabled, you can use this tool to see what Full-Text RSS caches, and clear the cache if you need to.</li>
</ul>
================================================
FILE: admin/login.php
================================================
<?php
header("X-Robots-Tag: noindex, nofollow", true);
session_start();
require_once(dirname(dirname(__FILE__)).'/config.php');
if (!isset($options->admin_credentials) || $options->admin_credentials['username'] == '' || $options->admin_credentials['password'] == '') {
die('<h2>Admin privileges required</h2><p>This page requires admin privileges but Full-Text RSS has not been configured with admin credentials.</p><p>If you are the administrator, please edit your <tt>custom_config.php</tt> file and enter the credentials in the appropriate section. When you\'ve done that, this page will prompt you for your admin credentials.</p>');
}
$name = @$_POST['username'];
$pass = @$_POST['pass'];
$invalid_login = false;
if ($name || $pass) {
if ($name == $options->admin_credentials['username'] && $pass == $options->admin_credentials['password']) {
// Authentication successful - set session
$_SESSION['auth'] = 1;
if (isset($_POST['redirect']) && preg_match('/^[0-9a-z]+$/', $_POST['redirect'])) {
header('Location: '.$_POST['redirect'].'.php');
} else {
header('Location: index.php');
}
exit;
}
$invalid_login = true;
}
?>
<!DOCTYPE html>
<html>
<head><title>Login</title></head>
<body>
<?php if ($invalid_login) echo '<p><strong>Invalid login, please try again.</strong> If you can\'t remember your admin credentials, open your <tt>custom_config.php</tt> and you\'ll find them in there.</p>'; ?>
<form method="post" action="login.php">
<?php if (isset($_GET['redirect'])) echo '<input type="hidden" name="redirect" value="'.htmlspecialchars($_GET['redirect']).'" />'; ?>
<label>Username: <input type="text" name="username" value="<?php echo @$_POST['username']; ?>" /></label>
<label>Password: <input type="password" name="pass" /></label>
<input type="submit" name="submit" value="Log In" />
</form>
</body>
</html>
================================================
FILE: admin/require_login.php
================================================
<?php
// Require login for admin access
// Author: Keyvan Minoukadeh
// Copyright (c) 2013 Keyvan Minoukadeh
// License: AGPLv3
// Date: 2013-05-09
// More info: http://fivefilters.org/content-only/
// Help: http://help.fivefilters.org
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Usage
// -----
// This file is included on pages which require admin privileges - e.g. updating the software.
// The username is 'admin' by default and the password should be set in the custom_config.php file.
session_start();
require_once(dirname(dirname(__FILE__)).'/config.php');
if (isset($_GET['logout'])) $_SESSION['auth'] = 0;
if (!isset($_SESSION['auth']) || $_SESSION['auth'] != 1) {
if (isset($admin_page)) {
header('Location: login.php?redirect='.$admin_page);
} else {
header('Location: login.php');
}
exit;
}
================================================
FILE: admin/template.php
================================================
<?php
ob_start();
function tpl_header($title='Full-Text RSS Admin Area') {
global $admin_page;
?>
<!DOCTYPE html>
<html>
<head>
<title><?php echo $title; ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="robots" content="noindex, nofollow" />
<link rel="stylesheet" href="../css/bootstrap.min.css" type="text/css" media="screen" />
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script type="text/javascript" src="../js/bootstrap-tooltip.js"></script>
<script type="text/javascript" src="../js/bootstrap-popover.js"></script>
<script type="text/javascript" src="../js/bootstrap-tab.js"></script>
<script type="text/javascript" src="codemirror/codemirror.js"></script>
<script type="text/javascript" src="codemirror/properties.js"></script>
<link rel="stylesheet" href="codemirror/codemirror.css" />
<style>
html, body { background-color: #eee; }
body { margin: 0; line-height: 1.4em; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; }
label, input, select, textarea { font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; }
.actions { padding-left: 220px; }
.popover .inner { width: 200px; }
#main-container { width: 800px; padding-bottom: 60px; }
.page-header { padding-bottom: 0; }
.CodeMirror {border: 1px solid black; font-size:13px}
.cm-def {color: green !important;}
.cm-quote {color: #000 !important;}
.CodeMirror-scroll { height: auto; overflow: visible; }
</style>
</head>
<body>
<div class="container" id="main-container">
<div class="navbar">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="../">Full-Text RSS</a>
<ul class="nav">
<li <?php if (@$admin_page == 'update') echo 'class="active"'; ?>><a href="update.php">Update patterns</a></li>
<li <?php if (@$admin_page == 'edit-pattern') echo 'class="active"'; ?>><a href="edit-pattern.php">Edit patterns</a></li>
<li <?php if (@$admin_page == 'apc') echo 'class="active"'; ?>><a href="apc.php?OB=3">APC</a></li>
<li><a href="index.php?logout">Logout</a></li>
</ul>
</div>
</div>
</div>
<div class="page-header"><h1><?php echo $title; ?></h1></div>
<?php
}
function tpl_footer() {
?>
</div> <!-- close container -->
</body>
</html>
<?php
}
register_shutdown_function('tpl_footer');
================================================
FILE: admin/update.php
================================================
<?php
// Update site config files for Full-Text RSS
// Author: Keyvan Minoukadeh
// Copyright (c) 2013 Keyvan Minoukadeh
// License: AGPLv3
// Date: 2013-05-12
// More info: http://fivefilters.org/content-only/
// Help: http://help.fivefilters.org
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Usage
// -----
// * Access this file in your browser and follow the instructions to update your site config files.
// * See section on automatic updates for a URL you can fetch periodically (e.g. with cron) to update site config files
error_reporting(E_ALL ^ E_NOTICE);
ini_set("display_errors", 1);
@set_time_limit(120);
////////////////////////////////
// Load config file
////////////////////////////////
$admin_page = 'update';
require_once('../config.php');
require_once 'template.php';
tpl_header('Update site patterns');
//////////////////////////////////
// Username and password must be available
//////////////////////////////////
if (!isset($options->admin_credentials) || $options->admin_credentials['username'] == '' || $options->admin_credentials['password'] == '') {
header("X-Robots-Tag: noindex, nofollow", true);
die('<h2>Username and password not set</h2><p>Full-Text RSS has not been configured with admin credentials.</p><p>If you are the administrator, please edit your <tt>custom_config.php</tt> file and enter the credentials in the appropriate section. When you\'ve done that, this page will prompt you for your admin credentials.</p>');
}
$admin_hash = sha1($options->admin_credentials['username'].'+'.$options->admin_credentials['password']);
$_self_host = $_SERVER['HTTP_HOST'];
$_self_path = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
$self_update_url = 'http://'.htmlspecialchars($_self_host.$_self_path).'/update.php?key='.urlencode($admin_hash);
$latest_remote = 'https://codeload.github.com/fivefilters/ftr-site-config/zip/master';
$version = @file_get_contents('../site_config/standard/version.txt');
/////////////////////////////////
// Check for update key
/////////////////////////////////
if (!isset($_REQUEST['key']) || trim($_REQUEST['key']) == '') {
require_once 'require_login.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
header('Location: update.php');
exit;
}
$auto = true;
$no_auto_reasons = array();
if (!class_exists('ZipArchive')) {
$auto = false;
$no_auto_reasons[] = 'zip support (PHP\'s <a href="http://php.net/manual/en/zip.requirements.php">ZipArchive</a> class) is missing';
}
if (!is_writable('../site_config')) {
$auto = false;
$no_auto_reasons[] = 'your <tt>site_config/</tt> folder is not writable - change permissions to 777 and try again.</p>';
}
if (!file_exists('../site_config/standard/version.txt')) {
die('Could not determine current version of your site pattern files (site_config/standard/version.txt). Make sure you\'re using at least version 3.2 of Full-Text RSS.');
}
?>
<p>You have Full-Text RSS <strong><?php echo _FF_FTR_VERSION; ?></strong>
(Site Patterns version: <strong><?php echo (isset($version) ? $version : 'Unknown'); ?></strong>)
</p>
<p>To see if you have the latest versions, <a href="http://fivefilters.org/content-only/latest_version.php?version=<?php echo urlencode(_FF_FTR_VERSION).'&site_config='.urlencode(@$version); ?>">check for updates</a>.</p>
<?php
if ($auto) {
echo '<p>This update tool will attempt to fetch the latest site patterns from our <a href="https://github.com/fivefilters/ftr-site-config/">GitHub repository</a>.</p>';
echo '<p><strong>Important: </strong>if you\'ve modified or added your own config files in the <tt>site_config/standard/</tt> folder, please move them to <tt>site_config/custom/</tt> — the update process will attempt to replace everything in <tt>site_config/standard/</tt> with our updated version.</p>';
echo '<form method="post" action="update.php" class="well">';
echo '<input type="hidden" name="key" value="'.$admin_hash.'" />';
echo '<input type="submit" value="Update site config files" />';
echo '</form>';
echo '<h3>Automatic updates</h3>';
echo '<p>You can schedule automatic updates using something like cron. The URL to call is:</p>';
echo '<p class="well">'.$self_update_url.'</p>';
echo '<p>We recommend you schedule this URL to be fetched once a day. If you do not have access to a scheduling service ';
echo 'you may want to consider one of these online services: <a href="http://www.easycron.com/">Easycron</a>, <a href="https://www.setcronjob.com/">SetCronJob</a>, <a href="http://www.onlinecronjobs.com/">onlinecronjobs.com</a>.</p>';
echo '<p>Note: the key contained in the URL is a hash value generated from your admin credentials. If you change these, the key will also change.</p>';
} else {
echo '<div class="notice">';
echo '<p>We cannot automatically update your site pattern files because:</p>';
echo '<ul>';
foreach ($no_auto_reasons as $reason) {
echo '<li>',$reason,'</li>';
}
echo '</ul>';
echo '<p>You can still manually update by downloading the zip file and replacing everything in your <tt>site_config/standard/</tt> folder with the contents of the zip file.</p>';
echo '</div>';
echo '<p><a href="'.$latest_remote.'">Download site config files (zip)</a></p>';
}
echo '<h3>Help</h3>';
echo '<p>If you have any trouble, please contact us via our <a href="http://help.fivefilters.org">support site</a>.</p>';
exit;
}
//////////////////////////////////
// Check update key valid
//////////////////////////////////
if ($_REQUEST['key'] !== $admin_hash) {
println("Sorry, invalid key supplied.");
exit;
}
//////////////////////////////////
// Check for updates
//////////////////////////////////
//$ff_version = @file_get_contents('http://fivefilters.org/content-only/site_config/standard/version.txt');
$_context = stream_context_create(array('http' => array('user_agent' => 'PHP/5.4')));
$latest_info_json = @file_get_contents('https://api.github.com/repos/fivefilters/ftr-site-config', false, $_context);
if (!$latest_info_json) {
println("Sorry, couldn't get info on latest site config files. Please try again later or contact us.");
exit;
}
$latest_info_json = @json_decode($latest_info_json);
if (!is_object($latest_info_json)) {
println("Sorry, couldn't parse JSON from GitHub. Please try again later or contact us.");
exit;
}
$ff_version = $latest_info_json->updated_at;
if ($version == $ff_version) {
die('Your site config files are up to date! If you have trouble extracting from a particular site, please email us: help@fivefilters.org');
} else {
println("Updated site patterns are available (version $ff_version)...");
}
//////////////////////////////////
// Prepare
//////////////////////////////////
$tmp_latest_local = '../site_config/latest_site_config.zip';
$tmp_latest_local_dir = '../site_config/standard_latest';
$tmp_old_local_dir = '../site_config/standard_old';
if (file_exists($tmp_latest_local)) unlink($tmp_latest_local);
if (file_exists($tmp_latest_local_dir)) {
if (!rrmdir($tmp_latest_local_dir)) {
println("Sorry, couldn't remove old folder from last update");
exit;
}
}
if (file_exists($tmp_old_local_dir)) {
rrmdir($tmp_old_local_dir);
}
$standard_local_dir = '../site_config/standard/';
//@copy($latest_remote, $tmp_latest_local);
//copy() does not appear to fill $http_response_header in certain environments
@file_put_contents($tmp_latest_local, @file_get_contents($latest_remote));
$headers = implode("\n", $http_response_header);
//var_dump($headers); exit;
if (strpos($headers, 'HTTP/1.0 200') === false) {
println("Sorry, something went wrong. Please contact us if the problem persists.");
exit;
}
if (class_exists('ZipArchive') && file_exists($tmp_latest_local)) {
println("Downloaded latest copy of the site pattern files to $tmp_latest_local");
$zip = new ZipArchive;
if ($zip->open($tmp_latest_local) === TRUE) {
$zip->extractTo($tmp_latest_local_dir);
$zip->close();
@unlink($tmp_latest_local);
if (file_exists($tmp_latest_local_dir)) {
println("Unzipped contents to $tmp_latest_local_dir");
if (!file_exists($tmp_latest_local_dir.'/ftr-site-config-master/README.md')) {
println("There was a problem extracting the latest site patterns archive - your current site patterns remain untouched.");
println("Please <a href=\"$latest_remote\">update manually</a>.");
exit;
}
@file_put_contents($tmp_latest_local_dir.'/ftr-site-config-master/version.txt', $ff_version);
if (!file_exists($tmp_latest_local_dir.'/ftr-site-config-master/version.txt')) {
println("There was a problem writing the new version number - your current site patterns remain untouched.");
println("Please <a href=\"$latest_remote\">update manually</a>.");
exit;
}
rename($standard_local_dir, $tmp_old_local_dir);
if (file_exists($tmp_old_local_dir)) println("Renamed $standard_local_dir to $tmp_old_local_dir");
rename($tmp_latest_local_dir."/ftr-site-config-master", $standard_local_dir);
if (file_exists($standard_local_dir)) println("Renamed $tmp_latest_local_dir/ftr-site-config-master to $standard_local_dir");
rmdir($tmp_latest_local_dir);
// clear cached site config files from APC
if ($options->apc && function_exists('apc_delete') && function_exists('apc_cache_info')) {
$_apc_data = apc_cache_info('user');
foreach ($_apc_data['cache_list'] as $_apc_item) {
if (substr($_apc_item['info'], 0, 3) == 'sc.') {
apc_delete($_apc_item['info']);
}
}
println('Cleared site config cache in APC.');
}
// all done!
println("<strong style=\"color: darkgreen;\">All done!</strong> Your old site config files are in $tmp_old_local_dir — these will be removed next time you go through the update process.");
} else {
if (file_exists($tmp_latest_local)) @unlink($tmp_latest_local);
println("Failed to unzip to $tmp_latest_local_dir - your current site patterns remain untouched");
}
} else {
if (file_exists($tmp_latest_local)) @unlink($tmp_latest_local);
println("Failed to extract from $tmp_latest_local - your current site patterns remain untouched");
}
} else {
println("Could not download the latest site config files. Please <a href=\"$latest_remote\">update manually</a> - your current site patterns remain untouched.");
}
function println($txt) {
echo $txt,"<br />\n";
ob_end_flush();
ob_flush();
flush();
}
function rrmdir($dir) {
foreach(glob($dir . '/{*.txt,*.php,.*.txt,.*.php,.gitattributes,.gitignore,ftr-site-config-master,README.md}', GLOB_BRACE|GLOB_NOSORT) as $file) {
if(is_dir($file)) {
rrmdir($file);
} else {
unlink($file);
}
}
return rmdir($dir);
}
================================================
FILE: cache/index.php
================================================
<?php
// this is here to prevent directory listing over the web
?>
================================================
FILE: cache/rss/index.php
================================================
<?php
// this is here to prevent directory listing over the web
?>
================================================
FILE: cache/urls/index.php
================================================
<?php
// this is here to prevent directory listing over the web
?>
================================================
FILE: changelog.txt
================================================
FiveFilters.org: Full-Text RSS
http://fivefilters.org/content-only/
CHANGELOG
------------------------------------
3.2 (2013-05-14)
- A short excerpt from the first few lines of the extracted content can now be included in the output (pass &summary=1 in querystring, see $options->summary in config file for more info)
- Full content can now be excluded from the output (pass &content=0 in querystring, see $options->content in config file for more info)
- Site config files can now be automatically updated from our GitHub repository (URL to call visible in admin area)
- Site config files updated for better extraction
- PHP Readability updated to be more lenient when pruning HTML
- Language detection library updated
- HTML meta refresh redirects now also followed
- APC stats (if APC is available on your server) now visible in admin area
- Bug fix: Duplicate find_string and replace_string values in site config files no longer removed (thanks Fabrizio!)
- Bug fix: MIME type actions now applied when following single page URLs
- Other minor fixes/improvements
3.1 (2013-03-06)
- PHP Readability updated to preserve more images/videos
- Site config files updated for better extraction
- SimplePie updated
- New config option favour_feed_titles and request parameter use_extracted_title to allow extracted titles to be used in generated feed
- Remove image lazy loading (looks for markup used by http://wordpress.org/extend/plugins/lazy-load/)
- <category> elements appearing inside <item> elements are now preserved in generated feed
- <media:thumbnail> elements now preserved
- Allow multiple <media:content> elements (previously only one was preserved)
- Bug fix: No more self-closing iframe elements
- Bug fix: Fixed manifest.yml to prevent error message when deploying to AppFog
- Other minor fixes/improvements
3.0 (2012-09-04)
- Multi-page support - next_page_link now supported in site config (enable/disable with $options->multipage)
- HTML5 parser available - use parser: html5lib in site config, also see $options->allowed_parsers
- Updated site patterns for better extraction
- New global site config to be applied to all sites (global.txt)
- APC caching of site config files to improve performance, if APC available - see $options->apc
- Site config editor in admin/ - easily find, edit, test, and test site config files, or add new ones
- Debug mode to see what's happening behind the scenes - see $options->debug
- Removed deprecated config options: restrict, message_to_prepend_with_key, message_to_append_with_key, error_message_with_key
- Removed extraction with CSS via querystring
- Removed config option: $options->alternative_url
- Bug fix: allow extraction of a single element
- Bug fix: redirect handling improved
- Strip 'http://' prefix when API key is supplied
- Site config merging (custom + standard + fingerprint + global)
- Site config command replace_string(find): replace can now be split over two lines: find_string: find, replace_string: replace
- YouTube and Vimeo URLs now return iframe embed code
- We now look for OpenGraph title and date elements
- Improved extraction from AJAX pages - we now look for AJAX triggers embedded in HTML, per Google spec
- JSONP support - use &format=json&callback=functionName in querystring
- New config option to enable Cross-Origin Resource Sharing (CORS): $option->cors
- New config option to enable XSS filtering, if required: $option->xss_filter
- Zend_Cache updated
- Smart caching - experimental feature to store cache IDs in APC first, and write output to disk on subsequent request (see $options->smart_cache)
- Easier cloud deploy - manifest.yml added for AppFog
- Override most config options with environment variables, e.g. ftr_max_entries: 3
2.9.5 (2012-04-29)
- Language detection using Text_LanguageDetect or PHP-CLD (dc:language field in output and $options->detect_language in config)
- New site patterns added and old ones updated
- Experimental tool for simpler site pattern updates (access admin/ folder)
- Plus other fixes/improvements
2.9.1 (2011-11-02)
- Fix: Character encoding issue affecting some non-English articles (makefulltextfeed.php and SimplePie/Misc.php changed)
2.9 (2011-11-01)
- New site patterns added and old ones updated
- New config option: require_key - restrict access to those with password/key
- New config option: rewrite_url - URL rewrite rules to be applied before HTTP request
- New site config options to extract author(s) and publication date (matches included in feed item as <dc:creator> and <pubDate>)
- New site config option: replace_string([string to find]): [replacement string]
- New site identification method: site fingerprints (HTML fragments linked to site config)
- Update check now also checks for new site patterns
- Effective URL (URL after redirects/rewrites) now included in feed item as <dc:identifier>
- Prevent indexing of generated feeds by search engines
- Enclosure support (enclosures preserved as <media:content> elements)
- Better handling of non-HTML content types
- Sending custom User-Agent HTTP header for matching sites now supported
- CSS extraction deprecated in favour of site patterns (still works, but form field removed and feature may disappear in 3.0)
- Fix: Improved character-encoding detection
- Fix: URL parsing issues for certain URLs (SimplePie updated)
- Fix: Author and other Dublin Core (<dc:..>) elements now appear in JSON output
- Fix: Minor fixes for PHP Readability
- Plus other minor fixes/improvements
2.8 (2011-05-30)
- Tidy no longer stripping HTML5 elements
- JSON output (pass &format=json in querystring)
- New site patterns added and old ones updated
- New site config option to force full-page retrieval on multi-page articles: single_page_link
- User Guide (PDF) now included (although still a work in progress)
- URL placeholders now accepted in message_to_prepend/append config options
- Plus minor fixes...
2.7 (2011-03-21)
- Site patterns for better control over extraction (see site_config/README.txt)
- hNews support (improves content extraction for sites using hNews microformatting)
- Cookie Jar now used to store and sends cookies when following HTTP redirects
- Better handling of certain cases where HTML Tidy fails to clean up properly
- Bug fix: curl_multi_select() timing out in certain environments (fixed in HumbleHttpAgent.php)
- Bug fix: broken HTTP header parsing in some environments (fixed in SimplePie_HumbleHttpAgent.php)
- Bug fix: invalid API URL shown (fixed in index.php)
- Plus other minor fixes...
2.6 (2011-03-02)
- Rewriting of hash-bang (#!) URLs (see http://www.tbray.org/ongoing/When/201x/2011/02/09/Hash-Blecch for an explanation)
- Improved parallel fetching support (HumbleHttpAgent uses curl_multi_* functions if PECL HTTP extension is not present)
- Improved HTTP redirect support (now handled in HumbleHttpAgent, no longer relies on PHP)
- Improved performance for single page (non-feed) requests: (SimplePie connected to HumbleHttpAgent)
- Improved memory use for processing large feeds (HumbleHttpAgent's stored responses cleared as they're retrieved)
- Bug fix: exclude on fail option no longer requires valid key
- Bug fix: workaround for PHP bug http://bugs.php.net/51192 (fixed in makefulltextfeed.php)
- Plus other minor changes...
2.5 (2011-01-08)
- New option: custom extraction pattern (CSS selectors)
- New option: allowed URLs (restrict service to pre-defined feeds/domains)
- New option: exclude items on fail (remove items from feed if content extraction fails)
- Remove 'http://' from URL before form submission (prevents errors on hosts which have overly vigilant security software)
- Allow overriding of index.php with custom_index.php
- config.php now required (override with custom_config.php)
- index.php now uses config.php to determine what to display
- Bug fix: occasional fatal error in IRI::__toString() (IRI updated)
- Bug fix: workaround for PHP bug http://bugs.php.net/51192 (fixed in HumbleHttpAgent.php)
2.2 (2010-10-30)
- Character-encoding detection improved (minor change)
- Rewriting of relative URLs improved (tracks redirect URLs)
- Minor changes to prevent errors in certain hosting environments
- Compatibility test file updated with more tests
2.1 (2010-09-13)
- Better content extraction (using PHP Readability 1.7.1)
- Parallel HTTP requests (using Humble HTTP Agent)
- Auto loading of necessary classes
- Rewriting of relative URLs (using IRI)
- Added compatibility test file (to check if server meets requirements)
- Character-encoding support improved (using SimplePie)
1.5 (2010-05-30)
- Support for PHP 5.3 (thanks Murilo!)
- Character-encoding support improved (favours iconv over mb_convert_encoding)
1.0 (2010-03-05)
- Better support for different character-encodings
- Auto-cleanup of cache files
- Very basic option for load distribution (if you're planning on installing the code on multiple servers)
- Separate config file (see config-sample.php)
================================================
FILE: cleancache.php
================================================
<?php
// Full-Text RSS: Clear Cache
// Author: Keyvan Minoukadeh
// Copyright (c) 2012 Keyvan Minoukadeh
// License: AGPLv3
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Usage
// -----
// Set up your scheduler (e.g. cron) to request this file periodically.
// Note: this file must _not_ be named cleancache.php so please rename it.
// We ask you to do this to prevent others from initiating
// the cache cleanup process. It will not run if it's called cleancache.php.
error_reporting(E_ALL ^ E_NOTICE);
ini_set("display_errors", 1);
@set_time_limit(200);
// check file name
if (basename(__FILE__) == 'cleancache.php') die('cleancache.php must be renamed');
// set include path
set_include_path(realpath(dirname(__FILE__).'/libraries').PATH_SEPARATOR.get_include_path());
// Autoloading of classes allows us to include files only when they're
// needed. If we've got a cached copy, for example, only Zend_Cache is loaded.
function __autoload($class_name) {
static $mapping = array(
'Zend_Cache' => 'Zend/Cache.php'
);
if (isset($mapping[$class_name])) {
//echo "Loading $class_name\n<br />";
require_once $mapping[$class_name];
return true;
} else {
return false;
}
}
require_once dirname(__FILE__).'/config.php';
if (!$options->caching) die('Caching is disabled');
// clean APC cache
if ($options->apc && function_exists('apc_delete')) {
$_apc_data = apc_cache_info('user');
foreach ($_apc_data['cache_list'] as $_apc_item) {
if ($_apc_item['ttl'] > 0 && ($_apc_item['ttl'] + $_apc_item['creation_time'] < time())) {
apc_delete($_apc_item['info']);
}
}
}
// clean rss (non-key) cache
$frontendOptions = array(
'lifetime' => 20*60,
'automatic_serialization' => false,
'write_control' => false,
'automatic_cleaning_factor' => 0,
'ignore_user_abort' => false
);
$backendOptions = array(
'cache_dir' => $options->cache_dir.'/rss/',
'file_locking' => false,
'read_control' => true,
'read_control_type' => 'strlen',
'hashed_directory_level' => $options->cache_directory_level,
'hashed_directory_perm' => 0777,
'cache_file_perm' => 0664,
'file_name_prefix' => 'ff'
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
$cache->clean(Zend_Cache::CLEANING_MODE_OLD);
// clean rss (key) cache
$frontendOptions = array(
'lifetime' => 20*60,
'automatic_serialization' => false,
'write_control' => false,
'automatic_cleaning_factor' => 0,
'ignore_user_abort' => false
);
$backendOptions = array(
'cache_dir' => $options->cache_dir.'/rss-with-key/',
'file_locking' => false,
'read_control' => true,
'read_control_type' => 'strlen',
'hashed_directory_level' => $options->cache_directory_level,
'hashed_directory_perm' => 0777,
'cache_file_perm' => 0664,
'file_name_prefix' => 'ff'
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
$cache->clean(Zend_Cache::CLEANING_MODE_OLD);
// clean rss (urls) cache
$frontendOptions = array(
'lifetime' => 60*60,
'automatic_serialization' => false,
'write_control' => false,
'automatic_cleaning_factor' => 0,
'ignore_user_abort' => false
);
$backendOptions = array(
'cache_dir' => $options->cache_dir.'/urls/',
'file_locking' => false,
'read_control' => true,
'read_control_type' => 'strlen',
'hashed_directory_level' => $options->cache_directory_level,
'hashed_directory_perm' => 0777,
'cache_file_perm' => 0664,
'file_name_prefix' => 'ff'
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
$cache->clean(Zend_Cache::CLEANING_MODE_OLD);
?>
================================================
FILE: config.php
================================================
<?php
/* Full-Text RSS config */
// ......IMPORTANT......................................
// .....................................................
// Please do not change this file (config.php) directly.
// Save a copy as custom_config.php and make your
// changes to that instead. It will automatically
// override anything in config.php. Because config.php
// always gets loaded anyway, you can simply specify
// options you'd like to override in custom_config.php.
// .....................................................
// Create config object
if (!isset($options)) $options = new stdClass();
// Enable service
// ----------------------
// Set this to false if you want to disable the service.
// If set to false, no feed is produced and users will
// be told that the service is disabled.
$options->enabled = true;
// Debug mode
// ----------------------
// Enable or disable debugging. When enabled debugging works by passing
// &debug=1 to the makefulltextfeed.php querystring.
// Valid values:
// true or 'user' (default) - let user decide
// 'admin' - debug works only for logged in admin users
// false - disabled
$options->debug = true;
// Default entries (without access key)
// ----------------------
// The number of feed items to process when no API key is supplied
// and no &max=x value is supplied in the querystring.
$options->default_entries = 5;
// Max entries (without access key)
// ----------------------
// The maximum number of feed items to process when no access key is supplied.
// This limits the user-supplied &max=x value. For example, if the user
// asks for 20 items to be processed (&max=20), if max_entries is set to
// 10, only 10 will be processed.
$options->max_entries = 10;
// Full content
// ----------------------
// By default Full-Text RSS includes the extracted content in the output.
// You can exclude this from the output by passing '&content=0' in the querystring.
//
// Possible values...
// Always include: true
// Never include: false
// Include unless user overrides (&content=0): 'user' (default)
//
// Note: currently this does not disable full content extraction. It simply omits it
// from the output.
$options->content = 'user';
// Excerpts
// ----------------------
// By default Full-Text RSS does not include excerpts in the output.
// You can enable this by passing '&summary=1' in the querystring.
// This will include a plain text excerpt from the extracted content.
//
// Possible values...
// Always include: true (recommended for new users)
// Never include: false
// Don't include unless user overrides (&summary=1): 'user' (default)
//
// Important: if both content and excerpts are requested, the excerpt will be
// placed in the description element and the full content inside content:encoded.
// If excerpts are not requested, the full content will go inside the description element.
//
// Why are we not returning both excerpts and content by default?
// Mainly for backward compatibility.
// Excerpts should appear in the feed item's description element. Previous versions
// of Full-Text RSS did not return excerpts, so the description element was always
// used for the full content (as recommended by the RSS advisory). When returning both,
// we need somewhere else to place the content (content:encoded).
// Having both enabled should not create any problems for news readers, but it may create
// problems for developers upgrading from one of our earlier versions who may now find
// their applications are returning excerpts instead of the full content they were
// expecting. To avoid such surprises for users who are upgrading Full-Text RSS,
// excerpts must be explicitly requested in the querystring by default.
//
// Why not use a different element name for excerpts?
// According to the RSS advisory:
// "Publishers who employ summaries should store the summary in description and
// the full content in content:encoded, ordering description first within the item.
// On items with no summary, the full content should be stored in description."
// See: http://www.rssboard.org/rss-profile#namespace-elements-content-encoded
//
// For more consistent element naming, we recommend new users set this option to true.
// The full content can still be excluded via the querystring, but the element names
// will not change: when $options->summary = true, the description element will always
// be reserved for the excerpt and content:encoded always for full content.
$options->summary = 'user';
// Rewrite relative URLs
// ----------------------
// With this enabled relative URLs found in the extracted content
// block are automatically rewritten as absolute URLs.
$options->rewrite_relative_urls = true;
// Exclude items if extraction fails
// ---------------------------------
// Excludes items from the resulting feed
// if we cannot extract any content from the
// item URL.
// Possible values...
// Enable: true
// Disable: false (default)
// User decides: 'user' (this option will appear on the form)
$options->exclude_items_on_fail = 'user';
// Enable multi-page support
// -------------------------
// If enabled, we will try to follow next page links on multi-page articles.
// Currently this only happens for sites where next_page_link has been defined
// in a site config file.
$options->multipage = true;
// Enable caching
// ----------------------
// Enable this if you'd like to cache results
// for 10 minutes. Cache files are written to disk (in cache/ subfolders
// - which must be writable).
// Initially it's best to keep this disabled to make sure everything works
// as expected. If you have APC enabled, please also see smart_cache in the
// advanced section.
$options->caching = false;
// Cache directory
// ----------------------
// Only used if caching is true
$options->cache_dir = dirname(__FILE__).'/cache';
// Message to prepend (without access key)
// ----------------------
// HTML to insert at the beginning of each feed item when no access key is supplied.
// Substitution tags:
// {url} - Feed item URL
// {effective-url} - Feed item URL after we've followed all redirects
$options->message_to_prepend = '';
// Message to append (without access key)
// ----------------------
// HTML to insert at the end of each feed item when no access key is supplied.
// Substitution tags:
// {url} - Feed item URL
// {effective-url} - Feed item URL after we've followed all redirects
$options->message_to_append = '';
// Error message when content extraction fails (without access key)
// ----------------------
$options->error_message = '[unable to retrieve full-text content]';
// Keep enclosure in feed items
// If enabled, we will try to preserve enclosures if present.
// ----------------------
$options->keep_enclosures = true;
// Detect language
// ---------------
// Should we try and find/guess the language of the article being processed?
// Values will be placed inside the <dc:language> element inside each <item> element
// Possible values:
// * Ignore language: 0
// * Use article/feed metadata (e.g. HTML lang attribute): 1 (default)
// * As above, but guess if not present: 2
// * Always guess: 3
// * User decides: 'user' (value of 0-3 can be passed in querystring: e.g. &l=2)
$options->detect_language = 1;
// Registration key
// ---------------
// The registration key is optional. It is not required to use Full-Text RSS,
// and does not affect the normal operation of Full-Text RSS. It is currently
// only used on admin pages which help you update site patterns with the
// latest version offered by FiveFilters.org. For these admin-related
// tasks to complete, we will require a valid registration key.
// If you would like one, you can purchase the latest version of Full-Text RSS
// at http://fivefilters.org/content-only/
// Your registration key will automatically be sent in the confirmation email.
// Once you have it, simply copy and paste it here.
$options->registration_key = '';
/////////////////////////////////////////////////
/// RESTRICT ACCESS /////////////////////////////
/////////////////////////////////////////////////
// Admin credentials
// ----------------------
// Certain pages/actions, e.g. updating site patterns with our online tool, will require admin credentials.
// To use these pages, enter a password here and you'll be prompted for it when you try to access those pages.
// If no password or username is set, pages requiring admin privelages will be inaccessible.
// The default username is 'admin'.
// If overriding with an environment variable, separate username and password with a colon, e.g.:
// ftr_admin_credentials: admin:my-secret-password
// Example: $options->admin_credentials = array('username'=>'admin', 'password'=>'my-secret-password');
$options->admin_credentials = array('username'=>'admin0', 'password'=>'admin0');
// URLs to allow
// ----------------------
// List of URLs (or parts of a URL) which the service will accept.
// If the list is empty, all URLs (except those specified in the blocked list below)
// will be permitted.
// Empty: array();
// Non-empty example: array('example.com', 'anothersite.org');
$options->allowed_urls = array();
// URLs to block
// ----------------------
// List of URLs (or parts of a URL) which the service will not accept.
// Note: this list is ignored if allowed_urls is not empty
$options->blocked_urls = array();
// Key holder(s) only?
// ----------------------
// Set this to true if you want to restrict access only to
// those with a key (see below to specify key(s)).
// If set to true, no feed is produced unless a valid
// key is provided.
$options->key_required = false;
// Favour item titles in feed
// ----------------------
// By default, when processing feeds, we assume item titles in the feed
// have not been truncated. So after processing web pages, the extracted titles
// are not used in the generated feed. If you prefer to have extracted titles in
// the feed you can either set this to false, in which case we will always favour
// extracted titles. Alternatively, if set to 'user' (default) we'll use the
// extracted title if you pass '&use_extracted_title' in the querystring.
// Possible values:
// * Favour feed titles: true
// * Favour extracted titles: false
// * Favour feed titles with user override: 'user' (default)
// Note: this has no effect when the input URL is to a web page - in these cases
// we always use the extracted title in the generated feed.
$options->favour_feed_titles = 'user';
// Access keys (password protected access)
// ------------------------------------
// NOTE: You do not need an API key from fivefilters.org to run your own
// copy of the code. This is here if you'd like to restrict access to
// _your_ copy.
// Keys let you group users - those with a key and those without - and
// restrict access to the service to those without a key.
// If you want everyone to access the service in the same way, you can
// leave the array below empty and ignore the access key options further down.
// The options further down let you control how the service should behave
// in each mode.
// Note: Explicitly including the index number (1 and 2 in the examples below)
// is highly recommended (when generating feeds, we encode the key and
// refer to it by index number and hash).
$options->api_keys = array();
// Example:
// $options->api_keys[1] = 'secret-key-1';
// $options->api_keys[2] = 'secret-key-2';
// Default entries (with access key)
// ----------------------
// The number of feed items to process when a valid access key is supplied.
$options->default_entries_with_key = 5;
// Max entries (with access key)
// ----------------------
// The maximum number of feed items to process when a valid access key is supplied.
$options->max_entries_with_key = 10;
/////////////////////////////////////////////////
/// ADVANCED OPTIONS ////////////////////////////
/////////////////////////////////////////////////
// Enable XSS filter?
// ----------------------
// We have not enabled this by default because we assume the majority of
// our users do not display the HTML retrieved by Full-Text RSS
// in a web page without further processing. If you subscribe to our generated
// feeds in your news reader application, it should, if it's good software, already
// filter the resulting HTML for XSS attacks, making it redundant for
// Full-Text RSS do the same. Similarly with frameworks/CMS which display
// feed content - the content should be treated like any other user-submitted content.
//
// If you are writing an application yourself which is processing feeds generated by
// Full-Text RSS, you can either filter the HTML yourself to remove potential XSS attacks
// or enable this option. This might be useful if you are processing our generated
// feeds with JavaScript on the client side - although there's client side xss
// filtering available too, e.g. https://code.google.com/p/google-caja/wiki/JsHtmlSanitizer
//
// If enabled, we'll pass retrieved HTML content through htmLawed with
// safe flag on and style attributes denied, see
// http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/htmLawed_README.htm#s3.6
// Note: if enabled this will also remove certain elements you may want to preserve, such as iframes.
//
// Valid values:
// true - enabled, all content will be filtered
// 'user' (default) - user must pass &xss in makefulltextfeed.php querystring to enable
// false - disabled
$options->xss_filter = 'user';
// Allowed parsers
// ----------------------
// Full-Text RSS attempts to use PHP's libxml extension to process HTML.
// While fast, on some sites it may not always produce good results.
// For these sites, you can specify an alternative HTML parser:
// parser: html5lib
// The html5lib parser is bundled with Full-Text RSS.
// see http://code.google.com/p/html5lib/
//
// To disable HTML parsing with html5lib, you can remove it from this list.
// By default we allow both: libxml and html5lib.
$options->allowed_parsers = array('libxml', 'html5lib');
//$options->allowed_parsers = array('libxml'); //disable html5lib - forcing libxml in all cases
// Enable Cross-Origin Resource Sharing (CORS)
// ----------------------
// If enabled we'll send the following HTTP header
// Access-Control-Allow-Origin: *
// see http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
$options->cors = false;
// Use APC user cache?
// ----------------------
// If enabled we will store site config files (when requested
// for the first time) in APC's user cache. Keys prefixed with 'sc.'
// This improves performance by reducing disk access.
// Note: this has no effect if APC is unavailable on your server.
$options->apc = true;
// Smart cache (experimental)
// ----------------------
// With this option enabled we will not cache to disk immediately.
// We will store the cache key in APC and if it's requested again
// we will cache results to disk. Keys prefixed with 'cache.'
// This improves performance by reducing disk access.
// Note: this has no effect if APC is disabled or unavailable on your server,
// or if you have caching disabled.
$options->smart_cache = true;
// Fingerprints
// ----------------------
// key is fingerprint (fragment to find in HTML)
// value is host name to use for site config lookup if fingerprint matches
$options->fingerprints = array(
// Posterous
'<meta name="generator" content="Posterous"' => array('hostname'=>'fingerprint.posterous.com', 'head'=>true),
// Blogger
'<meta content=\'blogger\' name=\'generator\'' => array('hostname'=>'fingerprint.blogspot.com', 'head'=>true),
'<meta name="generator" content="Blogger"' => array('hostname'=>'fingerprint.blogspot.com', 'head'=>true),
// WordPress (hosted)
// '<meta name="generator" content="WordPress.com"' => array('hostname'=>'fingerprint.wordpress.com', 'head'=>true),
// WordPress (self-hosted and hosted)
'<meta name="generator" content="WordPress' => array('hostname'=>'fingerprint.wordpress.com', 'head'=>true)
);
// User Agent strings - mapping domain names
// ----------------------
// e.g. $options->user_agents = array('example.org' => 'PHP/5.2');
$options->user_agents = array( 'lifehacker.com' => 'PHP/5.2',
'gawker.com' => 'PHP/5.2',
'deadspin.com' => 'PHP/5.2',
'kotaku.com' => 'PHP/5.2',
'jezebel.com' => 'PHP/5.2',
'io9.com' => 'PHP/5.2',
'jalopnik.com' => 'PHP/5.2',
'gizmodo.com' => 'PHP/5.2',
'.wikipedia.org' => 'Mozilla/5.2',
'.fok.nl' => 'Googlebot/2.1',
'getpocket.com' => 'PHP/5.2'
);
// URL Rewriting
// ----------------------
// Currently allows simple string replace of URLs.
// Useful for rewriting certain URLs to point to a single page
// or HTML view. Although using the single_page_link site config
// instruction is the preferred way to do this, sometimes, as
// with Google Docs URLs, it's not possible.
// Note: this might move to the site config file at some point.
$options->rewrite_url = array(
// Rewrite public Google Docs URLs to point to HTML view:
// if a URL contains docs.google.com, replace /Doc? with /View?
'docs.google.com' => array('/Doc?' => '/View?'),
'tnr.com' => array('tnr.com/article/' => 'tnr.com/print/article/'),
'.m.wikipedia.org' => array('.m.wikipedia.org' => '.wikipedia.org'),
'm.vanityfair.com' => array('m.vanityfair.com' => 'www.vanityfair.com')
);
// Content-Type exceptions
// -----------------------
// Here you can define different actions based
// on the Content-Type header returned by server.
// MIME type as key, action as value.
// Valid actions:
// * 'exclude' - exclude this item from the result
// * 'link' - create HTML link to the item
$options->content_type_exc = array(
'application/pdf' => array('action'=>'link', 'name'=>'PDF'),
'image' => array('action'=>'link', 'name'=>'Image'),
'audio' => array('action'=>'link', 'name'=>'Audio'),
'video' => array('action'=>'link', 'name'=>'Video')
);
// Cache directory level
// ----------------------
// Spread cache files over different directories (only used if caching is enabled).
// Used to prevent large number of files in one directory.
// This corresponds to Zend_Cache's hashed_directory_level
// see http://framework.zend.com/manual/en/zend.cache.backends.html
// It's best not to change this if you're unsure.
$options->cache_directory_level = 0;
// Cache cleanup
// -------------
// 0 = script will not clean cache (rename cachecleanup.php and use it for scheduled (e.g. cron) cache cleanup)
// 1 = clean cache everytime the script runs (not recommended)
// 100 = clean cache roughly once every 100 script runs
// x = clean cache roughly once every x script runs
// ...you get the idea :)
$options->cache_cleanup = 100;
/////////////////////////////////////////////////
/// DO NOT CHANGE ANYTHING BELOW THIS ///////////
/////////////////////////////////////////////////
if (!defined('_FF_FTR_VERSION')) define('_FF_FTR_VERSION', '3.2');
if (basename(__FILE__) == 'config.php') {
if (file_exists(dirname(__FILE__).'/custom_config.php')) {
require_once dirname(__FILE__).'/custom_config.php';
}
// check for environment variables - often used on cloud platforms
// environment variables should be prefixed with 'ftr_', e.g.
// ftr_max_entries: 1
// will set the max_entries value to 1.
foreach ($options as $_key=>&$_val) {
$_key = "ftr_$_key";
if (($_env = getenv($_key)) !== false) {
if (is_array($_val)) {
if ($_key === 'ftr_admin_credentials') {
$_val = array_combine(array('username', 'password'), array_map('trim', explode(':', $_env, 2)));
if ($_val === false) $_val = array('username'=>'admin', 'password'=>'');
}
} elseif ($_env === 'true' || $_env === 'false') {
$_val = ($_env === 'true');
} elseif (is_numeric($_env)) {
$_val = (int)$_env;
} else { // string
$_val = $_env;
}
}
}
unset($_key, $_val, $_env);
}
================================================
FILE: css/feed.css
================================================
/* RSS CSS Document */
* { margin:0; padding:0; }
p { padding: .5em 0; }
h1,h2,h3,h4,h5,h6 { font-size: 1em; padding: .5em 0; }
html { display:block; padding-bottom:50px; }
body { font:80% Verdana, sans-serif; color:#000; padding:25px 0 0 35px; }
a { color:#5BAB03; text-decoration:none; }
a:hover { color:#5BAB03; text-decoration: underline;}
ul { margin-left:1.5em; }
li { margin-bottom:0.4em; }
div#content>ul { list-style-type: none; }
div.article>li>a { font-weight:bold; font-size: 1.3em;}
div { line-height:1.6em; }
div#content { background:#fff; margin-right:15px; padding-left:1em;}
div#content div { margin:0 1em 1em 0; }
div#explanation { padding:1em 1em 0 1em; border:1px solid #ddd; background:#efefef; margin:0 2em 2em 0; }
div#explanation h1 { font-weight:normal; font-size:1.8em; margin-bottom:0.3em; }
div#explanation p { margin-bottom:1em; }
.small { font-size: .7em; color: #666; }
================================================
FILE: css/feed.xsl
================================================
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<xsl:output method="html" />
<xsl:variable name="title" select="/rss/channel/title"/>
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="$title"/> (full-text feed)</title>
<style type="text/css">
@import url(css/feed.css);
</style>
</head>
<body>
<div id="explanation">
<h1><xsl:value-of select="$title"/> <span class="small"> (full-text feed)</span></h1>
<p>You are viewing an auto-generated full-text <acronym title="Really Simple Syndication">RSS</acronym> feed. RSS feeds allow you to stay up to date with the latest news and features you want from websites. To subscribe to it, you will need a News Reader or other similar device.</p>
<p>Below is the latest content available from this feed.</p>
</div>
<div id="content">
<ul>
<xsl:for-each select="rss/channel/item">
<div class="article">
<li><a href="{link}" rel="bookmark"><xsl:value-of disable-output-escaping="yes" select="title"/></a>
<div>
<xsl:choose>
<xsl:when test="content:encoded"><xsl:value-of disable-output-escaping="yes" select="content:encoded" /></xsl:when>
<xsl:when test="description"><xsl:value-of disable-output-escaping="yes" select="description" /></xsl:when>
</xsl:choose>
</div>
</li>
</div>
</xsl:for-each>
</ul>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
================================================
FILE: custom_config.php.demo
================================================
<?php
/* Full-Text RSS config */
$options->debug = true;
$options->default_entries = 15;
$options->max_entries = 40;
$options->summary = 'user';
$options->rewrite_relative_urls = true;
$options->exclude_items_on_fail = 'user';
$options->multipage = true;
$options->caching = true;
$options->cache_dir = dirname(__FILE__).'/cache';
$options->error_message = '[unable to retrieve full-text content]';
$options->keep_enclosures = true;
$options->detect_language = 1;
$options->registration_key = '';
$options->admin_credentials = array('username'=>'admin0', 'password'=>'admin0');
// Non-empty example: array('example.com', 'anothersite.org');
$options->allowed_urls = array();
$options->blocked_urls = array();
$options->favour_feed_titles = 'user';
$options->xss_filter = 'user';
$options->allowed_parsers = array('libxml', 'html5lib');
$options->cors = false;
$options->apc = true;
$options->smart_cache = true;
$options->cache_ttl = 60*60;
$options->http_cache_ttl = 3*24*60*60;
$options->fingerprints = array(
// Posterous
'<meta name="generator" content="Posterous"' => array('hostname'=>'fingerprint.posterous.com', 'head'=>true),
// Blogger
'<meta content=\'blogger\' name=\'generator\'' => array('hostname'=>'fingerprint.blogspot.com', 'head'=>true),
'<meta name="generator" content="Blogger"' => array('hostname'=>'fingerprint.blogspot.com', 'head'=>true),
// WordPress (self-hosted and hosted)
'<meta name="generator" content="WordPress' => array('hostname'=>'fingerprint.wordpress.com', 'head'=>true)
);
$options->user_agents = array( 'lifehacker.com' => 'PHP/5.2',
'gawker.com' => 'PHP/5.2',
'deadspin.com' => 'PHP/5.2',
'kotaku.com' => 'PHP/5.2',
'jezebel.com' => 'PHP/5.2',
'io9.com' => 'PHP/5.2',
'jalopnik.com' => 'PHP/5.2',
'gizmodo.com' => 'PHP/5.2',
'.wikipedia.org' => 'Mozilla/5.2',
'.fok.nl' => 'Googlebot/2.1',
'getpocket.com' => 'PHP/5.2'
);
$options->rewrite_url = array(
// Rewrite public Google Docs URLs to point to HTML view:
// if a URL contains docs.google.com, replace /Doc? with /View?
'docs.google.com' => array('/Doc?' => '/View?'),
'tnr.com' => array('tnr.com/article/' => 'tnr.com/print/article/'),
'.m.wikipedia.org' => array('.m.wikipedia.org' => '.wikipedia.org'),
'm.vanityfair.com' => array('m.vanityfair.com' => 'www.vanityfair.com')
);
$options->content_type_exc = array(
'application/pdf' => array('action'=>'link', 'name'=>'PDF'),
'image' => array('action'=>'link', 'name'=>'Image'),
'audio' => array('action'=>'link', 'name'=>'Audio'),
'video' => array('action'=>'link', 'name'=>'Video')
);
$options->cache_directory_level = 0;
$options->cache_cleanup = 100;
================================================
FILE: ftr_compatibility_test.php
================================================
<?php
/*
FULL-TEXT-RSS V3 COMPATIBILITY TEST
1) Upload ftr_compatibility_test.php to the web-accessible root of your website.
For example, if your website is www.example.com, upload it so that you can get
to it at www.example.com/ftr_compatibility_test.php
2) Open your web browser and go to the page you just uploaded.
If things don't look right, have a look at our hosting suggestions:
http://help.fivefilters.org/customer/portal/articles/1143210-hosting
Note: This compatibility test has been borrowed (and slightly adapted) from the one supplied by
SimplePie.org. We have kept most of their checks intact as we use SimplePie in our application.
http://github.com/simplepie/simplepie/tree/master/compatibility_test/
*/
$app_name = 'Full-Text RSS 3.2';
$php_ok = (function_exists('version_compare') && version_compare(phpversion(), '5.2.0', '>='));
$pcre_ok = extension_loaded('pcre');
$zlib_ok = extension_loaded('zlib');
$mbstring_ok = extension_loaded('mbstring');
$iconv_ok = extension_loaded('iconv');
$tidy_ok = function_exists('tidy_parse_string');
$curl_ok = function_exists('curl_exec');
$parallel_ok = ((extension_loaded('http') && class_exists('HttpRequestPool')) || ($curl_ok && function_exists('curl_multi_init')));
$allow_url_fopen_ok = (bool)ini_get('allow_url_fopen');
$filter_ok = extension_loaded('filter');
if (extension_loaded('xmlreader')) {
$xml_ok = true;
} elseif (extension_loaded('xml')) {
$parser_check = xml_parser_create();
xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
xml_parser_free($parser_check);
$xml_ok = isset($values[0]['value']);
} else {
$xml_ok = false;
}
header('Content-type: text/html; charset=UTF-8');
?><!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $app_name; ?>: Server Compatibility Test</title>
<style type="text/css">
body {
font:14px/1.4em "Lucida Grande", Verdana, Arial, Helvetica, Clean, Sans, sans-serif;
letter-spacing:0px;
color:#333;
margin:0;
padding:0;
background:#fff;
}
div#site {
width:550px;
margin:20px auto 0 auto;
}
a {
color:#000;
text-decoration:underline;
padding:0 1px;
}
a:hover {
color:#fff;
background-color:#333;
text-decoration:none;
padding:0 1px;
}
p {
margin:0;
padding:5px 0;
}
em {
font-style:normal;
background-color:#ffc;
padding: 0.1em 0;
}
.success {
background-color: lightgreen;
}
.highlight {
background-color: #ffc;
}
ul, ol {
margin:10px 0 10px 20px;
padding:0 0 0 15px;
}
ul li, ol li {
margin:0 0 7px 0;
padding:0 0 0 3px;
}
h2 {
font-size:18px;
padding:0;
margin:30px 0 20px 0;
}
h3 {
font-size:16px;
padding:0;
margin:20px 0 5px 0;
}
h4 {
font-size:14px;
padding:0;
margin:15px 0 5px 0;
}
code {
font-size:1.1em;
color:#000;
}
em strong {
text-transform: uppercase;
}
table.chart {
border-collapse:collapse;
}
table.chart th {
background-color:#eee;
padding:2px 3px;
border:1px solid #fff;
}
table.chart td {
text-align:center;
padding:2px 3px;
border:1px solid #eee;
}
table.chart tr.enabled td {
/* Leave this alone */
}
table.chart tr.disabled td,
table.chart tr.disabled td a {
color:#999;
font-style:italic;
}
table.chart tr.disabled td a {
text-decoration:underline;
}
div.chunk {
margin:20px 0 0 0;
padding:0 0 10px 0;
border-bottom:1px solid #ccc;
}
.footnote,
.footnote a {
font:10px/12px verdana, sans-serif;
color:#aaa;
}
.footnote em {
background-color:transparent;
font-style:italic;
}
</style>
</head>
<body>
<div id="site">
<div id="content">
<div class="chunk">
<h2 style="text-align:center;"><?php echo $app_name; ?>: Compatibility Test</h2>
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="chart">
<thead>
<tr>
<th>Test</th>
<th>Should Be</th>
<th>What You Have</th>
</tr>
</thead>
<tbody>
<tr class="<?php echo ($php_ok) ? 'enabled' : 'disabled'; ?>">
<td>PHP</td>
<td>5.2.0 or higher</td>
<td><?php echo phpversion(); ?></td>
</tr>
<tr class="<?php echo ($xml_ok) ? 'enabled, and sane' : 'disabled, or broken'; ?>">
<td><a href="http://php.net/xml">XML</a></td>
<td>Enabled</td>
<td><?php echo ($xml_ok) ? 'Enabled, and sane' : 'Disabled, or broken'; ?></td>
</tr>
<tr class="<?php echo ($pcre_ok) ? 'enabled' : 'disabled'; ?>">
<td><a href="http://php.net/pcre">PCRE</a></td>
<td>Enabled</td>
<td><?php echo ($pcre_ok) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
<tr class="<?php echo ($zlib_ok) ? 'enabled' : 'disabled'; ?>">
<td><a href="http://php.net/zlib">Zlib</a></td>
<td>Enabled</td>
<td><?php echo ($zlib_ok) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
<tr class="<?php echo ($mbstring_ok) ? 'enabled' : 'disabled'; ?>">
<td><a href="http://php.net/mbstring">mbstring</a></td>
<td>Enabled</td>
<td><?php echo ($mbstring_ok) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
<tr class="<?php echo ($iconv_ok) ? 'enabled' : 'disabled'; ?>">
<td><a href="http://php.net/iconv">iconv</a></td>
<td>Enabled</td>
<td><?php echo ($iconv_ok) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
<tr class="<?php echo ($filter_ok) ? 'enabled' : 'disabled'; ?>">
<td><a href="http://uk.php.net/manual/en/book.filter.php">Data filtering</a></td>
<td>Enabled</td>
<td><?php echo ($filter_ok) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
<tr class="<?php echo ($tidy_ok) ? 'enabled' : 'disabled'; ?>">
<td><a href="http://php.net/tidy">Tidy</a></td>
<td>Enabled</td>
<td><?php echo ($tidy_ok) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
<tr class="<?php echo ($curl_ok) ? 'enabled' : 'disabled'; ?>">
<td><a href="http://php.net/curl">cURL</a></td>
<td>Enabled</td>
<td><?php echo (extension_loaded('curl')) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
<tr class="<?php echo ($parallel_ok) ? 'enabled' : 'disabled'; ?>">
<td>Parallel URL fetching</td>
<td>Enabled</td>
<td><?php echo ($parallel_ok) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
<tr class="<?php echo ($allow_url_fopen_ok) ? 'enabled' : 'disabled'; ?>">
<td><a href="http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen">allow_url_fopen</a></td>
<td>Enabled</td>
<td><?php echo ($allow_url_fopen_ok) ? 'Enabled' : 'Disabled'; ?></td>
</tr>
</tbody>
</table>
</div>
<div class="chunk">
<h3>What does this mean?</h3>
<ol>
<?php if ($php_ok && $xml_ok && $pcre_ok && $mbstring_ok && $iconv_ok && $filter_ok && $zlib_ok && $tidy_ok && $curl_ok && $parallel_ok && $allow_url_fopen_ok): ?>
<li>You have everything you need to run <?php echo $app_name; ?> properly! Congratulations!</li>
<?php else: ?>
<?php if ($php_ok): ?>
<li><strong>PHP:</strong> You are running a supported version of PHP. No problems here.</li>
<?php if ($xml_ok): ?>
<li><strong>XML:</strong> You have XMLReader support or a version of XML support that isn't broken installed. No problems here.</li>
<?php if ($pcre_ok): ?>
<li><strong>PCRE:</strong> You have PCRE support installed. No problems here.</li>
<?php if ($allow_url_fopen_ok): ?>
<li><strong>allow_url_fopen:</strong> You have allow_url_fopen enabled. No problems here.</li>
<?php if ($filter_ok): ?>
<li><strong>Data filtering:</strong> You have the PHP filter extension enabled. No problems here.</li>
<?php if ($zlib_ok): ?>
<li><strong>Zlib:</strong> You have <code>Zlib</code> enabled. This allows SimplePie to support GZIP-encoded feeds. No problems here.</li>
<?php else: ?>
<li class="highlight"><strong>Zlib:</strong> The <code>Zlib</code> extension is not available. SimplePie will ignore any GZIP-encoding, and instead handle feeds as uncompressed text.</li>
<?php endif; ?>
<?php if ($mbstring_ok && $iconv_ok): ?>
<li><strong>mbstring and iconv:</strong> You have both <code>mbstring</code> and <code>iconv</code> installed! This will allow <?php echo $app_name; ?> to handle the greatest number of languages. No problems here.</li>
<?php elseif ($mbstring_ok): ?>
<li class="highlight"><strong>mbstring:</strong> <code>mbstring</code> is installed, but <code>iconv</code> is not.</li>
<?php elseif ($iconv_ok): ?>
<li class="highlight"><strong>iconv:</strong> <code>iconv</code> is installed, but <code>mbstring</code> is not.</li>
<?php else: ?>
<li class="highlight"><strong>mbstring and iconv:</strong> <em>You do not have either of the extensions installed.</em> This will significantly impair your ability to read non-English feeds, as well as even some English ones.</li>
<?php endif; ?>
<?php if ($tidy_ok): ?>
<li><strong>Tidy:</strong> You have <code>Tidy</code> support installed. No problems here.</li>
<?php else: ?>
<li class="highlight"><strong>Tidy:</strong> Th
gitextract_1gv9702v/
├── README.md
├── README.txt
├── UPDATING.txt
├── admin/
│ ├── apc.php
│ ├── codemirror/
│ │ ├── codemirror.css
│ │ ├── codemirror.js
│ │ └── properties.js
│ ├── edit-pattern.php
│ ├── index.php
│ ├── login.php
│ ├── require_login.php
│ ├── template.php
│ └── update.php
├── cache/
│ ├── index.php
│ ├── rss/
│ │ └── index.php
│ └── urls/
│ └── index.php
├── changelog.txt
├── cleancache.php
├── config.php
├── css/
│ ├── feed.css
│ └── feed.xsl
├── custom_config.php.demo
├── ftr_compatibility_test.php
├── index.php
├── js/
│ ├── bootstrap-popover.js
│ ├── bootstrap-tab.js
│ └── bootstrap-tooltip.js
├── libraries/
│ ├── Zend/
│ │ ├── Cache/
│ │ │ ├── Backend/
│ │ │ │ ├── ExtendedInterface.php
│ │ │ │ ├── File.php
│ │ │ │ └── Interface.php
│ │ │ ├── Backend.php
│ │ │ ├── Core.php
│ │ │ └── Exception.php
│ │ ├── Cache.php
│ │ └── Exception.php
│ ├── content-extractor/
│ │ ├── ContentExtractor.php
│ │ └── SiteConfig.php
│ ├── feedwriter/
│ │ ├── FeedItem.php
│ │ └── FeedWriter.php
│ ├── htmLawed/
│ │ └── htmLawed2.php
│ ├── html5/
│ │ ├── Data.php
│ │ ├── InputStream.php
│ │ ├── Parser.php
│ │ ├── Tokenizer.php
│ │ ├── TreeBuilder.php
│ │ └── named-character-references.ser
│ ├── humble-http-agent/
│ │ ├── CookieJar.php
│ │ ├── HumbleHttpAgent.php
│ │ ├── RollingCurl.php
│ │ └── SimplePie_HumbleHttpAgent.php
│ ├── language-detect/
│ │ ├── LanguageDetect/
│ │ │ ├── Exception.php
│ │ │ ├── ISO639.php
│ │ │ └── Parser.php
│ │ └── LanguageDetect.php
│ ├── readability/
│ │ ├── ImageCaching.php
│ │ ├── JSLikeHTMLElement.php
│ │ └── Readability.php
│ └── simplepie/
│ ├── LICENSE.txt
│ ├── autoloader.php
│ └── library/
│ ├── SimplePie/
│ │ ├── Author.php
│ │ ├── Cache/
│ │ │ ├── Base.php
│ │ │ ├── DB.php
│ │ │ ├── File.php
│ │ │ ├── Memcache.php
│ │ │ └── MySQL.php
│ │ ├── Cache.php
│ │ ├── Caption.php
│ │ ├── Category.php
│ │ ├── Content/
│ │ │ └── Type/
│ │ │ └── Sniffer.php
│ │ ├── Copyright.php
│ │ ├── Core.php
│ │ ├── Credit.php
│ │ ├── Decode/
│ │ │ └── HTML/
│ │ │ └── Entities.php
│ │ ├── Enclosure.php
│ │ ├── Exception.php
│ │ ├── File.php
│ │ ├── HTTP/
│ │ │ └── Parser.php
│ │ ├── IRI.php
│ │ ├── Item.php
│ │ ├── Locator.php
│ │ ├── Misc.php
│ │ ├── Net/
│ │ │ └── IPv6.php
│ │ ├── Parse/
│ │ │ └── Date.php
│ │ ├── Parser.php
│ │ ├── Rating.php
│ │ ├── Registry.php
│ │ ├── Restriction.php
│ │ ├── Sanitize.php
│ │ ├── Source.php
│ │ ├── XML/
│ │ │ └── Declaration/
│ │ │ └── Parser.php
│ │ └── gzdecode.php
│ └── SimplePie.php
├── license.txt
├── makefulltextfeed.php
├── manifest.yml
└── site_config/
├── README.txt
├── custom/
│ └── index.php
├── index.php
└── standard/
├── .wikipedia.org.txt
└── version.txt
SYMBOL INDEX (951 symbols across 72 files)
FILE: admin/apc.php
function defaults (line 66) | function defaults($d,$v) {
function duration (line 215) | function duration($ts) {
function graphics_avail (line 239) | function graphics_avail() {
function fill_arc (line 248) | function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $col...
function text_arc (line 277) | function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $col...
function fill_box (line 290) | function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placei...
function bsize (line 458) | function bsize($s) {
function sortheader (line 467) | function sortheader($key,$name,$extra='') {
function menu_entry (line 478) | function menu_entry($ob,$title) {
function put_login_link (line 489) | function put_login_link($s="Login")
function block_sort (line 512) | function block_sort($array1, $array2)
FILE: admin/codemirror/codemirror.js
function e (line 1) | function e(r,i){function un(e){if(s.onDragEvent&&s.onDragEvent(ln,I(e)))...
function f (line 1) | function f(e){return typeof e=="string"?a[e]:e}
function l (line 1) | function l(e,t,n,r,i){function s(t){t=f(t);var n=t[e];if(n===!1)return i...
function c (line 1) | function c(e){var t=vt[X(e,"keyCode")];return t=="Ctrl"||t=="Alt"||t=="S...
function x (line 1) | function x(e,t){if(t===!0)return t;if(e.copyState)return e.copyState(t);...
function T (line 1) | function T(e,t,n){return e.startState?e.startState(t,n):!0}
function N (line 1) | function N(e,t){this.pos=this.start=0,this.string=e,this.tabSize=t||8}
function C (line 1) | function C(e,t,n,r){this.from=e,this.to=t,this.style=n,this.marker=r}
function k (line 1) | function k(e){this.from=e,this.to=e,this.line=null}
function A (line 1) | function A(e,t){this.styles=t||[e,null],this.text=e,this.height=1}
function O (line 1) | function O(e,t,n,r){for(var i=0,s=0,o=0;s<t;i+=2){var u=n[i],a=s+u.lengt...
function M (line 1) | function M(e){this.lines=e,this.parent=null;for(var t=0,n=e.length,r=0;t...
function _ (line 1) | function _(e){this.children=e;var t=0,n=0;for(var r=0,i=e.length;r<i;++r...
function D (line 1) | function D(e,t){while(!e.lines)for(var n=0;;++n){var r=e.children[n],i=r...
function P (line 1) | function P(e){if(e.parent==null)return null;var t=e.parent,n=ct(t.lines,...
function H (line 1) | function H(e,t){var n=0;e:do{for(var r=0,i=e.children.length;r<i;++r){va...
function B (line 1) | function B(e,t){var n=0;e:do{for(var r=0,i=e.children.length;r<i;++r){va...
function j (line 1) | function j(){this.time=0,this.done=[],this.undone=[],this.compound=0,thi...
function F (line 1) | function F(){U(this)}
function I (line 1) | function I(e){return e.stop||(e.stop=F),e}
function q (line 1) | function q(e){e.preventDefault?e.preventDefault():e.returnValue=!1}
function R (line 1) | function R(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}
function U (line 1) | function U(e){q(e),R(e)}
function z (line 1) | function z(e){return e.target||e.srcElement}
function W (line 1) | function W(e){var t=e.which;return t==null&&(e.button&1?t=1:e.button&2?t...
function X (line 1) | function X(e,t){var n=e.override&&e.override.hasOwnProperty(t);return n?...
function V (line 1) | function V(e,t,n,r){if(typeof e.addEventListener=="function"){e.addEvent...
function $ (line 1) | function $(){this.id=null}
function Y (line 1) | function Y(e,t,n){t==null&&(t=e.search(/[^\s\u00a0]/),t==-1&&(t=e.length...
function Z (line 1) | function Z(e){return e.currentStyle?e.currentStyle:window.getComputedSty...
function et (line 1) | function et(e,t){try{var n=e.getBoundingClientRect();n={top:n.top,left:n...
function tt (line 1) | function tt(e){return e.textContent||e.innerText||e.nodeValue||""}
function nt (line 1) | function nt(e){t?(e.selectionStart=0,e.selectionEnd=e.value.length):e.se...
function rt (line 1) | function rt(e,t){return e.line==t.line&&e.ch==t.ch}
function it (line 1) | function it(e,t){return e.line<t.line||e.line==t.line&&e.ch<t.ch}
function st (line 1) | function st(e){return{line:e.line,ch:e.ch}}
function ot (line 1) | function ot(e,t,n,r){var i=document.createElement(e);n&&(i.className=n),...
function ut (line 1) | function ut(e){return e.innerHTML="",e}
function at (line 1) | function at(e,t){ut(e).appendChild(t)}
function ft (line 1) | function ft(e,t){v?(e.innerHTML="",e.appendChild(document.createTextNode...
function lt (line 1) | function lt(e,t){if(!t)return 0;if(!e)return t.length;for(var n=e.length...
function ct (line 1) | function ct(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length...
function ht (line 1) | function ht(e){return/\w/.test(e)||e.toUpperCase()!=e.toLowerCase()}
function r (line 1) | function r(){t.value=o.getValue()}
function u (line 1) | function u(t,n,o){if(!n)return;r&&p&&n.charAt(0)==" "&&(n="\u00a0"+n.sli...
function m (line 1) | function m(e){return e?"cm-"+e.replace(/ +/g," cm-"):null}
FILE: admin/edit-pattern.php
function filter_only_text (line 62) | function filter_only_text($filename) {
function is_valid_hostname (line 65) | function is_valid_hostname($host) {
FILE: admin/template.php
function tpl_header (line 3) | function tpl_header($title='Full-Text RSS Admin Area') {
function tpl_footer (line 53) | function tpl_footer() {
FILE: admin/update.php
function println (line 225) | function println($txt) {
function rrmdir (line 232) | function rrmdir($dir) {
FILE: cleancache.php
function __autoload (line 41) | function __autoload($class_name) {
FILE: js/bootstrap-tab.js
function next (line 79) | function next() {
FILE: js/bootstrap-tooltip.js
function removeWithAnimation (line 174) | function removeWithAnimation() {
FILE: libraries/Zend/Cache.php
class Zend_Cache (line 28) | abstract class Zend_Cache
method factory (line 91) | public static function factory($frontend, $backend, $frontendOptions =...
method _makeBackend (line 124) | public static function _makeBackend($backend, $backendOptions, $custom...
method _makeFrontend (line 165) | public static function _makeFrontend($frontend, $frontendOptions = arr...
method throwException (line 205) | public static function throwException($msg, Exception $e = null)
method _normalizeName (line 218) | protected static function _normalizeName($name)
method _isReadable (line 241) | private static function _isReadable($filename)
FILE: libraries/Zend/Cache/Backend.php
class Zend_Cache_Backend (line 30) | class Zend_Cache_Backend
method __construct (line 64) | public function __construct(array $options = array())
method setDirectives (line 78) | public function setDirectives($directives)
method setOption (line 103) | public function setOption($name, $value)
method getOption (line 121) | public function getOption($name)
method getLifetime (line 145) | public function getLifetime($specificLifetime)
method isAutomaticCleaningAvailable (line 161) | public function isAutomaticCleaningAvailable()
method getTmpDir (line 174) | public function getTmpDir()
method _isGoodTmpDir (line 228) | protected function _isGoodTmpDir($dir)
method _loggerSanity (line 246) | protected function _loggerSanity()
method _log (line 275) | protected function _log($message, $priority = 4)
FILE: libraries/Zend/Cache/Backend/ExtendedInterface.php
type Zend_Cache_Backend_ExtendedInterface (line 35) | interface Zend_Cache_Backend_ExtendedInterface extends Zend_Cache_Backen...
method getIds (line 43) | public function getIds();
method getTags (line 50) | public function getTags();
method getIdsMatchingTags (line 60) | public function getIdsMatchingTags($tags = array());
method getIdsNotMatchingTags (line 70) | public function getIdsNotMatchingTags($tags = array());
method getIdsMatchingAnyTags (line 80) | public function getIdsMatchingAnyTags($tags = array());
method getFillingPercentage (line 87) | public function getFillingPercentage();
method getMetadatas (line 100) | public function getMetadatas($id);
method touch (line 109) | public function touch($id, $extraLifetime);
method getCapabilities (line 125) | public function getCapabilities();
FILE: libraries/Zend/Cache/Backend/File.php
class Zend_Cache_Backend_File (line 43) | class Zend_Cache_Backend_File extends Zend_Cache_Backend implements Zend...
method __construct (line 128) | public function __construct(array $options = array())
method setCacheDir (line 178) | public function setCacheDir($value, $trailingSeparator = true)
method load (line 200) | public function load($id, $doNotTestCacheValidity = false)
method test (line 228) | public function test($id)
method save (line 246) | public function save($data, $id, $tags = array(), $specificLifetime = ...
method remove (line 286) | public function remove($id)
method clean (line 312) | public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = a...
method getIds (line 324) | public function getIds()
method getTags (line 334) | public function getTags()
method getIdsMatchingTags (line 347) | public function getIdsMatchingTags($tags = array())
method getIdsNotMatchingTags (line 360) | public function getIdsNotMatchingTags($tags = array())
method getIdsMatchingAnyTags (line 373) | public function getIdsMatchingAnyTags($tags = array())
method getFillingPercentage (line 384) | public function getFillingPercentage()
method getMetadatas (line 409) | public function getMetadatas($id)
method touch (line 432) | public function touch($id, $extraLifetime)
method getCapabilities (line 468) | public function getCapabilities()
method ___expire (line 487) | public function ___expire($id)
method _getMetadatas (line 502) | protected function _getMetadatas($id)
method _setMetadatas (line 524) | protected function _setMetadatas($id, $metadatas, $save = true)
method _delMetadatas (line 546) | protected function _delMetadatas($id)
method _cleanMetadatas (line 560) | protected function _cleanMetadatas()
method _loadMetadatas (line 571) | protected function _loadMetadatas($id)
method _saveMetadatas (line 589) | protected function _saveMetadatas($id, $metadatas)
method _metadatasFile (line 605) | protected function _metadatasFile($id)
method _isMetadatasFile (line 618) | protected function _isMetadatasFile($fileName)
method _remove (line 637) | protected function _remove($file)
method _clean (line 669) | protected function _clean($dir, $mode = Zend_Cache::CLEANING_MODE_ALL,...
method _get (line 762) | protected function _get($dir, $mode, $tags = array())
method _expireTime (line 851) | protected function _expireTime($lifetime)
method _hash (line 867) | protected function _hash($data, $controlType)
method _idToFileName (line 889) | protected function _idToFileName($id)
method _file (line 902) | protected function _file($id)
method _path (line 916) | protected function _path($id, $parts = false)
method _recursiveMkdirAndChmod (line 941) | protected function _recursiveMkdirAndChmod($id)
method _test (line 963) | protected function _test($id, $doNotTestCacheValidity)
method _fileGetContents (line 981) | protected function _fileGetContents($file)
method _filePutContents (line 1004) | protected function _filePutContents($file, $string)
method _fileNameToId (line 1028) | protected function _fileNameToId($fileName)
FILE: libraries/Zend/Cache/Backend/Interface.php
type Zend_Cache_Backend_Interface (line 30) | interface Zend_Cache_Backend_Interface
method setDirectives (line 37) | public function setDirectives($directives);
method load (line 48) | public function load($id, $doNotTestCacheValidity = false);
method test (line 56) | public function test($id);
method save (line 70) | public function save($data, $id, $tags = array(), $specificLifetime = ...
method remove (line 78) | public function remove($id);
method clean (line 97) | public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = a...
FILE: libraries/Zend/Cache/Core.php
class Zend_Cache_Core (line 28) | class Zend_Cache_Core
method __construct (line 137) | public function __construct($options = array())
method setConfig (line 158) | public function setConfig(Zend_Config $config)
method setBackend (line 174) | public function setBackend(Zend_Cache_Backend $backendObject)
method getBackend (line 196) | public function getBackend()
method setOption (line 211) | public function setOption($name, $value)
method getOption (line 236) | public function getOption($name)
method _setOption (line 261) | private function _setOption($name, $value)
method setLifetime (line 280) | public function setLifetime($newLifetime)
method load (line 296) | public function load($id, $doNotTestCacheValidity = false, $doNotUnser...
method test (line 324) | public function test($id)
method save (line 348) | public function save($data, $id = null, $tags = array(), $specificLife...
method remove (line 421) | public function remove($id)
method clean (line 451) | public function clean($mode = 'all', $tags = array())
method getIdsMatchingTags (line 476) | public function getIdsMatchingTags($tags = array())
method getIdsNotMatchingTags (line 509) | public function getIdsNotMatchingTags($tags = array())
method getIdsMatchingAnyTags (line 542) | public function getIdsMatchingAnyTags($tags = array())
method getIds (line 572) | public function getIds()
method getTags (line 599) | public function getTags()
method getFillingPercentage (line 615) | public function getFillingPercentage()
method getMetadatas (line 634) | public function getMetadatas($id)
method touch (line 650) | public function touch($id, $extraLifetime)
method _validateIdOrTag (line 670) | protected static function _validateIdOrTag($string)
method _validateTagsArray (line 692) | protected static function _validateTagsArray($tags)
method _loggerSanity (line 711) | protected function _loggerSanity()
method _log (line 737) | protected function _log($message, $priority = 4)
method _id (line 757) | protected function _id($id)
FILE: libraries/Zend/Cache/Exception.php
class Zend_Cache_Exception (line 32) | class Zend_Cache_Exception extends Zend_Exception {}
FILE: libraries/Zend/Exception.php
class Zend_Exception (line 28) | class Zend_Exception extends Exception
method __construct (line 43) | public function __construct($msg = '', $code = 0, Exception $previous ...
method __call (line 62) | public function __call($method, array $args)
method __toString (line 75) | public function __toString()
method _getPrevious (line 92) | protected function _getPrevious()
FILE: libraries/content-extractor/ContentExtractor.php
class ContentExtractor (line 15) | class ContentExtractor
method __construct (line 32) | function __construct($path, $fallback=null) {
method debug (line 36) | protected function debug($msg) {
method reset (line 48) | public function reset() {
method findHostUsingFingerprints (line 61) | public function findHostUsingFingerprints($html) {
method buildSiteConfig (line 82) | public function buildSiteConfig($url, $html='', $add_to_cache=true) {
method process (line 138) | public function process($html, $url, $smart_tidy=true) {
method isDescendant (line 687) | private function isDescendant(DOMElement $parent, DOMElement $child) {
method getContent (line 696) | public function getContent() {
method getTitle (line 700) | public function getTitle() {
method getAuthors (line 704) | public function getAuthors() {
method getLanguage (line 708) | public function getLanguage() {
method getDate (line 712) | public function getDate() {
method getSiteConfig (line 716) | public function getSiteConfig() {
method getNextPageUrl (line 720) | public function getNextPageUrl() {
FILE: libraries/content-extractor/SiteConfig.php
class SiteConfig (line 15) | class SiteConfig
method debug (line 108) | protected static function debug($msg) {
method use_apc (line 127) | public static function use_apc($apc=true) {
method tidy (line 137) | public function tidy($use_default=true) {
method prune (line 143) | public function prune($use_default=true) {
method images_to_datauri (line 149) | public function images_to_datauri($use_default=true) {
method parser (line 155) | public function parser($use_default=true) {
method autodetect_on_failure (line 161) | public function autodetect_on_failure($use_default=true) {
method set_config_path (line 166) | public static function set_config_path($path, $fallback=null) {
method add_to_cache (line 171) | public static function add_to_cache($key, SiteConfig $config, $use_apc...
method is_cached (line 183) | public static function is_cached($key) {
method append (line 194) | public function append(SiteConfig $newconfig) {
method build (line 212) | public static function build($host, $exact_host_match=false) {
method build_from_array (line 315) | public static function build_from_array(array $lines) {
FILE: libraries/feedwriter/FeedItem.php
class FeedItem (line 11) | class FeedItem
method __construct (line 21) | function __construct($version = RSS2)
method setElement (line 35) | public function setElement($elementName, $content, $attributes = null)
method addElement (line 52) | public function addElement($elementName, $content, $attributes = null)
method addElementArray (line 73) | public function addElementArray($elementArray)
method getElements (line 88) | public function getElements()
method setDescription (line 102) | public function setDescription($description)
method setTitle (line 114) | public function setTitle($title)
method setDate (line 126) | public function setDate($date)
method setLink (line 159) | public function setLink($link)
method setEncloser (line 183) | public function setEncloser($url, $length, $type)
FILE: libraries/feedwriter/FeedWriter.php
class FeedWriter (line 19) | class FeedWriter
method __construct (line 37) | function __construct($version = RSS2)
method setFormat (line 49) | public function setFormat($format) {
method setChannelElement (line 62) | public function setChannelElement($elementName, $content)
method setChannelElementsFromArray (line 75) | public function setChannelElementsFromArray($elementArray)
method genarateFeed (line 90) | public function genarateFeed()
method getItems (line 113) | public function &getItems()
method createNewItem (line 124) | public function createNewItem()
method addItem (line 137) | public function addItem($feedItem)
method setTitle (line 151) | public function setTitle($title)
method addHub (line 163) | public function addHub($hub)
method setXsl (line 175) | public function setXsl($xsl)
method setSelf (line 187) | public function setSelf($self)
method setDescription (line 199) | public function setDescription($desciption)
method setLink (line 212) | public function setLink($link)
method setImage (line 226) | public function setImage($title, $link, $url)
method printHead (line 241) | private function printHead()
method printTale (line 262) | private function printTale()
method makeNode (line 280) | private function makeNode($tagName, $tagContent, $attributes = null)
method json_keys (line 330) | private function json_keys(array $array) {
method printChannels (line 348) | private function printChannels()
method printItems (line 379) | private function printItems()
method startItem (line 421) | private function startItem()
method endItem (line 436) | private function endItem()
FILE: libraries/htmLawed/htmLawed2.php
class htmLawed (line 12) | class htmLawed{
method hl (line 14) | public static function hl($t, $C=1, $S=array()){
method hl_attrval (line 118) | public static function hl_attrval($t, $p){
method hl_bal (line 146) | public static function hl_bal($t, $do=1, $in='div'){
method hl_cmtcd (line 302) | public static function hl_cmtcd($t){
method hl_ent (line 317) | public static function hl_ent($t){
method hl_prot (line 333) | public static function hl_prot($p, $c=null){
method hl_regex (line 366) | public static function hl_regex($p){
method hl_spec (line 382) | public static function hl_spec($t){
method hl_tag (line 413) | public static function hl_tag($t){
method hl_tag2 (line 616) | public static function hl_tag2(&$e, &$a, $t=1){
method hl_tidy (line 643) | public static function hl_tidy($t, $w, $p){
method hl_version (line 698) | public static function hl_version(){
method kses (line 704) | public static function kses($t, $h, $p=array('http', 'https', 'ftp', '...
method kses_hook (line 718) | public static function kses_hook($t, &$C, &$S){
FILE: libraries/html5/Data.php
class HTML5_Data (line 5) | class HTML5_Data
method getRealCodepoint (line 58) | public static function getRealCodepoint($ref) {
method getNamedCharacterReferences (line 63) | public static function getNamedCharacterReferences() {
method utf8chr (line 76) | public static function utf8chr($code) {
FILE: libraries/html5/InputStream.php
class HTML5_InputStream (line 32) | class HTML5_InputStream {
method __construct (line 56) | public function __construct($data) {
method getCurrentLine (line 165) | public function getCurrentLine() {
method getColumnOffset (line 180) | public function getColumnOffset() {
method char (line 216) | public function char() {
method remainingChars (line 226) | public function remainingChars() {
method charsUntil (line 241) | public function charsUntil($bytes, $max = null) {
method charsWhile (line 261) | public function charsWhile($bytes, $max = null) {
method unget (line 279) | public function unget() {
FILE: libraries/html5/Parser.php
class HTML5_Parser (line 11) | class HTML5_Parser
method parse (line 19) | static public function parse($text, $builder = null) {
method parseFragment (line 31) | static public function parseFragment($text, $context = null, $builder ...
FILE: libraries/html5/Tokenizer.php
class HTML5_Tokenizer (line 36) | class HTML5_Tokenizer {
method __construct (line 87) | public function __construct($data, $builder = null) {
method parseFragment (line 94) | public function parseFragment($context = null) {
method parse (line 108) | public function parse() {
method save (line 2094) | public function save() {
method stream (line 2101) | public function stream() {
method consumeCharacterReference (line 2105) | private function consumeCharacterReference($allowed = false, $inattr =...
method characterReferenceInAttributeValue (line 2349) | private function characterReferenceInAttributeValue($allowed = false) {
method emitToken (line 2372) | protected function emitToken($token, $checkStream = true, $dry = false) {
FILE: libraries/html5/TreeBuilder.php
class HTML5_TreeBuilder (line 37) | class HTML5_TreeBuilder {
method strConst (line 107) | private function strConst($number) {
method __construct (line 149) | public function __construct() {
method emitToken (line 160) | public function emitToken($token, $mode = null) {
method insertElement (line 3160) | private function insertElement($token, $append = true) {
method insertText (line 3185) | private function insertText($data) {
method insertComment (line 3197) | private function insertComment($data) {
method appendToRealParent (line 3202) | private function appendToRealParent($node) {
method elementInScope (line 3215) | private function elementInScope($el, $scope = self::SCOPE) {
method reconstructActiveFormattingElements (line 3265) | private function reconstructActiveFormattingElements() {
method clearTheActiveFormattingElementsUpToTheLastMarker (line 3336) | private function clearTheActiveFormattingElementsUpToTheLastMarker() {
method generateImpliedEndTags (line 3357) | private function generateImpliedEndTags($exclude = array()) {
method getElementCategory (line 3371) | private function getElementCategory($node) {
method clearStackToTableContext (line 3387) | private function clearStackToTableContext($elements) {
method resetInsertionMode (line 3403) | private function resetInsertionMode($context = null) {
method closeCell (line 3511) | private function closeCell() {
method processWithRulesFor (line 3526) | private function processWithRulesFor($token, $mode) {
method insertCDATAElement (line 3535) | private function insertCDATAElement($token) {
method insertRCDATAElement (line 3542) | private function insertRCDATAElement($token) {
method getAttr (line 3549) | private function getAttr($token, $key) {
method getCurrentTable (line 3558) | private function getCurrentTable() {
method getFosterParent (line 3571) | private function getFosterParent() {
method fosterParent (line 3602) | public function fosterParent($node) {
method printStack (line 3622) | private function printStack() {
method printActiveFormattingElements (line 3633) | private function printActiveFormattingElements() {
method currentTableIsTainted (line 3643) | public function currentTableIsTainted() {
method setupContext (line 3650) | public function setupContext($context = null) {
method adjustMathMLAttributes (line 3696) | public function adjustMathMLAttributes($token) {
method adjustSVGAttributes (line 3705) | public function adjustSVGAttributes($token) {
method adjustForeignAttributes (line 3778) | public function adjustForeignAttributes($token) {
method insertForeignElement (line 3801) | public function insertForeignElement($token, $namespaceURI) {
method save (line 3835) | public function save() {
FILE: libraries/humble-http-agent/CookieJar.php
class CookieJar (line 24) | class CookieJar
method __construct (line 44) | function __construct() {
method debug (line 47) | protected function debug($msg, $file=null, $line=null) {
method getMatchingCookies (line 69) | public function getMatchingCookies($url)
method storeCookies (line 137) | public function storeCookies($url, $set_cookies)
method extractCookies (line 232) | public function extractCookies($h) {
method set_cookie (line 290) | function set_cookie($domain, $path, $name, $value, $secure=false, $exp...
method clear (line 312) | function clear($domain=null, $path=null, $name=null)
method _cmp_length (line 330) | function _cmp_length($a, $b)
method _reduce_domain (line 343) | function _reduce_domain($domain)
method _path_match (line 362) | function _path_match($path1, $path2)
method _domain_match (line 392) | function _domain_match($domain1, $domain2)
FILE: libraries/humble-http-agent/HumbleHttpAgent.php
class HumbleHttpAgent (line 18) | class HumbleHttpAgent
method __construct (line 62) | function __construct($requestOptions=null, $method=null) {
method initCache (line 103) | public function initCache($dir, $level = 0, $cleanup = 100, $life = 36...
method isCached (line 126) | private function isCached($url) {
method setCached (line 131) | private function setCached($url, $data) {
method getCached (line 136) | private function getCached($url) {
method debug (line 141) | protected function debug($msg) {
method getUserAgent (line 153) | protected function getUserAgent($url, $asArray=false) {
method rewriteHashbangFragment (line 180) | public function rewriteHashbangFragment($url) {
method getRedirectURLfromHTML (line 198) | public function getRedirectURLfromHTML($url, $html) {
method getMetaRefreshURL (line 206) | public function getMetaRefreshURL($url, $html) {
method getUglyURL (line 229) | public function getUglyURL($url, $html) {
method removeFragment (line 252) | public function removeFragment($url) {
method rewriteUrls (line 261) | public function rewriteUrls($url) {
method enableDebug (line 272) | public function enableDebug($bool=true) {
method minimiseMemoryUse (line 276) | public function minimiseMemoryUse($bool = true) {
method setMaxParallelRequests (line 280) | public function setMaxParallelRequests($max) {
method validateUrl (line 284) | public function validateUrl($url) {
method fetchAll (line 298) | public function fetchAll(array $urls) {
method fetchAllOnce (line 308) | public function fetchAllOnce(array $urls, $isRedirect=false) {
method handleCurlResponse (line 649) | public function handleCurlResponse($response, $info, $request) {
method headersToString (line 661) | protected function headersToString(array $headers, $associative=true) {
method get (line 677) | public function get($url, $remove=false, $gzdecode=true) {
method parallelSupport (line 713) | public function parallelSupport() {
method headerOnlyType (line 717) | private function headerOnlyType($headers) {
method possibleUnsupportedType (line 729) | private function possibleUnsupportedType($url) {
function gzdecode (line 741) | function gzdecode($data,&$filename='',&$error='',$maxlength=null)
FILE: libraries/humble-http-agent/RollingCurl.php
class RollingCurlRequest (line 14) | class RollingCurlRequest {
method __construct (line 30) | function __construct($url, $method = "GET", $post_data = null, $header...
method set_original_url (line 43) | public function set_original_url($url) {
method __destruct (line 49) | public function __destruct() {
class RollingCurlException (line 57) | class RollingCurlException extends Exception {
class RollingCurl (line 65) | class RollingCurl implements Countable {
method __construct (line 136) | function __construct($callback = null) {
method __get (line 144) | public function __get($name) {
method __set (line 153) | public function __set($name, $value) {
method count (line 168) | public function count() {
method add (line 178) | public function add($request) {
method request (line 193) | public function request($url, $method = "GET", $post_data = null, $hea...
method get (line 206) | public function get($url, $headers = null, $options = null) {
method post (line 219) | public function post($url, $post_data = null, $headers = null, $option...
method execute (line 229) | public function execute($window_size = null) {
method single_curl (line 245) | private function single_curl() {
method rolling_curl (line 273) | private function rolling_curl($window_size = null) {
method get_options (line 357) | private function get_options($request) {
method __destruct (line 399) | public function __destruct() {
FILE: libraries/humble-http-agent/SimplePie_HumbleHttpAgent.php
class SimplePie_HumbleHttpAgent (line 14) | class SimplePie_HumbleHttpAgent extends SimplePie_File
method set_agent (line 27) | public static function set_agent(HumbleHttpAgent $agent) {
method __construct (line 31) | public function __construct($url, $timeout = 10, $redirects = 5, $head...
FILE: libraries/language-detect/LanguageDetect.php
method __construct (line 181) | function __construct()
method _get_data_loc (line 205) | function _get_data_loc($fname)
method _readdb (line 221) | function _readdb($fname)
method _checkTrigram (line 251) | function _checkTrigram($trigram)
method omitLanguages (line 288) | public function omitLanguages($omit_list, $include_only = false)
method getLanguageCount (line 347) | function getLanguageCount()
method languageExists (line 359) | public function languageExists($lang)
method getLanguages (line 389) | function getLanguages()
method setPerlCompatible (line 403) | public function setPerlCompatible($setting = true)
method setNameMode (line 427) | function setNameMode($name_mode)
method useUnicodeBlocks (line 444) | public function useUnicodeBlocks($setting = true)
method _trigram (line 460) | function _trigram($text)
method _arr_rank (line 480) | function _arr_rank($arr)
method _bub_sort (line 513) | function _bub_sort(&$arr)
method _sort_func (line 553) | function _sort_func($a, $b)
method _distance (line 593) | function _distance($arr1, $arr2)
method _normalize_score (line 626) | function _normalize_score($score, $base_count = null)
method detect (line 665) | public function detect($sample, $limit = 0)
method detectSimple (line 806) | public function detectSimple($sample)
method detectConfidence (line 846) | public function detectConfidence($sample)
method detectUnicodeBlocks (line 893) | public function detectUnicodeBlocks($str, $skip_symbols)
method unicodeBlockName (line 922) | public function unicodeBlockName($unicode)
method _unicode_block_name (line 967) | function _unicode_block_name($unicode, $blocks, $block_count = -1)
method _read_unicode_block_db (line 1020) | function _read_unicode_block_db()
method languageSimilarity (line 1053) | public function languageSimilarity($lang1 = null, $lang2 = null)
method clusterLanguages (line 1146) | function clusterLanguages()
method clusteredSearch (line 1337) | public function clusteredSearch($str)
method utf8strlen (line 1463) | public static function utf8strlen($str)
method _utf8char2unicode (line 1482) | function _utf8char2unicode($char)
function _convertFromNameMode (line 1624) | function _convertFromNameMode($lang, $convertKey = false)
function _convertToNameMode (line 1664) | function _convertToNameMode($lang, $convertKey = false)
FILE: libraries/language-detect/LanguageDetect/Exception.php
class Text_LanguageDetect_Exception (line 2) | class Text_LanguageDetect_Exception extends Exception
FILE: libraries/language-detect/LanguageDetect/ISO639.php
class Text_LanguageDetect_ISO639 (line 29) | class Text_LanguageDetect_ISO639
method nameToCode2 (line 283) | public static function nameToCode2($lang)
method nameToCode3 (line 299) | public static function nameToCode3($lang)
method code2ToName (line 315) | public static function code2ToName($code)
method code3ToName (line 331) | public static function code3ToName($code)
FILE: libraries/language-detect/LanguageDetect/Parser.php
class Text_LanguageDetect_Parser (line 33) | class Text_LanguageDetect_Parser extends Text_LanguageDetect
method Text_LanguageDetect_Parser (line 105) | function Text_LanguageDetect_Parser($string) {
method validateString (line 115) | public static function validateString($str) {
method prepareTrigram (line 129) | function prepareTrigram($bool = true)
method prepareUnicode (line 140) | function prepareUnicode($bool = true)
method setPadStart (line 151) | function setPadStart($bool = true)
method setUnicodeSkipSymbols (line 162) | function setUnicodeSkipSymbols($bool = true)
method getTrigramRanks (line 173) | function &getTrigramRanks()
method getTrigramFreqs (line 186) | function &getTrigramFreqs()
method getUnicodeBlocks (line 197) | function &getUnicodeBlocks()
method analyze (line 213) | function analyze()
FILE: libraries/readability/ImageCaching.php
class ImageCaching (line 2) | class ImageCaching {
method __construct (line 15) | function __construct() {
method setAllowedSizes (line 29) | public function setAllowedSizes($lower, $upper) {
method cacheFromString (line 37) | public function cacheFromString(&$html) {
method cacheFromDocument (line 61) | public function cacheFromDocument(&$document) {
method getFileSize (line 86) | protected function getFileSize($image) {
method getImageDataURI (line 113) | protected function getImageDataURI($image, $mime = '') {
FILE: libraries/readability/JSLikeHTMLElement.php
class JSLikeHTMLElement (line 35) | class JSLikeHTMLElement extends DOMElement
method __set (line 43) | public function __set($name, $value) {
method __get (line 90) | public function __get($name)
method __toString (line 105) | public function __toString()
FILE: libraries/readability/Readability.php
class Readability (line 79) | class Readability
method __construct (line 186) | function __construct($html, $url=null, $parser='libxml', $use_tidy=tru...
method getTitle (line 247) | public function getTitle() {
method getContent (line 255) | public function getContent() {
method preserveImages (line 262) | public function preserveImages() {
method addPreFilter (line 273) | public function addPreFilter($filter, $replacer='') {
method addPostFilter (line 282) | public function addPostFilter($filter, $replacer='') {
method init (line 298) | public function init() {
method dbg (line 360) | protected function dbg($msg) {//, $error=false) {
method dump_dbg (line 368) | protected function dump_dbg() {
method postProcessContent (line 381) | public function postProcessContent($articleContent) {
method getArticleTitle (line 392) | protected function getArticleTitle() {
method prepDocument (line 439) | protected function prepDocument() {
method addFootnotes (line 467) | public function addFootnotes($articleContent) {
method prepArticle (line 532) | function prepArticle($articleContent) {
method initializeNode (line 629) | protected function initializeNode($node) {
method grabArticle (line 692) | protected function grabArticle($page=null) {
method removeScripts (line 1037) | public function removeScripts($doc) {
method getInnerText (line 1053) | public function getInnerText($e, $normalizeSpaces=true, $flattenLines=...
method cleanStyles (line 1070) | public function cleanStyles($e) {
method getCommaCount (line 1084) | public function getCommaCount($text) {
method getWordCount (line 1095) | public function getWordCount($text) {
method getLinkDensity (line 1108) | public function getLinkDensity($e, $excludeExternal=false) {
method weightAttribute (line 1131) | protected function weightAttribute($element, $attribute) {
method getWeight (line 1163) | public function getWeight($e) {
method killBreaks (line 1184) | public function killBreaks($node) {
method clean (line 1200) | public function clean($e, $tag) {
method cleanConditionally (line 1229) | public function cleanConditionally($e, $tag) {
method cleanHeaders (line 1344) | public function cleanHeaders($e) {
method flagIsActive (line 1355) | public function flagIsActive($flag) {
method addFlag (line 1359) | public function addFlag($flag) {
method removeFlag (line 1363) | public function removeFlag($flag) {
FILE: libraries/simplepie/autoloader.php
class SimplePie_Autoloader (line 60) | class SimplePie_Autoloader
method __construct (line 65) | public function __construct()
method autoload (line 75) | public function autoload($class)
FILE: libraries/simplepie/library/SimplePie.php
class SimplePie (line 413) | class SimplePie
method __construct (line 625) | public function __construct()
method __toString (line 658) | public function __toString()
method __destruct (line 666) | public function __destruct()
method force_feed (line 698) | public function force_feed($enable = false)
method set_feed_url (line 718) | public function set_feed_url($url)
method set_file (line 740) | public function set_file(&$file)
method set_raw_data (line 764) | public function set_raw_data($data)
method set_timeout (line 778) | public function set_timeout($timeout = 10)
method force_fsockopen (line 789) | public function force_fsockopen($enable = false)
method enable_cache (line 803) | public function enable_cache($enable = true)
method set_cache_duration (line 814) | public function set_cache_duration($seconds = 3600)
method set_autodiscovery_cache_duration (line 825) | public function set_autodiscovery_cache_duration($seconds = 604800)
method set_cache_location (line 835) | public function set_cache_location($location = './cache')
method enable_order_by_date (line 845) | public function enable_order_by_date($enable = true)
method set_input_encoding (line 858) | public function set_input_encoding($encoding = false)
method set_autodiscovery_level (line 882) | public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
method get_registry (line 894) | public function &get_registry()
method set_cache_class (line 910) | public function set_cache_class($class = 'SimplePie_Cache')
method set_locator_class (line 918) | public function set_locator_class($class = 'SimplePie_Locator')
method set_parser_class (line 926) | public function set_parser_class($class = 'SimplePie_Parser')
method set_file_class (line 934) | public function set_file_class($class = 'SimplePie_File')
method set_sanitize_class (line 942) | public function set_sanitize_class($class = 'SimplePie_Sanitize')
method set_item_class (line 950) | public function set_item_class($class = 'SimplePie_Item')
method set_author_class (line 958) | public function set_author_class($class = 'SimplePie_Author')
method set_category_class (line 966) | public function set_category_class($class = 'SimplePie_Category')
method set_enclosure_class (line 974) | public function set_enclosure_class($class = 'SimplePie_Enclosure')
method set_caption_class (line 982) | public function set_caption_class($class = 'SimplePie_Caption')
method set_copyright_class (line 990) | public function set_copyright_class($class = 'SimplePie_Copyright')
method set_credit_class (line 998) | public function set_credit_class($class = 'SimplePie_Credit')
method set_rating_class (line 1006) | public function set_rating_class($class = 'SimplePie_Rating')
method set_restriction_class (line 1014) | public function set_restriction_class($class = 'SimplePie_Restriction')
method set_content_type_sniffer_class (line 1022) | public function set_content_type_sniffer_class($class = 'SimplePie_Con...
method set_source_class (line 1030) | public function set_source_class($class = 'SimplePie_Source')
method set_useragent (line 1041) | public function set_useragent($ua = SIMPLEPIE_USERAGENT)
method set_cache_name_function (line 1051) | public function set_cache_name_function($function = 'md5')
method set_stupidly_fast (line 1067) | public function set_stupidly_fast($set = false)
method set_max_checked_feeds (line 1085) | public function set_max_checked_feeds($max = 10)
method remove_div (line 1090) | public function remove_div($enable = true)
method strip_htmltags (line 1095) | public function strip_htmltags($tags = '', $encode = null)
method encode_instead_of_strip (line 1108) | public function encode_instead_of_strip($enable = true)
method strip_attributes (line 1113) | public function strip_attributes($attribs = '')
method set_output_encoding (line 1144) | public function set_output_encoding($encoding = 'UTF-8')
method strip_comments (line 1149) | public function strip_comments($strip = false)
method set_url_replacements (line 1165) | public function set_url_replacements($element_attribute = null)
method set_image_handler (line 1176) | public function set_image_handler($page = false, $qs = 'i')
method set_item_limit (line 1193) | public function set_item_limit($limit = 0)
method init (line 1207) | public function init()
method fetch_data (line 1398) | protected function fetch_data(&$cache)
method error (line 1559) | public function error()
method get_raw_data (line 1572) | public function get_raw_data()
method get_encoding (line 1583) | public function get_encoding()
method handle_content_type (line 1607) | public function handle_content_type($mime = 'text/html')
method get_type (line 1650) | public function get_type()
method subscribe_url (line 1742) | public function subscribe_url()
method get_feed_tags (line 1785) | public function get_feed_tags($namespace, $tag)
method get_channel_tags (line 1833) | public function get_channel_tags($namespace, $tag)
method get_image_tags (line 1890) | public function get_image_tags($namespace, $tag)
method get_base (line 1938) | public function get_base($element = array())
method sanitize (line 1964) | public function sanitize($data, $type, $base = '')
method get_title (line 1977) | public function get_title()
method get_category (line 2020) | public function get_category($key = 0)
method get_categories (line 2041) | public function get_categories()
method get_author (line 2105) | public function get_author($key = 0)
method get_authors (line 2126) | public function get_authors()
method get_contributor (line 2203) | public function get_contributor($key = 0)
method get_contributors (line 2224) | public function get_contributors()
method get_link (line 2290) | public function get_link($key = 0, $rel = 'alternate')
method get_permalink (line 2314) | public function get_permalink()
method get_links (line 2328) | public function get_links($rel = 'alternate')
method get_all_discovered_feeds (line 2402) | public function get_all_discovered_feeds()
method get_description (line 2416) | public function get_description()
method get_copyright (line 2468) | public function get_copyright()
method get_language (line 2504) | public function get_language()
method get_latitude (line 2552) | public function get_latitude()
method get_longitude (line 2581) | public function get_longitude()
method get_image_title (line 2610) | public function get_image_title()
method get_image_url (line 2649) | public function get_image_url()
method get_image_link (line 2693) | public function get_image_link()
method get_image_width (line 2723) | public function get_image_width()
method get_image_height (line 2749) | public function get_image_height()
method get_item_quantity (line 2774) | public function get_item_quantity($max = 0)
method get_item (line 2800) | public function get_item($key = 0)
method get_items (line 2826) | public function get_items($start = 0, $end = 0)
method set_favicon_handler (line 2931) | public function set_favicon_handler($page = false, $qs = 'i')
method get_favicon (line 2943) | public function get_favicon()
method __call (line 2963) | public function __call($method, $args)
method sort_items (line 2993) | public static function sort_items($a, $b)
method merge_items (line 3011) | public static function merge_items($urls, $start = 0, $end = 0, $limit...
FILE: libraries/simplepie/library/SimplePie/Author.php
class SimplePie_Author (line 55) | class SimplePie_Author
method __construct (line 88) | public function __construct($name = null, $link = null, $email = null)
method __toString (line 100) | public function __toString()
method get_name (line 111) | public function get_name()
method get_link (line 128) | public function get_link()
method get_email (line 145) | public function get_email()
FILE: libraries/simplepie/library/SimplePie/Cache.php
class SimplePie_Cache (line 55) | class SimplePie_Cache
method __construct (line 72) | private function __construct() { }
method get_handler (line 82) | public static function get_handler($location, $filename, $extension)
method create (line 100) | public function create($location, $filename, $extension)
method register (line 112) | public static function register($type, $class)
method parse_URL (line 123) | public static function parse_URL($url)
FILE: libraries/simplepie/library/SimplePie/Cache/Base.php
type SimplePie_Cache_Base (line 54) | interface SimplePie_Cache_Base
method __construct (line 77) | public function __construct($location, $name, $type);
method save (line 85) | public function save($data);
method load (line 92) | public function load();
method mtime (line 99) | public function mtime();
method touch (line 106) | public function touch();
method unlink (line 113) | public function unlink();
FILE: libraries/simplepie/library/SimplePie/Cache/DB.php
class SimplePie_Cache_DB (line 51) | abstract class SimplePie_Cache_DB implements SimplePie_Cache_Base
method prepare_simplepie_object_for_cache (line 61) | protected static function prepare_simplepie_object_for_cache($data)
FILE: libraries/simplepie/library/SimplePie/Cache/File.php
class SimplePie_Cache_File (line 51) | class SimplePie_Cache_File implements SimplePie_Cache_Base
method __construct (line 89) | public function __construct($location, $name, $type)
method save (line 103) | public function save($data)
method load (line 123) | public function load()
method mtime (line 137) | public function mtime()
method touch (line 151) | public function touch()
method unlink (line 165) | public function unlink()
FILE: libraries/simplepie/library/SimplePie/Cache/Memcache.php
class SimplePie_Cache_Memcache (line 58) | class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
method __construct (line 88) | public function __construct($location, $name, $type)
method save (line 114) | public function save($data)
method load (line 128) | public function load()
method mtime (line 144) | public function mtime()
method touch (line 162) | public function touch()
method unlink (line 179) | public function unlink()
FILE: libraries/simplepie/library/SimplePie/Cache/MySQL.php
class SimplePie_Cache_MySQL (line 57) | class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
method __construct (line 87) | public function __construct($location, $name, $type)
method save (line 153) | public function save($data)
method load (line 291) | public function load()
method mtime (line 369) | public function mtime()
method touch (line 393) | public function touch()
method unlink (line 418) | public function unlink()
FILE: libraries/simplepie/library/SimplePie/Caption.php
class SimplePie_Caption (line 56) | class SimplePie_Caption
method __construct (line 104) | public function __construct($type = null, $lang = null, $startTime = n...
method __toString (line 118) | public function __toString()
method get_endtime (line 129) | public function get_endtime()
method get_language (line 147) | public function get_language()
method get_starttime (line 164) | public function get_starttime()
method get_text (line 181) | public function get_text()
method get_type (line 198) | public function get_type()
FILE: libraries/simplepie/library/SimplePie/Category.php
class SimplePie_Category (line 55) | class SimplePie_Category
method __construct (line 88) | public function __construct($term = null, $scheme = null, $label = null)
method __toString (line 100) | public function __toString()
method get_term (line 111) | public function get_term()
method get_scheme (line 128) | public function get_scheme()
method get_label (line 145) | public function get_label()
FILE: libraries/simplepie/library/SimplePie/Content/Type/Sniffer.php
class SimplePie_Content_Type_Sniffer (line 60) | class SimplePie_Content_Type_Sniffer
method __construct (line 74) | public function __construct($file)
method get_type (line 84) | public function get_type()
method text_or_binary (line 149) | public function text_or_binary()
method unknown (line 173) | public function unknown()
method image (line 222) | public function image()
method feed_or_html (line 256) | public function feed_or_html()
FILE: libraries/simplepie/library/SimplePie/Copyright.php
class SimplePie_Copyright (line 55) | class SimplePie_Copyright
method __construct (line 79) | public function __construct($url = null, $label = null)
method __toString (line 90) | public function __toString()
method get_url (line 101) | public function get_url()
method get_attribution (line 118) | public function get_attribution()
FILE: libraries/simplepie/library/SimplePie/Core.php
class SimplePie_Core (line 54) | class SimplePie_Core extends SimplePie
FILE: libraries/simplepie/library/SimplePie/Credit.php
class SimplePie_Credit (line 55) | class SimplePie_Credit
method __construct (line 87) | public function __construct($role = null, $scheme = null, $name = null)
method __toString (line 99) | public function __toString()
method get_role (line 110) | public function get_role()
method get_scheme (line 127) | public function get_scheme()
method get_name (line 144) | public function get_name()
FILE: libraries/simplepie/library/SimplePie/Decode/HTML/Entities.php
class SimplePie_Decode_HTML_Entities (line 54) | class SimplePie_Decode_HTML_Entities
method __construct (line 86) | public function __construct($data)
method parse (line 97) | public function parse()
method consume (line 114) | public function consume()
method consume_range (line 134) | public function consume_range($chars)
method unconsume (line 154) | public function unconsume()
method entity (line 165) | public function entity()
FILE: libraries/simplepie/library/SimplePie/Enclosure.php
class SimplePie_Enclosure (line 55) | class SimplePie_Enclosure
method __construct (line 227) | public function __construct($link = null, $type = null, $length = null...
method __toString (line 269) | public function __toString()
method get_bitrate (line 280) | public function get_bitrate()
method get_caption (line 298) | public function get_caption($key = 0)
method get_captions (line 316) | public function get_captions()
method get_category (line 334) | public function get_category($key = 0)
method get_categories (line 352) | public function get_categories()
method get_channels (line 369) | public function get_channels()
method get_copyright (line 386) | public function get_copyright()
method get_credit (line 404) | public function get_credit($key = 0)
method get_credits (line 422) | public function get_credits()
method get_description (line 439) | public function get_description()
method get_duration (line 457) | public function get_duration($convert = false)
method get_expression (line 482) | public function get_expression()
method get_extension (line 499) | public function get_extension()
method get_framerate (line 517) | public function get_framerate()
method get_handler (line 534) | public function get_handler()
method get_hash (line 546) | public function get_hash($key = 0)
method get_hashes (line 564) | public function get_hashes()
method get_height (line 581) | public function get_height()
method get_language (line 599) | public function get_language()
method get_keyword (line 617) | public function get_keyword($key = 0)
method get_keywords (line 635) | public function get_keywords()
method get_length (line 652) | public function get_length()
method get_link (line 669) | public function get_link()
method get_medium (line 687) | public function get_medium()
method get_player (line 705) | public function get_player()
method get_rating (line 723) | public function get_rating($key = 0)
method get_ratings (line 741) | public function get_ratings()
method get_restriction (line 759) | public function get_restriction($key = 0)
method get_restrictions (line 777) | public function get_restrictions()
method get_sampling_rate (line 794) | public function get_sampling_rate()
method get_size (line 811) | public function get_size()
method get_thumbnail (line 830) | public function get_thumbnail($key = 0)
method get_thumbnails (line 848) | public function get_thumbnails()
method get_title (line 865) | public function get_title()
method get_type (line 883) | public function get_type()
method get_width (line 900) | public function get_width()
method native_embed (line 920) | public function native_embed($options='')
method embed (line 970) | public function embed($options = '', $native = false)
method get_real_type (line 1205) | public function get_real_type($find_handler = false)
FILE: libraries/simplepie/library/SimplePie/Exception.php
class SimplePie_Exception (line 50) | class SimplePie_Exception extends Exception
FILE: libraries/simplepie/library/SimplePie/File.php
class SimplePie_File (line 56) | class SimplePie_File
method __construct (line 68) | public function __construct($url, $timeout = 10, $redirects = 5, $head...
FILE: libraries/simplepie/library/SimplePie/HTTP/Parser.php
class SimplePie_HTTP_Parser (line 52) | class SimplePie_HTTP_Parser
method __construct (line 136) | public function __construct($data)
method parse (line 147) | public function parse()
method has_data (line 175) | protected function has_data()
method is_linear_whitespace (line 185) | protected function is_linear_whitespace()
method http_version (line 197) | protected function http_version()
method status (line 224) | protected function status()
method reason (line 241) | protected function reason()
method new_line (line 252) | protected function new_line()
method name (line 289) | protected function name()
method linear_whitespace (line 315) | protected function linear_whitespace()
method value (line 335) | protected function value()
method value_char (line 374) | protected function value_char()
method quote (line 385) | protected function quote()
method quote_char (line 420) | protected function quote_char()
method quote_escaped (line 431) | protected function quote_escaped()
method body (line 441) | protected function body()
method chunked (line 458) | protected function chunked()
FILE: libraries/simplepie/library/SimplePie/IRI.php
class SimplePie_IRI (line 56) | class SimplePie_IRI
method __toString (line 138) | public function __toString()
method __set (line 149) | public function __set($name, $value)
method __get (line 174) | public function __get($name)
method __isset (line 227) | public function __isset($name)
method __unset (line 244) | public function __unset($name)
method __construct (line 257) | public function __construct($iri = null)
method absolutize (line 271) | public static function absolutize($base, $relative)
method parse_iri (line 364) | protected function parse_iri($iri)
method remove_dot_segments (line 404) | protected function remove_dot_segments($input)
method replace_invalid_with_pct_encoding (line 467) | protected function replace_invalid_with_pct_encoding($string, $extra_c...
method remove_iunreserved_percent_encoded (line 603) | protected function remove_iunreserved_percent_encoded($match)
method scheme_normalization (line 735) | protected function scheme_normalization()
method is_valid (line 769) | public function is_valid()
method set_iri (line 800) | public function set_iri($iri)
method set_scheme (line 857) | public function set_scheme($scheme)
method set_authority (line 882) | public function set_authority($authority)
method set_userinfo (line 948) | public function set_userinfo($iuserinfo)
method set_host (line 970) | public function set_host($ihost)
method set_port (line 1026) | public function set_port($port)
method set_path (line 1052) | public function set_path($ipath)
method set_query (line 1085) | public function set_query($iquery)
method set_fragment (line 1105) | public function set_fragment($ifragment)
method to_uri (line 1124) | public function to_uri($string)
method get_iri (line 1149) | public function get_iri()
method get_uri (line 1190) | public function get_uri()
method get_iauthority (line 1200) | protected function get_iauthority()
method get_authority (line 1230) | protected function get_authority()
FILE: libraries/simplepie/library/SimplePie/Item.php
class SimplePie_Item (line 56) | class SimplePie_Item
method __construct (line 91) | public function __construct($feed, $data)
method set_registry (line 105) | public function set_registry(SimplePie_Registry $registry)
method __toString (line 115) | public function __toString()
method __destruct (line 123) | public function __destruct()
method get_item_tags (line 145) | public function get_item_tags($namespace, $tag)
method get_base (line 165) | public function get_base($element = array())
method sanitize (line 180) | public function sanitize($data, $type, $base = '')
method get_feed (line 194) | public function get_feed()
method get_id (line 213) | public function get_id($hash = false)
method get_title (line 268) | public function get_title()
method get_description (line 323) | public function get_description($description_only = false)
method get_content (line 386) | public function get_content($content_only = false)
method get_category (line 417) | public function get_category($key = 0)
method get_categories (line 438) | public function get_categories()
method get_author (line 502) | public function get_author($key = 0)
method get_contributor (line 522) | public function get_contributor($key = 0)
method get_contributors (line 543) | public function get_contributors()
method get_authors (line 609) | public function get_authors()
method get_copyright (line 699) | public function get_copyright()
method get_date (line 733) | public function get_date($date_format = 'j F Y, g:i a')
method get_updated_date (line 812) | public function get_updated_date($date_format = 'j F Y, g:i a')
method get_local_date (line 865) | public function get_local_date($date_format = '%c')
method get_gmdate (line 888) | public function get_gmdate($date_format = 'j F Y, g:i a')
method get_updated_gmdate (line 906) | public function get_updated_gmdate($date_format = 'j F Y, g:i a')
method get_permalink (line 927) | public function get_permalink()
method get_link (line 953) | public function get_link($key = 0, $rel = 'alternate')
method get_links (line 975) | public function get_links($rel = 'alternate')
method get_enclosure (line 1059) | public function get_enclosure($key = 0, $prefer = null)
method get_enclosures (line 1086) | public function get_enclosures()
method get_latitude (line 2898) | public function get_latitude()
method get_longitude (line 2926) | public function get_longitude()
method get_source (line 2952) | public function get_source()
FILE: libraries/simplepie/library/SimplePie/Locator.php
class SimplePie_Locator (line 53) | class SimplePie_Locator
method __construct (line 68) | public function __construct(SimplePie_File $file, $timeout = 10, $user...
method set_registry (line 89) | public function set_registry(SimplePie_Registry $registry)
method find (line 94) | public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
method is_feed (line 145) | public function is_feed($file)
method get_base (line 170) | public function get_base()
method autodiscovery (line 195) | public function autodiscovery()
method search_elements_by_tag (line 213) | protected function search_elements_by_tag($name, &$done, $feeds)
method get_links (line 264) | public function get_links()
method extension (line 315) | public function extension(&$array)
method body (line 344) | public function body(&$array)
FILE: libraries/simplepie/library/SimplePie/Misc.php
class SimplePie_Misc (line 50) | class SimplePie_Misc
method time_hms (line 52) | public static function time_hms($seconds)
method absolutize_url (line 80) | public static function absolutize_url($relative, $base)
method get_element (line 98) | public static function get_element($realname, $string)
method element_implode (line 135) | public static function element_implode($element)
method error (line 154) | public static function error($message, $level, $file, $line)
method fix_protocol (line 195) | public static function fix_protocol($url, $http = 1)
method parse_url (line 227) | public static function parse_url($url)
method compress_parse_url (line 239) | public static function compress_parse_url($scheme = '', $authority = '...
method normalize_url (line 250) | public static function normalize_url($url)
method percent_encoding_normalization (line 256) | public static function percent_encoding_normalization($match)
method windows_1252_to_utf8 (line 276) | public static function windows_1252_to_utf8($string)
method change_encoding (line 291) | public static function change_encoding($data, $input, $output)
method change_encoding_mbstring (line 332) | protected static function change_encoding_mbstring($data, $input, $out...
method change_encoding_iconv (line 370) | protected static function change_encoding_iconv($data, $input, $output)
method encoding (line 386) | public static function encoding($charset)
method get_curl_version (line 1699) | public static function get_curl_version()
method strip_comments (line 1726) | public static function strip_comments($data)
method parse_date (line 1744) | public static function parse_date($dt)
method entities_decode (line 1757) | public static function entities_decode($data)
method uncomment_rfc822 (line 1769) | public static function uncomment_rfc822($string)
method parse_mime (line 1823) | public static function parse_mime($mime)
method atom_03_construct_type (line 1835) | public static function atom_03_construct_type($attribs)
method atom_10_construct_type (line 1871) | public static function atom_10_construct_type($attribs)
method atom_10_content_construct_type (line 1893) | public static function atom_10_content_construct_type($attribs)
method is_isegment_nz_nc (line 1924) | public static function is_isegment_nz_nc($string)
method space_seperated_tokens (line 1929) | public static function space_seperated_tokens($string)
method codepoint_to_utf8 (line 1955) | public static function codepoint_to_utf8($codepoint)
method parse_str (line 1995) | public static function parse_str($str)
method xml_encoding (line 2024) | public static function xml_encoding($data, $registry)
method output_javascript (line 2124) | public static function output_javascript()
method get_build (line 2163) | public static function get_build()
method debug (line 2195) | public static function debug(&$sp)
method silence_errors (line 2242) | public static function silence_errors($num, $str)
FILE: libraries/simplepie/library/SimplePie/Net/IPv6.php
class SimplePie_Net_IPv6 (line 59) | class SimplePie_Net_IPv6
method uncompress (line 79) | public static function uncompress($ip)
method compress (line 147) | public static function compress($ip)
method split_v6_v4 (line 195) | private static function split_v6_v4($ip)
method check_ipv6 (line 218) | public static function check_ipv6($ip)
method checkIPv6 (line 272) | public static function checkIPv6($ip)
FILE: libraries/simplepie/library/SimplePie/Parse/Date.php
class SimplePie_Parse_Date (line 52) | class SimplePie_Parse_Date
method __construct (line 542) | public function __construct()
method get (line 572) | public static function get()
method parse (line 590) | public function parse($date)
method add_callback (line 618) | public function add_callback($callback)
method date_w3cdtf (line 638) | public function date_w3cdtf($date)
method remove_rfc2822_comments (line 710) | public function remove_rfc2822_comments($string)
method date_rfc2822 (line 770) | public function date_rfc2822($date)
method date_rfc850 (line 863) | public function date_rfc850($date)
method date_asctime (line 928) | public function date_asctime($date)
method date_strtotime (line 970) | public function date_strtotime($date)
FILE: libraries/simplepie/library/SimplePie/Parser.php
class SimplePie_Parser (line 54) | class SimplePie_Parser
method set_registry (line 73) | public function set_registry(SimplePie_Registry $registry)
method parse (line 78) | public function parse(&$data, $encoding)
method get_error_code (line 238) | public function get_error_code()
method get_error_string (line 243) | public function get_error_string()
method get_current_line (line 248) | public function get_current_line()
method get_current_column (line 253) | public function get_current_column()
method get_current_byte (line 258) | public function get_current_byte()
method get_data (line 263) | public function get_data()
method tag_open (line 268) | public function tag_open($parser, $tag, $attributes)
method cdata (line 335) | public function cdata($parser, $cdata)
method tag_close (line 347) | public function tag_close($parser, $tag)
method split_ns (line 370) | public function split_ns($string)
FILE: libraries/simplepie/library/SimplePie/Rating.php
class SimplePie_Rating (line 55) | class SimplePie_Rating
method __construct (line 79) | public function __construct($scheme = null, $value = null)
method __toString (line 90) | public function __toString()
method get_scheme (line 101) | public function get_scheme()
method get_value (line 118) | public function get_value()
FILE: libraries/simplepie/library/SimplePie/Registry.php
class SimplePie_Registry (line 52) | class SimplePie_Registry
method __construct (line 104) | public function __construct() { }
method register (line 114) | public function register($type, $class, $legacy = false)
method get_class (line 139) | public function get_class($type)
method create (line 160) | public function &create($type, $parameters = array())
method call (line 202) | public function &call($type, $method, $parameters = array())
FILE: libraries/simplepie/library/SimplePie/Restriction.php
class SimplePie_Restriction (line 55) | class SimplePie_Restriction
method __construct (line 87) | public function __construct($relationship = null, $type = null, $value...
method __toString (line 99) | public function __toString()
method get_relationship (line 110) | public function get_relationship()
method get_type (line 127) | public function get_type()
method get_value (line 144) | public function get_value()
FILE: libraries/simplepie/library/SimplePie/Sanitize.php
class SimplePie_Sanitize (line 54) | class SimplePie_Sanitize
method __construct (line 75) | public function __construct()
method remove_div (line 81) | public function remove_div($enable = true)
method set_image_handler (line 86) | public function set_image_handler($page = false)
method set_registry (line 98) | public function set_registry(SimplePie_Registry $registry)
method pass_cache_data (line 103) | public function pass_cache_data($enable_cache = true, $cache_location ...
method pass_file_data (line 121) | public function pass_file_data($file_class = 'SimplePie_File', $timeou...
method strip_htmltags (line 139) | public function strip_htmltags($tags = array('base', 'blink', 'body', ...
method encode_instead_of_strip (line 158) | public function encode_instead_of_strip($encode = false)
method strip_attributes (line 163) | public function strip_attributes($attribs = array('bgsound', 'class', ...
method strip_comments (line 182) | public function strip_comments($strip = false)
method set_output_encoding (line 187) | public function set_output_encoding($encoding = 'UTF-8')
method set_url_replacements (line 203) | public function set_url_replacements($element_attribute = null)
method sanitize (line 225) | public function sanitize($data, $type, $base = '')
method preprocess (line 379) | protected function preprocess($html, $type)
method replace_urls (line 402) | public function replace_urls($document, $tag, $attributes)
method do_strip_htmltags (line 429) | public function do_strip_htmltags($match)
method strip_tag (line 454) | protected function strip_tag($tag, $document, $type)
method strip_attr (line 539) | protected function strip_attr($attrib, $document)
FILE: libraries/simplepie/library/SimplePie/Source.php
class SimplePie_Source (line 55) | class SimplePie_Source
method __construct (line 61) | public function __construct($item, $data)
method set_registry (line 67) | public function set_registry(SimplePie_Registry $registry)
method __toString (line 72) | public function __toString()
method get_source_tags (line 77) | public function get_source_tags($namespace, $tag)
method get_base (line 89) | public function get_base($element = array())
method sanitize (line 94) | public function sanitize($data, $type, $base = '')
method get_item (line 99) | public function get_item()
method get_title (line 104) | public function get_title()
method get_category (line 140) | public function get_category($key = 0)
method get_categories (line 153) | public function get_categories()
method get_author (line 210) | public function get_author($key = 0)
method get_authors (line 223) | public function get_authors()
method get_contributor (line 293) | public function get_contributor($key = 0)
method get_contributors (line 306) | public function get_contributors()
method get_link (line 364) | public function get_link($key = 0, $rel = 'alternate')
method get_permalink (line 380) | public function get_permalink()
method get_links (line 385) | public function get_links($rel = 'alternate')
method get_description (line 459) | public function get_description()
method get_copyright (line 503) | public function get_copyright()
method get_language (line 531) | public function get_language()
method get_latitude (line 555) | public function get_latitude()
method get_longitude (line 571) | public function get_longitude()
method get_image_url (line 591) | public function get_image_url()
FILE: libraries/simplepie/library/SimplePie/XML/Declaration/Parser.php
class SimplePie_XML_Declaration_Parser (line 52) | class SimplePie_XML_Declaration_Parser
method __construct (line 116) | public function __construct($data)
method parse (line 128) | public function parse()
method has_data (line 155) | public function has_data()
method skip_whitespace (line 165) | public function skip_whitespace()
method get_value (line 175) | public function get_value()
method before_version_name (line 192) | public function before_version_name()
method version_name (line 204) | public function version_name()
method version_equals (line 218) | public function version_equals()
method version_value (line 232) | public function version_value()
method encoding_name (line 252) | public function encoding_name()
method encoding_equals (line 266) | public function encoding_equals()
method encoding_value (line 280) | public function encoding_value()
method standalone_name (line 300) | public function standalone_name()
method standalone_equals (line 314) | public function standalone_equals()
method standalone_value (line 328) | public function standalone_value()
FILE: libraries/simplepie/library/SimplePie/gzdecode.php
class SimplePie_gzdecode (line 53) | class SimplePie_gzdecode
method __set (line 181) | public function __set($name, $value)
method __construct (line 191) | public function __construct($data)
method parse (line 202) | public function parse()
FILE: makefulltextfeed.php
function encodeURI (line 57) | function encodeURI($url) {
function autoload (line 84) | function autoload($class_name) {
class DummySingleItemFeed (line 528) | class DummySingleItemFeed {
method __construct (line 530) | function __construct($url) { $this->item = new DummySingleItem($url); }
method get_title (line 531) | public function get_title() { return ''; }
method get_description (line 532) | public function get_description() { return 'Content extracted from '.$...
method get_link (line 533) | public function get_link() { return $this->item->url; }
method get_language (line 534) | public function get_language() { return false; }
method get_image_url (line 535) | public function get_image_url() { return false; }
method get_items (line 536) | public function get_items($start=0, $max=1) { return array(0=>$this->i...
class DummySingleItem (line 538) | class DummySingleItem {
method __construct (line 540) | function __construct($url) { $this->url = $url; }
method get_permalink (line 541) | public function get_permalink() { return $this->url; }
method get_title (line 542) | public function get_title() { return null; }
method get_date (line 543) | public function get_date($format='') { return false; }
method get_author (line 544) | public function get_author($key=0) { return null; }
method get_authors (line 545) | public function get_authors() { return null; }
method get_description (line 546) | public function get_description() { return ''; }
method get_enclosure (line 547) | public function get_enclosure($key=0, $prefer=null) { return null; }
method get_enclosures (line 548) | public function get_enclosures() { return null; }
method get_categories (line 549) | public function get_categories() { return null; }
function get_excerpt (line 1009) | function get_excerpt($text, $num_words=55, $more=null) {
function url_allowed (line 1039) | function url_allowed($url) {
function convert_to_utf8 (line 1065) | function convert_to_utf8($html, $header=null)
function makeAbsolute (line 1144) | function makeAbsolute($base, $elem) {
function makeAbsoluteAttr (line 1159) | function makeAbsoluteAttr($base, $e, $attr) {
function makeAbsoluteStr (line 1172) | function makeAbsoluteStr($base, $url) {
function getSinglePage (line 1187) | function getSinglePage($item, $html, $url) {
function get_mime_action_info (line 1245) | function get_mime_action_info($headers) {
function remove_url_cruft (line 1268) | function remove_url_cruft($url) {
function make_substitutions (line 1275) | function make_substitutions($string) {
function get_cache (line 1283) | function get_cache() {
function get_url_cache (line 1312) | function get_url_cache() {
function is_cached (line 1341) | function is_cached($url) {
function set_cached (line 1346) | function set_cached($url, $data) {
function get_cached (line 1351) | function get_cached($url) {
function debug (line 1356) | function debug($msg) {
Condensed preview — 100 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,870K chars).
[
{
"path": "README.md",
"chars": 3286,
"preview": "Full-Text RSS\n=============\n\n### NOTE\n\nThis is a our public version of Full-Text RSS available to download for free from"
},
{
"path": "README.txt",
"chars": 1080,
"preview": "Full-Text RSS\n=============\n\nAbout\n-----\n\nSee http://fivefilters.org/content-only/ for a description of the code.\n\n\nInst"
},
{
"path": "UPDATING.txt",
"chars": 2133,
"preview": "Updating Full-Text RSS\n======================\n\nTo update your copy of Full-Text RSS to ensure feeds continue to be proce"
},
{
"path": "admin/apc.php",
"chars": 46604,
"preview": "<?php\n/*\n +----------------------------------------------------------------------+\n | APC (slightly modified for the F"
},
{
"path": "admin/codemirror/codemirror.css",
"chars": 4670,
"preview": ".CodeMirror {\n line-height: 1em;\n font-family: monospace;\n\n /* Necessary so the scrollbar can be absolutely positione"
},
{
"path": "admin/codemirror/codemirror.js",
"chars": 59606,
"preview": "var CodeMirror=function(){\"use strict\";function e(r,i){function un(e){if(s.onDragEvent&&s.onDragEvent(ln,I(e)))return;U("
},
{
"path": "admin/codemirror/properties.js",
"chars": 1692,
"preview": "CodeMirror.defineMode(\"properties\", function() {\n return {\n token: function(stream, state) {\n var sol = stream."
},
{
"path": "admin/edit-pattern.php",
"chars": 11672,
"preview": "<?php\n// Edit site config files for Full-Text RSS\n// Author: Keyvan Minoukadeh\n// Copyright (c) 2013 Keyvan Minoukadeh\n/"
},
{
"path": "admin/index.php",
"chars": 1702,
"preview": "<?php\n// Admin page for Full-Text RSS\n// Author: Keyvan Minoukadeh\n// Copyright (c) 2012 Keyvan Minoukadeh\n// License: A"
},
{
"path": "admin/login.php",
"chars": 1841,
"preview": "<?php\nheader(\"X-Robots-Tag: noindex, nofollow\", true);\nsession_start();\nrequire_once(dirname(dirname(__FILE__)).'/config"
},
{
"path": "admin/require_login.php",
"chars": 1411,
"preview": "<?php\n// Require login for admin access\n// Author: Keyvan Minoukadeh\n// Copyright (c) 2013 Keyvan Minoukadeh\n// License:"
},
{
"path": "admin/template.php",
"chars": 2357,
"preview": "<?php\nob_start();\nfunction tpl_header($title='Full-Text RSS Admin Area') {\nglobal $admin_page;\n?>\n<!DOCTYPE html>\n<html>"
},
{
"path": "admin/update.php",
"chars": 11264,
"preview": "<?php\n// Update site config files for Full-Text RSS\n// Author: Keyvan Minoukadeh\n// Copyright (c) 2013 Keyvan Minoukadeh"
},
{
"path": "cache/index.php",
"chars": 66,
"preview": "<?php\n// this is here to prevent directory listing over the web\n?>"
},
{
"path": "cache/rss/index.php",
"chars": 66,
"preview": "<?php\n// this is here to prevent directory listing over the web\n?>"
},
{
"path": "cache/urls/index.php",
"chars": 66,
"preview": "<?php\n// this is here to prevent directory listing over the web\n?>"
},
{
"path": "changelog.txt",
"chars": 9069,
"preview": "FiveFilters.org: Full-Text RSS\nhttp://fivefilters.org/content-only/\nCHANGELOG\n------------------------------------\n3.2 ("
},
{
"path": "cleancache.php",
"chars": 4161,
"preview": "<?php\n// Full-Text RSS: Clear Cache\n// Author: Keyvan Minoukadeh\n// Copyright (c) 2012 Keyvan Minoukadeh\n// License: AGP"
},
{
"path": "config.php",
"chars": 19992,
"preview": "<?php\n/* Full-Text RSS config */\n\n// ......IMPORTANT......................................\n// .........................."
},
{
"path": "css/feed.css",
"chars": 911,
"preview": "/* RSS CSS Document */\n\n* { margin:0; padding:0; }\n\np { padding: .5em 0; }\n\nh1,h2,h3,h4,h5,h6 { font-size: 1em; padding:"
},
{
"path": "css/feed.xsl",
"chars": 1580,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xm"
},
{
"path": "custom_config.php.demo",
"chars": 2775,
"preview": "<?php\n/* Full-Text RSS config */\n$options->debug = true;\n$options->default_entries = 15;\n$options->max_entries = 40;\n$op"
},
{
"path": "ftr_compatibility_test.php",
"chars": 16203,
"preview": "<?php\n/*\nFULL-TEXT-RSS V3 COMPATIBILITY TEST\n\n1) Upload ftr_compatibility_test.php to the web-accessible root of your we"
},
{
"path": "index.php",
"chars": 17245,
"preview": "<?php\nrequire_once(dirname(__FILE__).'/config.php');\n// check for custom index.php (custom_index.php)\nif (!defined('_FF_"
},
{
"path": "js/bootstrap-popover.js",
"chars": 2874,
"preview": "/* ===========================================================\n * bootstrap-popover.js v2.0.3\n * http://twitter.github.c"
},
{
"path": "js/bootstrap-tab.js",
"chars": 3384,
"preview": "/* ========================================================\n * bootstrap-tab.js v2.0.3\n * http://twitter.github.com/boot"
},
{
"path": "js/bootstrap-tooltip.js",
"chars": 7655,
"preview": "/* ===========================================================\n * bootstrap-tooltip.js v2.0.3\n * http://twitter.github.c"
},
{
"path": "libraries/Zend/Cache/Backend/ExtendedInterface.php",
"chars": 4085,
"preview": "<?php\n/**\n * Zend Framework\n *\n * LICENSE\n *\n * This source file is subject to the new BSD license that is bundled\n * wi"
},
{
"path": "libraries/Zend/Cache/Backend/File.php",
"chars": 35925,
"preview": "<?php\n/**\n * Zend Framework\n *\n * LICENSE\n *\n * This source file is subject to the new BSD license that is bundled\n * wi"
},
{
"path": "libraries/Zend/Cache/Backend/Interface.php",
"chars": 3906,
"preview": "<?php\n/**\n * Zend Framework\n *\n * LICENSE\n *\n * This source file is subject to the new BSD license that is bundled\n * wi"
},
{
"path": "libraries/Zend/Cache/Backend.php",
"chars": 8473,
"preview": "<?php\n/**\n * Zend Framework\n *\n * LICENSE\n *\n * This source file is subject to the new BSD license that is bundled\n * wi"
},
{
"path": "libraries/Zend/Cache/Core.php",
"chars": 25842,
"preview": "<?php\n/**\n * Zend Framework\n *\n * LICENSE\n *\n * This source file is subject to the new BSD license that is bundled\n * wi"
},
{
"path": "libraries/Zend/Cache/Exception.php",
"chars": 1069,
"preview": "<?php\n/**\n * Zend Framework\n *\n * LICENSE\n *\n * This source file is subject to the new BSD license that is bundled\n * wi"
},
{
"path": "libraries/Zend/Cache.php",
"chars": 9832,
"preview": "<?php\n/**\n * Zend Framework\n *\n * LICENSE\n *\n * This source file is subject to the new BSD license that is bundled\n * wi"
},
{
"path": "libraries/Zend/Exception.php",
"chars": 2557,
"preview": "<?php\n/**\n * Zend Framework\n *\n * LICENSE\n *\n * This source file is subject to the new BSD license that is bundled\n * wi"
},
{
"path": "libraries/content-extractor/ContentExtractor.php",
"chars": 25967,
"preview": "<?php\n/**\n * Content Extractor\n * \n * Uses patterns specified in site config files and auto detection (hNews/PHP Readabi"
},
{
"path": "libraries/content-extractor/SiteConfig.php",
"chars": 14034,
"preview": "<?php\n/**\n * Site Config\n * \n * Each instance of this class should hold extraction patterns and other directives\n * for "
},
{
"path": "libraries/feedwriter/FeedItem.php",
"chars": 4484,
"preview": "<?php\n /**\n * Univarsel Feed Writer\n * \n * FeedItem class - Used as feed element in FeedWriter class\n *\n * @package "
},
{
"path": "libraries/feedwriter/FeedWriter.php",
"chars": 11302,
"preview": "<?php\ndefine('RSS2', 1, true);\ndefine('JSON', 2, true);\ndefine('JSONP', 3, true);\n\n /**\n * Univarsel Feed Writer class\n "
},
{
"path": "libraries/htmLawed/htmLawed2.php",
"chars": 54335,
"preview": "<?php\n\n/*\nhtmLawed 1.2.b2, 9 June 2013\nCopyright Santosh Patnaik\nDual licensed with LGPL v3 and GPL v2+\nBased on PHP Lab"
},
{
"path": "libraries/html5/Data.php",
"chars": 4329,
"preview": "<?php\n\n// warning: this file is encoded in UTF-8!\n\nclass HTML5_Data\n{\n\n // at some point this should be moved to a .s"
},
{
"path": "libraries/html5/InputStream.php",
"chars": 10258,
"preview": "<?php\n\n/*\n\nCopyright 2009 Geoffrey Sneddon <http://gsnedders.com/>\n\nPermission is hereby granted, free of charge, to any"
},
{
"path": "libraries/html5/Parser.php",
"chars": 1147,
"preview": "<?php\n\nrequire_once dirname(__FILE__) . '/Data.php';\nrequire_once dirname(__FILE__) . '/InputStream.php';\nrequire_once d"
},
{
"path": "libraries/html5/Tokenizer.php",
"chars": 114658,
"preview": "<?php\n\n/*\n\nCopyright 2007 Jeroen van der Meer <http://jero.net/>\nCopyright 2008 Edward Z. Yang <http://htmlpurifier.org/"
},
{
"path": "libraries/html5/TreeBuilder.php",
"chars": 173022,
"preview": "<?php\n\n/*\n\nCopyright 2007 Jeroen van der Meer <http://jero.net/>\nCopyright 2009 Edward Z. Yang <edwardzyang@thewritingpo"
},
{
"path": "libraries/html5/named-character-references.ser",
"chars": 182163,
"preview": "a:52:{s:1:\"A\";a:16:{s:1:\"E\";a:1:{s:1:\"l\";a:1:{s:1:\"i\";a:1:{s:1:\"g\";a:2:{s:1:\";\";a:1:{s:9:\"codepoint\";i:198;}s:9:\"codepoi"
},
{
"path": "libraries/humble-http-agent/CookieJar.php",
"chars": 15475,
"preview": "<?php\n/**\n * Cookie Jar\n * \n * PHP class for handling cookies, as defined by the Netscape spec: \n * <http://curl.haxx.se"
},
{
"path": "libraries/humble-http-agent/HumbleHttpAgent.php",
"chars": 32217,
"preview": "<?php\n/**\n * Humble HTTP Agent\n * \n * This class is designed to take advantage of parallel HTTP requests\n * offered by P"
},
{
"path": "libraries/humble-http-agent/RollingCurl.php",
"chars": 11363,
"preview": "<?php\n/*\nAuthored by Josh Fraser (www.joshfraser.com)\nReleased under Apache License 2.0\n\nMaintained by Alexander Makarov"
},
{
"path": "libraries/humble-http-agent/SimplePie_HumbleHttpAgent.php",
"chars": 2375,
"preview": "<?php\n/**\n * Humble HTTP Agent extension for SimplePie_File\n * \n * This class is designed to extend and override SimpleP"
},
{
"path": "libraries/language-detect/LanguageDetect/Exception.php",
"chars": 932,
"preview": "<?php\nclass Text_LanguageDetect_Exception extends Exception\n{\n /**\n * Database file could not be found\n */\n "
},
{
"path": "libraries/language-detect/LanguageDetect/ISO639.php",
"chars": 9554,
"preview": "<?php\n/**\n * Part of Text_LanguageDetect\n *\n * PHP version 5\n *\n * @category Text\n * @package Text_LanguageDetect\n * "
},
{
"path": "libraries/language-detect/LanguageDetect/Parser.php",
"chars": 9424,
"preview": "<?php\n\n/**\n * This class represents a text sample to be parsed.\n *\n * @category Text\n * @package Text_LanguageDet"
},
{
"path": "libraries/language-detect/LanguageDetect.php",
"chars": 54224,
"preview": "<?php\n\n/**\n * Detects the language of a given piece of text.\n *\n * Attempts to detect the language of a sample of text b"
},
{
"path": "libraries/readability/ImageCaching.php",
"chars": 4346,
"preview": "<?php\nclass ImageCaching {\n\n\tconst UPPER_LIMIT = 256000;\n\tconst UPPER_MAX = 3145728;\n\tconst LOWER_LIMIT = 512;\n\tconst LO"
},
{
"path": "libraries/readability/JSLikeHTMLElement.php",
"chars": 3479,
"preview": "<?php\n/**\n* JavaScript-like HTML DOM Element\n*\n* This class extends PHP's DOMElement to allow\n* users to get and set the"
},
{
"path": "libraries/readability/Readability.php",
"chars": 50951,
"preview": "<?php\n/**\n* Arc90's Readability ported to PHP for FiveFilters.org\n* Based on readability.js version 1.7.1 (without multi"
},
{
"path": "libraries/simplepie/LICENSE.txt",
"chars": 1537,
"preview": "Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon.\nAll rights reserved.\n\nRedistribution and use in source and bi"
},
{
"path": "libraries/simplepie/autoloader.php",
"chars": 2873,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Author.php",
"chars": 3592,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Cache/Base.php",
"chars": 3452,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Cache/DB.php",
"chars": 4726,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Cache/File.php",
"chars": 4424,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Cache/Memcache.php",
"chars": 5141,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Cache/MySQL.php",
"chars": 12280,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Cache.php",
"chars": 4296,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Caption.php",
"chars": 4510,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Category.php",
"chars": 3707,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Content/Type/Sniffer.php",
"chars": 8137,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Copyright.php",
"chars": 3367,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Core.php",
"chars": 2268,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Credit.php",
"chars": 3721,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Decode/HTML/Entities.php",
"chars": 17321,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Enclosure.php",
"chars": 27487,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Exception.php",
"chars": 2187,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/File.php",
"chars": 9678,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/HTTP/Parser.php",
"chars": 10882,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/IRI.php",
"chars": 28359,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Item.php",
"chars": 98299,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Locator.php",
"chars": 11148,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Misc.php",
"chars": 51559,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Net/IPv6.php",
"chars": 7576,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Parse/Date.php",
"chars": 19577,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Parser.php",
"chars": 11851,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Rating.php",
"chars": 3451,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Registry.php",
"chars": 5991,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Restriction.php",
"chars": 3800,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Sanitize.php",
"chars": 15499,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/Source.php",
"chars": 20539,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/XML/Declaration/Parser.php",
"chars": 7149,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie/gzdecode.php",
"chars": 8572,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "libraries/simplepie/library/SimplePie.php",
"chars": 88121,
"preview": "<?php\n/**\n * SimplePie\n *\n * A PHP-Based RSS and Atom Feed Framework.\n * Takes the hard work out of managing a complete "
},
{
"path": "license.txt",
"chars": 34520,
"preview": " GNU AFFERO GENERAL PUBLIC LICENSE\n Version 3, 19 November 2007\n\n Copyright (C)"
},
{
"path": "makefulltextfeed.php",
"chars": 51721,
"preview": "<?php\n// Full-Text RSS: Create Full-Text Feeds\n// Author: Keyvan Minoukadeh\n// Copyright (c) 2013 Keyvan Minoukadeh\n// L"
},
{
"path": "manifest.yml",
"chars": 380,
"preview": "# This file is only used when deploying Full-Text RSS to AppFog.\n# See http://help.fivefilters.org/customer/portal/artic"
},
{
"path": "site_config/README.txt",
"chars": 245,
"preview": "Full-Text RSS Site Patterns\n---------------------------\n\nSite patterns allow you to specify what should be extracted fro"
},
{
"path": "site_config/custom/index.php",
"chars": 66,
"preview": "<?php\n// this is here to prevent directory listing over the web\n?>"
},
{
"path": "site_config/index.php",
"chars": 63,
"preview": "<?php\n// this is here to prevent directory listing over the web"
},
{
"path": "site_config/standard/.wikipedia.org.txt",
"chars": 638,
"preview": "title: //h1[@id='firstHeading']\nbody: //div[@id = 'bodyContent']\nstrip_id_or_class: editsection\n#strip_id_or_class: toc\n"
},
{
"path": "site_config/standard/version.txt",
"chars": 20,
"preview": "2013-05-12T22:53:07Z"
}
]
About this extraction
This page contains the full source code of the Dither/full-text-rss GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 100 files (1.6 MB), approximately 555.6k tokens, and a symbol index with 951 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.