<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[2499] sites/trunk/wordpress.org/public_html/wp-content: Plugins Directory: Adding the initial plugin directory plugin & theme.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://meta.trac.wordpress.org/changeset/2499">2499</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/2499","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>dd32</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2016-02-13 03:38:51 +0000 (Sat, 13 Feb 2016)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Plugins Directory: Adding the initial plugin directory plugin & theme.
These include a lot of hard-coded test data still, which will be iterated upon.</pre>

<h3>Added Paths</h3>
<ul>
<li>sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryplugindirectoryphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/plugin-directory.php</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryreadmeparserReadmeParserphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/ReadmeParser.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryreadmeparsercompatphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/compat.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryreadmeparsermarkdownphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/markdown.php</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsGruntfilejs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/Gruntfile.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsfilterbarphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/filter-bar.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsfooterphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/footer.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsfunctionsphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/functions.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsheaderphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/header.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsindexphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/index.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginspagephp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/page.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsplugincardphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/plugin-card.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginssinglepluginphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/single-plugin.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsstylecss">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/style.css</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginstemplatetagsphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/template-tags.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsviewintrophp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/view-intro.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryplugindirectoryphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/plugin-directory.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/plugin-directory.php                            (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/plugin-directory.php      2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,348 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/*
+ * Plugin Name: Plugin Repository
+ * Plugin URI: http://wordpress.org/plugins/
+ * Description: Transforms a WordPress site in The Official Plugin Directory.
+ * Version: 0.1
+ * Author: wordpressdotorg
+ * Author URI: http://wordpress.org/
+ * Text Domain: wporg-plugins
+ * License: GPLv2
+ * License URI: http://opensource.org/licenses/gpl-2.0.php
+ */
+
+class Plugin_Directory {
+
+       function __construct() {
+               register_activation_hook( __FILE__, array( $this, 'activate' ) );
+               register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
+
+               add_action( 'init', array( $this, 'init' ) );
+               add_filter( 'post_type_link', array( $this, 'package_link' ), 10, 2 );
+               add_filter( 'pre_insert_term', array( $this, 'pre_insert_term_prevent' ) );
+               add_action( 'pre_get_posts', array( $this, 'use_plugins_in_query' ) );
+               add_filter( 'the_content', array( $this, 'filter_post_content_to_correct_page' ), 1 );
+       }
+
+       function activate() {
+               global $wp_rewrite;
+
+               // Setup the environment
+               $this->init();
+
+               // %postname% is required
+               $wp_rewrite->set_permalink_structure( '/%postname%/' );
+
+               // /tags/%slug% is required for tags
+               $wp_rewrite->set_tag_base( '/tags' );
+
+               // We require the WordPress.org Ratings plugin also be active
+               if ( ! is_plugin_active( 'wporg-ratings/wporg-ratings.php' ) ) {
+                       activate_plugin( 'wporg-ratings/wporg-ratings.php' );
+               }
+       
+               // Enable the WordPress.org Theme Repo Theme
+               foreach ( wp_get_themes() as $theme ) {
+                       if ( $theme->get( 'Name' ) === 'WordPress.org Plugins' ) {
+                               switch_theme( $theme->get_stylesheet() );
+                               break;
+                       }
+               }
+       
+               flush_rewrite_rules();
+       
+               do_action( 'wporg_plugins_activation' );
+       }
+
+       function deactivate() {
+               flush_rewrite_rules();
+       
+               do_action( 'wporg_plugins_deactivation' );
+       }
+
+
+       function init() {
+               load_plugin_textdomain( 'wporg-plugins' );
+
+               register_post_type( 'plugin', array(
+                       'labels'      => array(
+                               'name'               => __( 'Plugins', 'wporg-plugins' ),
+                               'singular_name'      => __( 'Plugin', 'wporg-plugins' ),
+                               'add_new'            => __( 'Add New', 'wporg-plugins' ),
+                               'add_new_item'       => __( 'Add New Plugin', 'wporg-plugins' ),
+                               'edit_item'          => __( 'Edit Plugin', 'wporg-plugins' ),
+                               'new_item'           => __( 'New Plugin', 'wporg-plugins' ),
+                               'view_item'          => __( 'View Plugin', 'wporg-plugins' ),
+                               'search_items'       => __( 'Search Plugins', 'wporg-plugins' ),
+                               'not_found'          => __( 'No plugins found', 'wporg-plugins' ),
+                               'not_found_in_trash' => __( 'No plugins found in Trash', 'wporg-plugins' ),
+                               'menu_name'          => __( 'My Plugins', 'wporg-plugins' ),
+                       ),
+                       'description' => __( 'A package', 'wporg-plugins' ),
+                       'supports'    => array( 'title', 'editor', 'excerpt', 'custom-fields' ),
+                       'taxonomies'  => array( 'post_tag', 'category' ),
+                       'public'      => true,
+                       'show_ui'     => true,
+                       'has_archive' => true,
+                       'rewrite'     => false,
+                       'menu_icon'   => 'dashicons-admin-plugins',
+               ) );
+
+               register_post_status( 'pending', array(
+                       'label' => _x( 'Pending', 'plugin status', 'wporg-plugins' ),
+                       'public' => false,
+                       'show_in_admin_status_list' => true,
+                       'label_count' => _n_noop( 'Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>', 'wporg-plugins' ),
+               ) );
+               register_post_status( 'disabled', array(
+                       'label' => _x( 'Disabled', 'plugin status', 'wporg-plugins' ),
+                       'public' => false,
+                       'show_in_admin_status_list' => true,
+                       'label_count' => _n_noop( 'Disabled <span class="count">(%s)</span>', 'Disabled <span class="count">(%s)</span>', 'wporg-plugins' ),
+               ) );
+               register_post_status( 'closed', array(
+                       'label' => _x( 'Closed', 'plugin status', 'wporg-plugins' ),
+                       'public' => false,
+                       'show_in_admin_status_list' => true,
+                       'label_count' => _n_noop( 'Closed <span class="count">(%s)</span>', 'Closed <span class="count">(%s)</span>', 'wporg-plugins' ),
+               ) );
+       
+               // Add the browse/* views
+               add_rewrite_tag( '%browse%', '(featured|popular|beta|new|favorites)' );
+               add_permastruct( 'browse', 'browse/%browse%' );
+
+               add_rewrite_endpoint( 'installation', EP_PERMALINK );
+               add_rewrite_endpoint( 'faq',          EP_PERMALINK );
+               add_rewrite_endpoint( 'screenshots',  EP_PERMALINK );
+               add_rewrite_endpoint( 'changelog',    EP_PERMALINK );
+               add_rewrite_endpoint( 'stats',        EP_PERMALINK );
+               add_rewrite_endpoint( 'developers',   EP_PERMALINK );
+               add_rewrite_endpoint( 'other_notes',  EP_PERMALINK );
+       }
+
+       /**
+        * Filter the permalink for the Packages to be /post_name/
+        *
+        * @param string $link The generated permalink
+        * @param string $post The package object
+        * @return string
+        */
+       function package_link( $link, $post ) {
+               if ( 'plugin' != $post->post_type ) {
+                       return $link;
+               }
+       
+               return trailingslashit( home_url( $post->post_name ) );
+       }
+
+       /**
+        * Checks if ther current users is a super admin before allowing terms to be added.
+        *
+        * @param string           $term The term to add or update.
+        * @return string|WP_Error The term to add or update or WP_Error on failure.
+        */
+       function pre_insert_term_prevent( $term ) {
+               if ( ! is_super_admin() ) {
+                       $term = new WP_Error( 'not-allowed', __( 'You are not allowed to add terms.', 'wporg-plugins' ) );
+               }
+       
+               return $term;
+       }
+
+       function use_plugins_in_query( $wp_query ) {
+               if ( ! $wp_query->is_main_query() ) {
+                       return;
+               }
+
+               if ( empty( $wp_query->query_vars['pagename'] ) &&
+                       ( empty( $wp_query->query_vars['post_type'] ) || 'posts' == $wp_query->query_vars['post_type'] ) ) {
+                       $wp_query->query_vars['post_type'] = array( 'plugin' );
+               }
+
+               if ( empty( $wp_query->query ) ) {
+                       $wp_query->query_vars['browse'] = 'featured';
+               }
+
+               switch ( get_query_var( 'browse' ) ) {
+                       case 'beta':
+                               $wp_query->query_vars['category_name'] = 'beta';
+                               break;
+       
+                       case 'featured':
+                               $wp_query->query_vars['category_name'] = 'featured';
+                               break;
+       
+                       case 'favorites':
+                               break;
+       
+                       case 'popular':
+                               break;
+               }
+
+               // Re-route the Endpoints to the `content_page` query var.
+               if ( !empty( $wp_query->query['name'] ) ) {
+                       foreach ( array( 'installation', 'faq', 'screenshots', 'changelog', 'stats', 'developers', 'other_notes' ) as $plugin_field ) {
+                               if ( isset( $wp_query->query[ $plugin_field ] ) ) {
+                                       $wp_query->query['content_page'] = $wp_query->query_vars['content_page'] = $plugin_field;
+                                       unset( $wp_query->query[ $plugin_field ], $wp_query->query_vars[ $plugin_field ] );
+                               }
+                       }
+               }
+       }
+
+       function filter_post_content_to_correct_page( $content ) {
+               global $content_pages;
+
+               $post = get_post();
+               if ( 'plugin' != $post->post_type ) {
+                       return $content;
+               }
+
+               $page = get_query_var( 'content_page' );
+               $content_pages = $this->split_post_content_into_pages( $content );
+
+               if ( ! isset( $content_pages[ $page ] ) ) {
+                       $page = 'description';
+               }
+
+               return $content_pages[ $page ];
+       }
+
+       function split_post_content_into_pages( $content ) {
+               $content_pages = array(
+                       'stats' => '[wporg-plugins-stats]',
+                       'developers' => '[wporg-plugins-developer]',
+               );
+               $_pages = preg_split( "#<!--section=(.+?)-->#", $content, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
+               for ( $i = 0; $i < count( $_pages ); $i += 2 ) {
+                       // Don't overwrite existing tabs.
+                       if ( ! isset( $content_pages[ $_pages[ $i ] ] ) ) {
+                               $content_pages[ $_pages[ $i ] ] = $_pages[ $i + 1 ];
+                       }
+               }
+
+               return $content_pages;
+       }
+
+}
+new Plugin_Directory();
+
+// Various functions used by other processes, will make sense to move to specific classses.
+class Plugin_Directory_Tools {
+       static function get_readme_data( $readme ) {
+               // Uses https://github.com/rmccue/WordPress-Readme-Parser (with modifications)
+               include_once __DIR__ . '/readme-parser/markdown.php';
+               include_once __DIR__ . '/readme-parser/compat.php';
+
+               $data = (object) _WordPress_org_Readme::parse_readme( $readme );
+
+               unset( $data->sections['screenshots'] ); // Useless
+
+               // sanitize contributors.
+               foreach ( $data->contributors as $i => $name ) {
+                       if ( get_user_by( 'login', $name ) ) {
+                               continue;
+                       } elseif ( false !== ( $user = get_user_by( 'slug', $name ) ) ) {
+                               $data->contributors[] = $user->user_login;
+                               unset( $data->contributors[ $i ] );
+                       } else {
+                               unset( $data->contributors[ $i ] );
+                       }
+               }
+
+               return $data;
+       }
+}
+
+// Various helpers to retrieve data not stored within WordPress
+class Plugin_Directory_Template_Helpers {
+       static function get_active_installs_count( $plugin_slug ) {
+               global $wpdb;
+       
+               $count = wp_cache_get( $plugin_slug, 'plugin_active_installs' );
+               if ( false === $count ) {
+                       $count = (int) $wpdb->get_var( $wpdb->prepare(
+                               "SELECT count FROM rev2_daily_stat_summary WHERE type = 'plugin' AND type_name = %s AND stat = 'active_installs' LIMIT 1",
+                               $plugin_slug
+                       ) );
+                       wp_cache_add( $plugin_slug, $count, 'plugin_active_installs', 1200 );
+               }
+       
+               if ( $count < 10 ) {
+                       return 0;
+               }
+       
+               if ( $count >= 1000000 ) {
+                       return 1000000;
+               }
+       
+               return strval( $count )[0] * pow( 10, floor( log10( $count ) ) );
+       }
+
+       static function get_total_downloads() {
+               global $wpdb;
+
+               $count = wp_cache_get( 'plugin_download_count', 'plugin_download_count' );
+               if ( false === $count ) {
+                       $count = (int) $wpdb->get_var( "SELECT SUM(downloads) FROM `plugin_2_stats`" );
+                       wp_cache_add( 'plugin_download_count', $count, 'plugin_download_count', DAY_IN_SECONDS );
+               }
+
+               return $count;
+       }
+
+       static function get_plugin_sections() {
+               $plugin_slug  = get_post()->post_name;
+               $raw_sections = get_post_meta( get_the_ID(), 'sections', true );
+               $raw_sections = array_unique( array_merge( $raw_sections, array( 'description', 'stats', 'support', 'reviews', 'developers' ) ) );
+       
+               $sections = array();
+               foreach ( $raw_sections as $section_slug ) {
+                       $url = get_permalink();
+                       switch ( $section_slug ) {
+                               case 'description':
+                                       $title = _x( 'Description', 'plugin tab title', 'wporg-plugins' );
+                                       break;
+                               case 'installation':
+                                       $title = _x( 'Installation', 'plugin tab title', 'wporg-plugins' );
+                                       $url = trailingslashit( $url ) . '/' . $section_slug . '/';
+                                       break;
+                               case 'faq':
+                                       $title = _x( 'FAQ', 'plugin tab title', 'wporg-plugins' );
+                                       $url = trailingslashit( $url ) . '/' . $section_slug . '/';
+                                       break;
+                               case 'screenshots':
+                                       $title = _x( 'Screenshots', 'plugin tab title', 'wporg-plugins' );
+                                       $url = trailingslashit( $url ) . '/' . $section_slug . '/';
+                                       break;
+                               case 'changelog':
+                                       $title = _x( 'Changelog', 'plugin tab title', 'wporg-plugins' );
+                                       $url = trailingslashit( $url ) . '/' . $section_slug . '/';
+                                       break;
+                               case 'stats':
+                                       $title = _x( 'Stats', 'plugin tab title', 'wporg-plugins' );
+                                       $url = trailingslashit( $url ) . '/' . $section_slug . '/';
+                                       break;
+                               case 'support':
+                                       $title = _x( 'Support', 'plugin tab title', 'wporg-plugins' );
+                                       $url = 'https://wordpress.org/support/plugin/' . $plugin_slug;
+                                       break;
+                               case 'reviews':
+                                       $title = _x( 'Reviews', 'plugin tab title', 'wporg-plugins' );
+                                       $url = 'https://wordpress.org/support/view/plugin-reviews/' . $plugin_slug;
+                                       break;
+                               case 'developers':
+                                       $title = _x( 'Developers', 'plugin tab title', 'wporg-plugins' );
+                                       $url = trailingslashit( $url ) . '/' . $section_slug . '/';
+                                       break;
+                       }
+                       $sections[] = array(
+                               'slug'  => $section_slug,
+                               'url'   => $url,
+                               'title' => $title,
+                       );
+               }
+               return $sections;
+       }
+}
+       
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/plugin-directory.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryreadmeparserReadmeParserphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/ReadmeParser.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/ReadmeParser.php                          (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/ReadmeParser.php    2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,329 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Custom readme parser
+ *
+ * Based on Automattic_Readme from http://code.google.com/p/wordpress-plugin-readme-parser/
+ *
+ * Relies on Markdown_Extra
+ *
+ * @todo Handle screenshots section properly
+ * @todo Create validator for this based on http://code.google.com/p/wordpress-plugin-readme-parser/source/browse/trunk/validator.php
+ */
+class Baikonur_ReadmeParser {
+
+       public static function parse_readme($file) {
+               $contents = file($file);
+               return self::parse_readme_contents($contents);
+       }
+
+       public static function parse_readme_contents($contents) {
+               if (is_string($contents)) {
+                       $contents = explode("\n", $contents);
+               }
+
+               $this_class = __CLASS__;
+               if (function_exists('get_called_class')) {
+                       $this_class = get_called_class();
+               }
+
+               $contents = array_map(array($this_class, 'strip_newlines'), $contents);
+
+               // Strip BOM
+               if (strpos($contents[0], "\xEF\xBB\xBF") === 0) {
+                       $contents[0] = substr($contents[0], 3);
+               }
+
+               $data = new stdClass;
+
+               // Defaults
+               $data->is_excerpt = false;
+               $data->is_truncated = false;
+               $data->tags = array();
+               $data->requires = '';
+               $data->tested = '';
+               $data->contributors = array();
+               $data->stable_tag = '';
+               $data->version = '';
+               $data->donate_link = '';
+               $data->short_description = '';
+               $data->sections = array();
+               $data->changelog = array();
+               $data->upgrade_notice = array();
+               $data->screenshots = array();
+               $data->remaining_content = array();
+
+               $line = call_user_func_array(array($this_class, 'get_first_nonwhitespace'), array(&$contents));
+               $data->name = $line;
+               $data->name = trim($data->name, "#= ");
+
+               // Parse headers
+               $headers = array();
+
+               $line = call_user_func_array(array($this_class, 'get_first_nonwhitespace'), array(&$contents));
+               do {
+                       $key = $value = null;
+                       if (strpos($line, ':') === false) {
+                               break;
+                       }
+                       $bits = explode(':', $line, 2);
+                       list($key, $value) = $bits;
+                       $key = strtolower(str_replace(array(' ', "\t"), '_', trim($key)));
+                       if ($key === 'tags' && isset($headers['tags'])) {
+                               $headers[$key] .= ',' . trim($value);
+                       }
+                       else {
+                               $headers[$key] = trim($value);
+                       }
+               }
+               while (($line = array_shift($contents)) !== null && ($line = trim($line)) && !empty($line));
+               array_unshift($contents, $line);
+
+               if (!empty($headers['tags'])) {
+                       $data->tags = explode(',', $headers['tags']);
+                       $data->tags = array_map('trim', $data->tags);
+               }
+               if (!empty($headers['requires'])) {
+                       $data->requires = $headers['requires'];
+               }
+               if (!empty($headers['requires_at_least'])) {
+                       $data->requires = $headers['requires_at_least'];
+               }
+               if (!empty($headers['tested'])) {
+                       $data->tested = $headers['tested'];
+               }
+               if (!empty($headers['tested_up_to'])) {
+                       $data->tested = $headers['tested_up_to'];
+               }
+               if (!empty($headers['contributors'])) {
+                       $data->contributors = explode(',', $headers['contributors']);
+                       $data->contributors = array_map('trim', $data->contributors);
+               }
+               if (!empty($headers['stable_tag'])) {
+                       $data->stable_tag = $headers['stable_tag'];
+               }
+               if (!empty($headers['donate_link'])) {
+                       $data->donate_link = $headers['donate_link'];
+               }
+               if (!empty($headers['version'])) {
+                       $data->version = $headers['version'];
+               }
+               else {
+                       $data->version = $data->stable_tag;
+               }
+
+               // Parse the short description
+               while (($line = array_shift($contents)) !== null) {
+                       $trimmed = trim($line);
+                       if (empty($trimmed)) {
+                               $data->short_description .= "\n";
+                               continue;
+                       }
+                       if ($trimmed[0] === '=' && isset($trimmed[1]) && $trimmed[1] === '=') {
+                               array_unshift($contents, $line);
+                               break;
+                       }
+
+                       $data->short_description .= $line . "\n";
+               }
+               $data->short_description = trim($data->short_description);
+
+               $data->is_truncated = call_user_func_array(array($this_class, 'trim_short_desc'), array(&$data->short_description));
+
+               // Parse the rest of the body
+               $current = '';
+               $special = array('description', 'installation', 'faq', 'frequently_asked_questions', 'screenshots', 'changelog', 'upgrade_notice');
+
+               while (($line = array_shift($contents)) !== null) {
+                       $trimmed = trim($line);
+                       if (empty($trimmed)) {
+                               $current .= "\n";
+                               continue;
+                       }
+
+                       if ($trimmed[0] === '=' && isset($trimmed[1]) && $trimmed[1] === '=') {
+                               if (!empty($title)) {
+                                       $data->sections[$title] = trim($current);
+                               }
+
+                               $current = '';
+                               $real_title = trim($line, "#= \t");
+                               $title = strtolower(str_replace(' ', '_', $real_title));
+                               if ($title === 'faq') {
+                                       $title = 'frequently_asked_questions';
+                               }
+                               elseif ($title === 'change_log') {
+                                       $title = 'changelog';
+                               }
+                               if (!in_array($title, $special)) {
+                                       $current .= '<h3>' . $real_title . "</h3>";
+                               }
+                               continue;
+                       }
+
+                       $current .= $line . "\n";
+               }
+
+               if (!empty($title)) {
+                       $data->sections[$title] = trim($current);
+               }
+               $title = null;
+               $current = null;
+
+               if (empty($data->sections['description'])) {
+                       $data->sections['description'] = call_user_func(array($this_class, 'parse_markdown'), $data->short_description);
+               }
+
+               // Parse changelog
+               if (!empty($data->sections['changelog'])) {
+                       $lines = explode("\n", $data->sections['changelog']);
+                       while (($line = array_shift($lines)) !== null) {
+                               $trimmed = trim($line);
+                               if (empty($trimmed)) {
+                                       continue;
+                               }
+
+                               if ($trimmed[0] === '=') {
+                                       if (!empty($current)) {
+                                               $data->changelog[$title] = trim($current);
+                                       }
+
+                                       $current = '';
+                                       $title = trim($line, "#= \t");
+                                       continue;
+                               }
+
+                               $current .= $line . "\n";
+                       }
+
+                       $data->changelog[$title] = trim($current);
+               }
+               $title = null;
+               $current = null;
+
+               if (isset($data->sections['upgrade_notice'])) {
+                       $lines = explode("\n", $data->sections['upgrade_notice']);
+                       while (($line = array_shift($lines)) !== null) {
+                               $trimmed = trim($line);
+                               if (empty($trimmed)) {
+                                       continue;
+                               }
+
+                               if ($trimmed[0] === '=') {
+                                       if (!empty($current)) {
+                                               $data->upgrade_notice[$title] = trim($current);
+                                       }
+
+                                       $current = '';
+                                       $title = trim($line, "#= \t");
+                                       continue;
+                               }
+
+                               $current .= $line . "\n";
+                       }
+
+                       if (!empty($title) && !empty($current)) {
+                               $data->upgrade_notice[$title] = trim($current);
+                       }
+                       unset($data->sections['upgrade_notice']);
+               }
+
+               // Markdownify!
+
+               $data->sections = array_map(array($this_class, 'parse_markdown'), $data->sections);
+               $data->changelog = array_map(array($this_class, 'parse_markdown'), $data->changelog);
+               $data->upgrade_notice = array_map(array($this_class, 'parse_markdown'), $data->upgrade_notice);
+
+               if (isset($data->sections['screenshots'])) {
+                       preg_match_all('#<li>(.*?)</li>#is', $data->sections['screenshots'], $screenshots, PREG_SET_ORDER);
+                       if ($screenshots) {
+                               foreach ((array) $screenshots as $ss) {
+                                       $data->screenshots[] = trim($ss[1]);
+                               }
+                       }
+               }
+
+               // Rearrange stuff
+
+               $data->remaining_content = $data->sections;
+               $data->sections = array();
+
+               foreach ($special as $spec) {
+                       if (isset($data->remaining_content[$spec])) {
+                               $data->sections[$spec] = $data->remaining_content[$spec];
+                               unset($data->remaining_content[$spec]);
+                       }
+               }
+
+               return $data;
+       }
+
+       protected static function get_first_nonwhitespace(&$contents) {
+               while (($line = array_shift($contents)) !== null) {
+                       $trimmed = trim($line);
+                       if (!empty($line)) {
+                               break;
+                       }
+               }
+
+               return $line;
+       }
+
+       protected static function strip_newlines($line) {
+               return rtrim($line, "\r\n");
+       }
+
+       protected static function trim_short_desc(&$desc) {
+               if (function_exists('mb_strlen') && function_exists('mb_substr')) {
+                       if (mb_strlen($desc) > 150) {
+                               $desc = mb_substr($desc, 0, 150);
+                               $desc = trim($desc);
+                               return true;
+                       }
+               }
+               else {
+                       if (strlen($desc) > 150) {
+                               $desc = substr($desc, 0, 150);
+                               $desc = trim($desc);
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       protected static function parse_markdown($text) {
+               $text = self::code_trick($text);
+               $text = preg_replace('/^[\s]*=[\s]+(.+?)[\s]+=/m', "\n" . '<h4>$1</h4>' . "\n", $text);
+               $text = Markdown(trim($text));
+               return trim($text);
+       }
+
+       protected static function code_trick($text) {
+               // If doing markdown, first take any user formatted code blocks and turn them into backticks so that
+               // markdown will preserve things like underscores in code blocks
+               $text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array(__CLASS__, 'decodeit'), $text);
+
+               $text = str_replace(array("\r\n", "\r"), "\n", $text);
+               // Markdown can do inline code, we convert bbPress style block level code to Markdown style
+               $text = preg_replace_callback("!(^|\n)([ \t]*?)`(.*?)`!s", array(__CLASS__, 'indent'), $text);
+               return $text;
+       }
+
+       protected static function indent($matches) {
+               $text = $matches[3];
+               $text = preg_replace('|^|m', $matches[2] . '    ', $text);
+               return $matches[1] . $text;
+       }
+
+       protected static function decodeit($matches) {
+               $text = $matches[2];
+               $trans_table = array_flip(get_html_translation_table(HTML_ENTITIES));
+               $text = strtr($text, $trans_table);
+               $text = str_replace('<br />', '', $text);
+               $text = str_replace('&#38;', '&', $text);
+               $text = str_replace('&#39;', "'", $text);
+               if ( '<pre><code>' == $matches[1] )
+                       $text = "\n$text\n";
+               return "`$text`";
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/ReadmeParser.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryreadmeparsercompatphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/compat.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/compat.php                                (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/compat.php  2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,95 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+if ( !defined('WORDPRESS_README_MARKDOWN') ) {
+       define('WORDPRESS_README_MARKDOWN', dirname(__FILE__) . '/markdown.php');
+}
+
+require_once(dirname(__FILE__) . '/ReadmeParser.php');
+
+class _WordPress_org_Readme extends Baikonur_ReadmeParser {
+       public static function parse_readme($file) {
+               $contents = file($file);
+               return self::parse_readme_contents($contents);
+       }
+
+       public static function parse_readme_contents($contents) {
+               if (empty($contents)) {
+                       return array();
+               }
+
+               $result = parent::parse_readme_contents($contents);
+               foreach ($result->sections as &$section) {
+                       $section = self::filter_text($section);
+               }
+               if (!empty($result->upgrade_notice)) {
+                       foreach ($result->upgrade_notice as &$notice) {
+                               $notice = self::sanitize_text($notice);
+                       }
+               }
+               if (!empty($result->screenshots)) {
+                       foreach ($result->screenshots as &$shot) {
+                               $shot = self::filter_text($shot);
+                       }
+               }
+
+               if (!empty($result->remaining_content)) {
+                       $result->remaining_content = implode("\n", $result->remaining_content);
+                       $result->remaining_content = self::filter_text(str_replace("</h3>\n\n", "</h3>\n", $result->remaining_content));
+               }
+               else {
+                       $result->remaining_content = '';
+               }
+
+               $result->name = self::sanitize_text($result->name);
+               //$result->short_description = self::sanitize_text($result->short_description);
+               $result->donate_link = esc_url($result->donate_link);
+
+               $result->requires_at_least = $result->requires;
+               $result->tested_up_to = $result->tested;
+               unset($result->requires, $result->tested);
+               $result = ((array) $result);
+               return $result;
+       }
+
+       protected static function trim_short_desc(&$desc) {
+               $desc = self::sanitize_text($desc);
+               return parent::trim_short_desc($desc);
+       }
+
+       protected static function sanitize_text( $text ) { // not fancy
+               $text = strip_tags($text);
+               $text = esc_html($text);
+               $text = trim($text);
+               return $text;
+       }
+
+       protected static function filter_text( $text ) {
+               $text = trim($text);
+               //$text = self::code_trick($text); // A better parser than Markdown's for: backticks -> CODE
+
+               $allowed = array(
+                       'a' => array(
+                               'href' => array(),
+                               'title' => array(),
+                               'rel' => array()),
+                       'blockquote' => array('cite' => array()),
+                       'br' => array(),
+                       'p' => array(),
+                       'code' => array(),
+                       'pre' => array(),
+                       'em' => array(),
+                       'strong' => array(),
+                       'ul' => array(),
+                       'ol' => array(),
+                       'li' => array(),
+                       'h3' => array(),
+                       'h4' => array()
+               );
+
+               $text = balanceTags($text);
+
+               $text = wp_kses( $text, $allowed );
+               $text = trim($text);
+               return $text;
+       }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/compat.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginsplugindirectoryreadmeparsermarkdownphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/markdown.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/markdown.php                              (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/markdown.php        2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,2932 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+#
+# Markdown Extra  -  A text-to-HTML conversion tool for web writers
+#
+# PHP Markdown & Extra
+# Copyright (c) 2004-2009 Michel Fortin  
+# <http://michelf.com/projects/php-markdown/>
+#
+# Original Markdown
+# Copyright (c) 2004-2006 John Gruber  
+# <http://daringfireball.net/projects/markdown/>
+#
+
+
+define( 'MARKDOWN_VERSION',  "1.0.1n" ); # Sat 10 Oct 2009
+define( 'MARKDOWNEXTRA_VERSION',  "1.2.4" ); # Sat 10 Oct 2009
+
+
+#
+# Global default settings:
+#
+
+# Change to ">" for HTML output
+@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX',  " />");
+
+# Define the width of a tab for code blocks.
+@define( 'MARKDOWN_TAB_WIDTH',     4 );
+
+# Optional title attribute for footnote links and backlinks.
+@define( 'MARKDOWN_FN_LINK_TITLE',         "" );
+@define( 'MARKDOWN_FN_BACKLINK_TITLE',     "" );
+
+# Optional class attribute for footnote links and backlinks.
+@define( 'MARKDOWN_FN_LINK_CLASS',         "" );
+@define( 'MARKDOWN_FN_BACKLINK_CLASS',     "" );
+
+
+#
+# WordPress settings:
+#
+
+# Change to false to remove Markdown from posts and/or comments.
+@define( 'MARKDOWN_WP_POSTS',      true );
+@define( 'MARKDOWN_WP_COMMENTS',   true );
+
+
+
+### Standard Function Interface ###
+
+@define( 'MARKDOWN_PARSER_CLASS',  'MarkdownExtra_Parser' );
+
+function Markdown($text) {
+#
+# Initialize the parser and return the result of its transform method.
+#
+       # Setup static parser variable.
+       static $parser;
+       if (!isset($parser)) {
+               $parser_class = MARKDOWN_PARSER_CLASS;
+               $parser = new $parser_class;
+       }
+
+       # Transform text using parser.
+       return $parser->transform($text);
+}
+
+
+### WordPress Plugin Interface ###
+
+/*
+Plugin Name: Markdown Extra
+Plugin URI: http://michelf.com/projects/php-markdown/
+Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.com/projects/php-markdown/">More...</a>
+Version: 1.2.4
+Author: Michel Fortin
+Author URI: http://michelf.com/
+*/
+
+if (isset($wp_version)) {
+       # More details about how it works here:
+       # <http://michelf.com/weblog/2005/wordpress-text-flow-vs-markdown/>
+       
+       # Post content and excerpts
+       # - Remove WordPress paragraph generator.
+       # - Run Markdown on excerpt, then remove all tags.
+       # - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
+       if (MARKDOWN_WP_POSTS) {
+               remove_filter('the_content',     'wpautop');
+        remove_filter('the_content_rss', 'wpautop');
+               remove_filter('the_excerpt',     'wpautop');
+               add_filter('the_content',     'mdwp_MarkdownPost', 6);
+        add_filter('the_content_rss', 'mdwp_MarkdownPost', 6);
+               add_filter('get_the_excerpt', 'mdwp_MarkdownPost', 6);
+               add_filter('get_the_excerpt', 'trim', 7);
+               add_filter('the_excerpt',     'mdwp_add_p');
+               add_filter('the_excerpt_rss', 'mdwp_strip_p');
+               
+               remove_filter('content_save_pre',  'balanceTags', 50);
+               remove_filter('excerpt_save_pre',  'balanceTags', 50);
+               add_filter('the_content',         'balanceTags', 50);
+               add_filter('get_the_excerpt', 'balanceTags', 9);
+       }
+       
+       # Add a footnote id prefix to posts when inside a loop.
+       function mdwp_MarkdownPost($text) {
+               static $parser;
+               if (!$parser) {
+                       $parser_class = MARKDOWN_PARSER_CLASS;
+                       $parser = new $parser_class;
+               }
+               if (is_single() || is_page() || is_feed()) {
+                       $parser->fn_id_prefix = "";
+               } else {
+                       $parser->fn_id_prefix = get_the_ID() . ".";
+               }
+               return $parser->transform($text);
+       }
+       
+       # Comments
+       # - Remove WordPress paragraph generator.
+       # - Remove WordPress auto-link generator.
+       # - Scramble important tags before passing them to the kses filter.
+       # - Run Markdown on excerpt then remove paragraph tags.
+       if (MARKDOWN_WP_COMMENTS) {
+               remove_filter('comment_text', 'wpautop', 30);
+               remove_filter('comment_text', 'make_clickable');
+               add_filter('pre_comment_content', 'Markdown', 6);
+               add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
+               add_filter('pre_comment_content', 'mdwp_show_tags', 12);
+               add_filter('get_comment_text',    'Markdown', 6);
+               add_filter('get_comment_excerpt', 'Markdown', 6);
+               add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
+       
+               global $mdwp_hidden_tags, $mdwp_placeholders;
+               $mdwp_hidden_tags = explode(' ',
+                       '<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
+               $mdwp_placeholders = explode(' ', str_rot13(
+                       'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
+                       'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
+       }
+       
+       function mdwp_add_p($text) {
+               if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
+                       $text = '<p>'.$text.'</p>';
+                       $text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text);
+               }
+               return $text;
+       }
+       
+       function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); }
+
+       function mdwp_hide_tags($text) {
+               global $mdwp_hidden_tags, $mdwp_placeholders;
+               return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
+       }
+       function mdwp_show_tags($text) {
+               global $mdwp_hidden_tags, $mdwp_placeholders;
+               return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
+       }
+}
+
+
+### bBlog Plugin Info ###
+
+function identify_modifier_markdown() {
+       return array(
+               'name' => 'markdown',
+               'type' => 'modifier',
+               'nicename' => 'PHP Markdown Extra',
+               'description' => 'A text-to-HTML conversion tool for web writers',
+               'authors' => 'Michel Fortin and John Gruber',
+               'licence' => 'GPL',
+               'version' => MARKDOWNEXTRA_VERSION,
+               'help' => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.com/projects/php-markdown/">More...</a>',
+               );
+}
+
+
+### Smarty Modifier Interface ###
+
+function smarty_modifier_markdown($text) {
+       return Markdown($text);
+}
+
+
+### Textile Compatibility Mode ###
+
+# Rename this file to "classTextile.php" and it can replace Textile everywhere.
+
+if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
+       # Try to include PHP SmartyPants. Should be in the same directory.
+       @include_once 'smartypants.php';
+       # Fake Textile class. It calls Markdown instead.
+       class Textile {
+               function TextileThis($text, $lite='', $encode='') {
+                       if ($lite == '' && $encode == '')    $text = Markdown($text);
+                       if (function_exists('SmartyPants'))  $text = SmartyPants($text);
+                       return $text;
+               }
+               # Fake restricted version: restrictions are not supported for now.
+               function TextileRestricted($text, $lite='', $noimage='') {
+                       return $this->TextileThis($text, $lite);
+               }
+               # Workaround to ensure compatibility with TextPattern 4.0.3.
+               function blockLite($text) { return $text; }
+       }
+}
+
+
+
+#
+# Markdown Parser Class
+#
+
+class Markdown_Parser {
+
+       # Regex to match balanced [brackets].
+       # Needed to insert a maximum bracked depth while converting to PHP.
+       var $nested_brackets_depth = 6;
+       var $nested_brackets_re;
+       
+       var $nested_url_parenthesis_depth = 4;
+       var $nested_url_parenthesis_re;
+
+       # Table of hash values for escaped characters:
+       var $escape_chars = '\`*_{}[]()>#+-.!';
+       var $escape_chars_re;
+
+       # Change to ">" for HTML output.
+       var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
+       var $tab_width = MARKDOWN_TAB_WIDTH;
+       
+       # Change to `true` to disallow markup or entities.
+       var $no_markup = false;
+       var $no_entities = false;
+       
+       # Predefined urls and titles for reference links and images.
+       var $predef_urls = array();
+       var $predef_titles = array();
+
+
+       function Markdown_Parser() {
+       #
+       # Constructor function. Initialize appropriate member variables.
+       #
+               $this->_initDetab();
+               $this->prepareItalicsAndBold();
+       
+               $this->nested_brackets_re = 
+                       str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
+                       str_repeat('\])*', $this->nested_brackets_depth);
+       
+               $this->nested_url_parenthesis_re = 
+                       str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
+                       str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
+               
+               $this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
+               
+               # Sort document, block, and span gamut in ascendent priority order.
+               asort($this->document_gamut);
+               asort($this->block_gamut);
+               asort($this->span_gamut);
+       }
+
+
+       # Internal hashes used during transformation.
+       var $urls = array();
+       var $titles = array();
+       var $html_hashes = array();
+       
+       # Status flag to avoid invalid nesting.
+       var $in_anchor = false;
+       
+       
+       function setup() {
+       #
+       # Called before the transformation process starts to setup parser 
+       # states.
+       #
+               # Clear global hashes.
+               $this->urls = $this->predef_urls;
+               $this->titles = $this->predef_titles;
+               $this->html_hashes = array();
+               
+               $in_anchor = false;
+       }
+       
+       function teardown() {
+       #
+       # Called after the transformation process to clear any variable 
+       # which may be taking up memory unnecessarly.
+       #
+               $this->urls = array();
+               $this->titles = array();
+               $this->html_hashes = array();
+       }
+
+
+       function transform($text) {
+       #
+       # Main function. Performs some preprocessing on the input text
+       # and pass it through the document gamut.
+       #
+               $this->setup();
+       
+               # Remove UTF-8 BOM and marker character in input, if present.
+               $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
+
+               # Standardize line endings:
+               #   DOS to Unix and Mac to Unix
+               $text = preg_replace('{\r\n?}', "\n", $text);
+
+               # Make sure $text ends with a couple of newlines:
+               $text .= "\n\n";
+
+               # Convert all tabs to spaces.
+               $text = $this->detab($text);
+
+               # Turn block-level HTML blocks into hash entries
+               $text = $this->hashHTMLBlocks($text);
+
+               # Strip any lines consisting only of spaces and tabs.
+               # This makes subsequent regexen easier to write, because we can
+               # match consecutive blank lines with /\n+/ instead of something
+               # contorted like /[ ]*\n+/ .
+               $text = preg_replace('/^[ ]+$/m', '', $text);
+
+               # Run document gamut methods.
+               foreach ($this->document_gamut as $method => $priority) {
+                       $text = $this->$method($text);
+               }
+               
+               $this->teardown();
+
+               return $text . "\n";
+       }
+       
+       var $document_gamut = array(
+               # Strip link definitions, store in hashes.
+               "stripLinkDefinitions" => 20,
+               
+               "runBasicBlockGamut"   => 30,
+               );
+
+
+       function stripLinkDefinitions($text) {
+       #
+       # Strips link definitions from text, stores the URLs and titles in
+       # hash references.
+       #
+               $less_than_tab = $this->tab_width - 1;
+
+               # Link defs are in the form: ^[id]: url "optional title"
+               $text = preg_replace_callback('{
+                                                       ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
+                                                         [ ]*
+                                                         \n?                           # maybe *one* newline
+                                                         [ ]*
+                                                       (?:
+                                                         <(.+?)>                 # url = $2
+                                                       |
+                                                         (\S+?)                        # url = $3
+                                                       )
+                                                         [ ]*
+                                                         \n?                           # maybe one newline
+                                                         [ ]*
+                                                       (?:
+                                                               (?<=\s)                      # lookbehind for whitespace
+                                                               ["(]
+                                                               (.*?)                   # title = $4
+                                                               [")]
+                                                               [ ]*
+                                                       )?      # title is optional
+                                                       (?:\n+|\Z)
+                       }xm',
+                       array(&$this, '_stripLinkDefinitions_callback'),
+                       $text);
+               return $text;
+       }
+       function _stripLinkDefinitions_callback($matches) {
+               $link_id = strtolower($matches[1]);
+               $url = $matches[2] == '' ? $matches[3] : $matches[2];
+               $this->urls[$link_id] = $url;
+               $this->titles[$link_id] =& $matches[4];
+               return ''; # String that will replace the block
+       }
+
+
+       function hashHTMLBlocks($text) {
+               if ($this->no_markup)  return $text;
+
+               $less_than_tab = $this->tab_width - 1;
+
+               # Hashify HTML blocks:
+               # We only want to do this for block-level HTML tags, such as headers,
+               # lists, and tables. That's because we still want to wrap <p>s around
+               # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+               # phrase emphasis, and spans. The list of tags we're looking for is
+               # hard-coded:
+               #
+               # *  List "a" is made of tags which can be both inline or block-level.
+               #    These will be treated block-level when the start tag is alone on 
+               #    its line, otherwise they're not matched here and will be taken as 
+               #    inline later.
+               # *  List "b" is made of tags which are always block-level;
+               #
+               $block_tags_a_re = 'ins|del';
+               $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
+                                                  'script|noscript|form|fieldset|iframe|math';
+
+               # Regular expression for the content of a block tag.
+               $nested_tags_level = 4;
+               $attr = '
+                       (?>                          # optional tag attributes
+                         \s                    # starts with whitespace
+                         (?>
+                               [^>"/]+         # text outside quotes
+                         |
+                               /+(?!>)              # slash not followed by ">"
+                         |
+                               "[^"]*"          # text inside double quotes (tolerate ">")
+                         |
+                               \'[^\']*\'      # text inside single quotes (tolerate ">")
+                         )*
+                       )?      
+                       ';
+               $content =
+                       str_repeat('
+                               (?>
+                                 [^<]+                      # content without tag
+                               |
+                                 <\2                        # nested opening tag
+                                       '.$attr.'       # attributes
+                                       (?>
+                                         />
+                                       |
+                                         >', $nested_tags_level).   # end of opening tag
+                                         '.*?'.                                        # last level nested tag content
+                       str_repeat('
+                                         </\2\s*>        # closing nested tag
+                                       )
+                                 |                             
+                                       <(?!/\2\s*>       # other tags with a different name
+                                 )
+                               )*',
+                               $nested_tags_level);
+               $content2 = str_replace('\2', '\3', $content);
+
+               # First, look for nested blocks, e.g.:
+               #       <div>
+               #               <div>
+               #               tags for inner block must be indented.
+               #               </div>
+               #       </div>
+               #
+               # The outermost tags must start at the left margin for this to match, and
+               # the inner nested divs must be indented.
+               # We need to do this before the next, more liberal match, because the next
+               # match will start at the first `<div>` and stop at the first `</div>`.
+               $text = preg_replace_callback('{(?>
+                       (?>
+                               (?<=\n\n)            # Starting after a blank line
+                               |                               # or
+                               \A\n?                   # the beginning of the doc
+                       )
+                       (                                               # save in $1
+
+                         # Match from `\n<tag>` to `</tag>\n`, handling nested tags 
+                         # in between.
+                                       
+                                               [ ]{0,'.$less_than_tab.'}
+                                               <('.$block_tags_b_re.')# start tag = $2
+                                               '.$attr.'>                   # attributes followed by > and \n
+                                               '.$content.'            # content, support nesting
+                                               </\2>                             # the matching end tag
+                                               [ ]*                            # trailing spaces/tabs
+                                               (?=\n+|\Z)      # followed by a newline or end of document
+
+                       | # Special version for tags of group a.
+
+                                               [ ]{0,'.$less_than_tab.'}
+                                               <('.$block_tags_a_re.')# start tag = $3
+                                               '.$attr.'>[ ]*\n     # attributes followed by >
+                                               '.$content2.'           # content, support nesting
+                                               </\3>                             # the matching end tag
+                                               [ ]*                            # trailing spaces/tabs
+                                               (?=\n+|\Z)      # followed by a newline or end of document
+                                       
+                       | # Special case just for <hr />. It was easier to make a special 
+                         # case than to make the other regex more complicated.
+                       
+                                               [ ]{0,'.$less_than_tab.'}
+                                               <(hr)                                # start tag = $2
+                                               '.$attr.'                       # attributes
+                                               /?>                                  # the matching end tag
+                                               [ ]*
+                                               (?=\n{2,}|\Z)           # followed by a blank line or end of document
+                       
+                       | # Special case for standalone HTML comments:
+                       
+                                       [ ]{0,'.$less_than_tab.'}
+                                       (?s:
+                                               <!-- .*? -->
+                                       )
+                                       [ ]*
+                                       (?=\n{2,}|\Z)           # followed by a blank line or end of document
+                       
+                       | # PHP and ASP-style processor instructions (<? and <%)
+                       
+                                       [ ]{0,'.$less_than_tab.'}
+                                       (?s:
+                                               <([?%])                      # $2
+                                               .*?
+                                               \2>
+                                       )
+                                       [ ]*
+                                       (?=\n{2,}|\Z)           # followed by a blank line or end of document
+                                       
+                       )
+                       )}Sxmi',
+                       array(&$this, '_hashHTMLBlocks_callback'),
+                       $text);
+
+               return $text;
+       }
+       function _hashHTMLBlocks_callback($matches) {
+               $text = $matches[1];
+               $key  = $this->hashBlock($text);
+               return "\n\n$key\n\n";
+       }
+       
+       
+       function hashPart($text, $boundary = 'X') {
+       #
+       # Called whenever a tag must be hashed when a function insert an atomic 
+       # element in the text stream. Passing $text to through this function gives
+       # a unique text-token which will be reverted back when calling unhash.
+       #
+       # The $boundary argument specify what character should be used to surround
+       # the token. By convension, "B" is used for block elements that needs not
+       # to be wrapped into paragraph tags at the end, ":" is used for elements
+       # that are word separators and "X" is used in the general case.
+       #
+               # Swap back any tag hash found in $text so we do not have to `unhash`
+               # multiple times at the end.
+               $text = $this->unhash($text);
+               
+               # Then hash the block.
+               static $i = 0;
+               $key = "$boundary\x1A" . ++$i . $boundary;
+               $this->html_hashes[$key] = $text;
+               return $key; # String that will replace the tag.
+       }
+
+
+       function hashBlock($text) {
+       #
+       # Shortcut function for hashPart with block-level boundaries.
+       #
+               return $this->hashPart($text, 'B');
+       }
+
+
+       var $block_gamut = array(
+       #
+       # These are all the transformations that form block-level
+       # tags like paragraphs, headers, and list items.
+       #
+               "doHeaders"         => 10,
+               "doHorizontalRules" => 20,
+               
+               "doLists"           => 40,
+               "doCodeBlocks"      => 50,
+               "doBlockQuotes"     => 60,
+               );
+
+       function runBlockGamut($text) {
+       #
+       # Run block gamut tranformations.
+       #
+               # We need to escape raw HTML in Markdown source before doing anything 
+               # else. This need to be done for each block, and not only at the 
+               # begining in the Markdown function since hashed blocks can be part of
+               # list items and could have been indented. Indented blocks would have 
+               # been seen as a code block in a previous pass of hashHTMLBlocks.
+               $text = $this->hashHTMLBlocks($text);
+               
+               return $this->runBasicBlockGamut($text);
+       }
+       
+       function runBasicBlockGamut($text) {
+       #
+       # Run block gamut tranformations, without hashing HTML blocks. This is 
+       # useful when HTML blocks are known to be already hashed, like in the first
+       # whole-document pass.
+       #
+               foreach ($this->block_gamut as $method => $priority) {
+                       $text = $this->$method($text);
+               }
+               
+               # Finally form paragraph and restore hashed blocks.
+               $text = $this->formParagraphs($text);
+
+               return $text;
+       }
+       
+       
+       function doHorizontalRules($text) {
+               # Do Horizontal Rules:
+               return preg_replace(
+                       '{
+                               ^[ ]{0,3}       # Leading space
+                               ([-*_])         # $1: First marker
+                               (?>                  # Repeated marker group
+                                       [ ]{0,2}        # Zero, one, or two spaces.
+                                       \1                      # Marker character
+                               ){2,}           # Group repeated at least twice
+                               [ ]*            # Tailing spaces
+                               $                       # End of line.
+                       }mx',
+                       "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n", 
+                       $text);
+       }
+
+
+       var $span_gamut = array(
+       #
+       # These are all the transformations that occur *within* block-level
+       # tags like paragraphs, headers, and list items.
+       #
+               # Process character escapes, code spans, and inline HTML
+               # in one shot.
+               "parseSpan"           => -30,
+
+               # Process anchor and image tags. Images must come first,
+               # because ![foo][f] looks like an anchor.
+               "doImages"            =>  10,
+               "doAnchors"           =>  20,
+               
+               # Make links out of things like `<http://example.com/>`
+               # Must come after doAnchors, because you can use < and >
+               # delimiters in inline links like [this](<url>).
+               "doAutoLinks"         =>  30,
+               "encodeAmpsAndAngles" =>  40,
+
+               "doItalicsAndBold"    =>  50,
+               "doHardBreaks"        =>  60,
+               );
+
+       function runSpanGamut($text) {
+       #
+       # Run span gamut tranformations.
+       #
+               foreach ($this->span_gamut as $method => $priority) {
+                       $text = $this->$method($text);
+               }
+
+               return $text;
+       }
+       
+       
+       function doHardBreaks($text) {
+               # Do hard breaks:
+               return preg_replace_callback('/ {2,}\n/', 
+                       array(&$this, '_doHardBreaks_callback'), $text);
+       }
+       function _doHardBreaks_callback($matches) {
+               return $this->hashPart("<br$this->empty_element_suffix\n");
+       }
+
+
+       function doAnchors($text) {
+       #
+       # Turn Markdown link shortcuts into XHTML <a> tags.
+       #
+               if ($this->in_anchor) return $text;
+               $this->in_anchor = true;
+               
+               #
+               # First, handle reference-style links: [link text] [id]
+               #
+               $text = preg_replace_callback('{
+                       (                                       # wrap whole match in $1
+                         \[
+                               ('.$this->nested_brackets_re.')      # link text = $2
+                         \]
+
+                         [ ]?                          # one optional space
+                         (?:\n[ ]*)?           # one optional newline followed by spaces
+
+                         \[
+                               (.*?)           # id = $3
+                         \]
+                       )
+                       }xs',
+                       array(&$this, '_doAnchors_reference_callback'), $text);
+
+               #
+               # Next, inline-style links: [link text](url "optional title")
+               #
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         \[
+                               ('.$this->nested_brackets_re.')      # link text = $2
+                         \]
+                         \(                    # literal paren
+                               [ \n]*
+                               (?:
+                                       <(.+?)>   # href = $3
+                               |
+                                       ('.$this->nested_url_parenthesis_re.')       # href = $4
+                               )
+                               [ \n]*
+                               (                       # $5
+                                 ([\'"])  # quote char = $6
+                                 (.*?)         # Title = $7
+                                 \6            # matching quote
+                                 [ \n]*        # ignore any spaces/tabs between closing quote and )
+                               )?                      # title is optional
+                         \)
+                       )
+                       }xs',
+                       array(&$this, '_doAnchors_inline_callback'), $text);
+
+               #
+               # Last, handle reference-style shortcuts: [link text]
+               # These must come last in case you've also got [link text][1]
+               # or [link text](/foo)
+               #
+               $text = preg_replace_callback('{
+                       (                                       # wrap whole match in $1
+                         \[
+                               ([^\[\]]+)              # link text = $2; can\'t contain [ or ]
+                         \]
+                       )
+                       }xs',
+                       array(&$this, '_doAnchors_reference_callback'), $text);
+
+               $this->in_anchor = false;
+               return $text;
+       }
+       function _doAnchors_reference_callback($matches) {
+               $whole_match =  $matches[1];
+               $link_text   =  $matches[2];
+               $link_id     =& $matches[3];
+
+               if ($link_id == "") {
+                       # for shortcut links like [this][] or [this].
+                       $link_id = $link_text;
+               }
+               
+               # lower-case and turn embedded newlines into spaces
+               $link_id = strtolower($link_id);
+               $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
+
+               if (isset($this->urls[$link_id])) {
+                       $url = $this->urls[$link_id];
+                       $url = $this->encodeAttribute($url);
+                       
+                       $result = "<a href=\"$url\"";
+                       if ( isset( $this->titles[$link_id] ) ) {
+                               $title = $this->titles[$link_id];
+                               $title = $this->encodeAttribute($title);
+                               $result .=  " title=\"$title\"";
+                       }
+               
+                       $link_text = $this->runSpanGamut($link_text);
+                       $result .= ">$link_text</a>";
+                       $result = $this->hashPart($result);
+               }
+               else {
+                       $result = $whole_match;
+               }
+               return $result;
+       }
+       function _doAnchors_inline_callback($matches) {
+               $whole_match    =  $matches[1];
+               $link_text              =  $this->runSpanGamut($matches[2]);
+               $url                    =  $matches[3] == '' ? $matches[4] : $matches[3];
+               $title                  =& $matches[7];
+
+               $url = $this->encodeAttribute($url);
+
+               $result = "<a href=\"$url\"";
+               if (isset($title)) {
+                       $title = $this->encodeAttribute($title);
+                       $result .=  " title=\"$title\"";
+               }
+               
+               $link_text = $this->runSpanGamut($link_text);
+               $result .= ">$link_text</a>";
+
+               return $this->hashPart($result);
+       }
+
+
+       function doImages($text) {
+       #
+       # Turn Markdown image shortcuts into <img> tags.
+       #
+               #
+               # First, handle reference-style labeled images: ![alt text][id]
+               #
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         !\[
+                               ('.$this->nested_brackets_re.')              # alt text = $2
+                         \]
+
+                         [ ]?                          # one optional space
+                         (?:\n[ ]*)?           # one optional newline followed by spaces
+
+                         \[
+                               (.*?)           # id = $3
+                         \]
+
+                       )
+                       }xs', 
+                       array(&$this, '_doImages_reference_callback'), $text);
+
+               #
+               # Next, handle inline images:  ![alt text](url "optional title")
+               # Don't forget: encode * and _
+               #
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         !\[
+                               ('.$this->nested_brackets_re.')              # alt text = $2
+                         \]
+                         \s?                   # One optional whitespace character
+                         \(                    # literal paren
+                               [ \n]*
+                               (?:
+                                       <(\S*)>   # src url = $3
+                               |
+                                       ('.$this->nested_url_parenthesis_re.')       # src url = $4
+                               )
+                               [ \n]*
+                               (                       # $5
+                                 ([\'"])  # quote char = $6
+                                 (.*?)         # title = $7
+                                 \6            # matching quote
+                                 [ \n]*
+                               )?                      # title is optional
+                         \)
+                       )
+                       }xs',
+                       array(&$this, '_doImages_inline_callback'), $text);
+
+               return $text;
+       }
+       function _doImages_reference_callback($matches) {
+               $whole_match = $matches[1];
+               $alt_text    = $matches[2];
+               $link_id     = strtolower($matches[3]);
+
+               if ($link_id == "") {
+                       $link_id = strtolower($alt_text); # for shortcut links like ![this][].
+               }
+
+               $alt_text = $this->encodeAttribute($alt_text);
+               if (isset($this->urls[$link_id])) {
+                       $url = $this->encodeAttribute($this->urls[$link_id]);
+                       $result = "<img src=\"$url\" alt=\"$alt_text\"";
+                       if (isset($this->titles[$link_id])) {
+                               $title = $this->titles[$link_id];
+                               $title = $this->encodeAttribute($title);
+                               $result .=  " title=\"$title\"";
+                       }
+                       $result .= $this->empty_element_suffix;
+                       $result = $this->hashPart($result);
+               }
+               else {
+                       # If there's no such link ID, leave intact:
+                       $result = $whole_match;
+               }
+
+               return $result;
+       }
+       function _doImages_inline_callback($matches) {
+               $whole_match    = $matches[1];
+               $alt_text               = $matches[2];
+               $url                    = $matches[3] == '' ? $matches[4] : $matches[3];
+               $title                  =& $matches[7];
+
+               $alt_text = $this->encodeAttribute($alt_text);
+               $url = $this->encodeAttribute($url);
+               $result = "<img src=\"$url\" alt=\"$alt_text\"";
+               if (isset($title)) {
+                       $title = $this->encodeAttribute($title);
+                       $result .=  " title=\"$title\""; # $title already quoted
+               }
+               $result .= $this->empty_element_suffix;
+
+               return $this->hashPart($result);
+       }
+
+
+       function doHeaders($text) {
+               # Setext-style headers:
+               #         Header 1
+               #         ========
+               #  
+               #         Header 2
+               #         --------
+               #
+               $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
+                       array(&$this, '_doHeaders_callback_setext'), $text);
+
+               # atx-style headers:
+               #       # Header 1
+               #       ## Header 2
+               #       ## Header 2 with closing hashes ##
+               #       ...
+               #       ###### Header 6
+               #
+               $text = preg_replace_callback('{
+                               ^(\#{1,6})      # $1 = string of #\'s
+                               [ ]*
+                               (.+?)           # $2 = Header text
+                               [ ]*
+                               \#*                     # optional closing #\'s (not counted)
+                               \n+
+                       }xm',
+                       array(&$this, '_doHeaders_callback_atx'), $text);
+
+               return $text;
+       }
+       function _doHeaders_callback_setext($matches) {
+               # Terrible hack to check we haven't found an empty list item.
+               if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
+                       return $matches[0];
+               
+               $level = $matches[2]{0} == '=' ? 1 : 2;
+               $block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
+               return "\n" . $this->hashBlock($block) . "\n\n";
+       }
+       function _doHeaders_callback_atx($matches) {
+               $level = strlen($matches[1]);
+               $block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
+               return "\n" . $this->hashBlock($block) . "\n\n";
+       }
+
+
+       function doLists($text) {
+       #
+       # Form HTML ordered (numbered) and unordered (bulleted) lists.
+       #
+               $less_than_tab = $this->tab_width - 1;
+
+               # Re-usable patterns to match list item bullets and number markers:
+               $marker_ul_re  = '[*+-]';
+               $marker_ol_re  = '\d+[.]';
+               $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+               $markers_relist = array(
+                       $marker_ul_re => $marker_ol_re,
+                       $marker_ol_re => $marker_ul_re,
+                       );
+
+               foreach ($markers_relist as $marker_re => $other_marker_re) {
+                       # Re-usable pattern to match any entirel ul or ol list:
+                       $whole_list_re = '
+                               (                                                               # $1 = whole list
+                                 (                                                             # $2
+                                       ([ ]{0,'.$less_than_tab.'})     # $3 = number of spaces
+                                       ('.$marker_re.')                        # $4 = first list item marker
+                                       [ ]+
+                                 )
+                                 (?s:.+?)
+                                 (                                                             # $5
+                                         \z
+                                       |
+                                         \n{2,}
+                                         (?=\S)
+                                         (?!                                           # Negative lookahead for another list item marker
+                                               [ ]*
+                                               '.$marker_re.'[ ]+
+                                         )
+                                       |
+                                         (?=                                           # Lookahead for another kind of list
+                                           \n
+                                               \3                                              # Must have the same indentation
+                                               '.$other_marker_re.'[ ]+
+                                         )
+                                 )
+                               )
+                       '; // mx
+                       
+                       # We use a different prefix before nested lists than top-level lists.
+                       # See extended comment in _ProcessListItems().
+               
+                       if ($this->list_level) {
+                               $text = preg_replace_callback('{
+                                               ^
+                                               '.$whole_list_re.'
+                                       }mx',
+                                       array(&$this, '_doLists_callback'), $text);
+                       }
+                       else {
+                               $text = preg_replace_callback('{
+                                               (?:(?<=\n)\n|\A\n?) # Must eat the newline
+                                               '.$whole_list_re.'
+                                       }mx',
+                                       array(&$this, '_doLists_callback'), $text);
+                       }
+               }
+
+               return $text;
+       }
+       function _doLists_callback($matches) {
+               # Re-usable patterns to match list item bullets and number markers:
+               $marker_ul_re  = '[*+-]';
+               $marker_ol_re  = '\d+[.]';
+               $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+               
+               $list = $matches[1];
+               $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
+               
+               $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
+               
+               $list .= "\n";
+               $result = $this->processListItems($list, $marker_any_re);
+               
+               $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
+               return "\n". $result ."\n\n";
+       }
+
+       var $list_level = 0;
+
+       function processListItems($list_str, $marker_any_re) {
+       #
+       #       Process the contents of a single ordered or unordered list, splitting it
+       #       into individual list items.
+       #
+               # The $this->list_level global keeps track of when we're inside a list.
+               # Each time we enter a list, we increment it; when we leave a list,
+               # we decrement. If it's zero, we're not in a list anymore.
+               #
+               # We do this because when we're not inside a list, we want to treat
+               # something like this:
+               #
+               #               I recommend upgrading to version
+               #               8. Oops, now this line is treated
+               #               as a sub-list.
+               #
+               # As a single paragraph, despite the fact that the second line starts
+               # with a digit-period-space sequence.
+               #
+               # Whereas when we're inside a list (or sub-list), that line will be
+               # treated as the start of a sub-list. What a kludge, huh? This is
+               # an aspect of Markdown's syntax that's hard to parse perfectly
+               # without resorting to mind-reading. Perhaps the solution is to
+               # change the syntax rules such that sub-lists must start with a
+               # starting cardinal number; e.g. "1." or "a.".
+               
+               $this->list_level++;
+
+               # trim trailing blank lines:
+               $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+               $list_str = preg_replace_callback('{
+                       (\n)?                                                   # leading line = $1
+                       (^[ ]*)                                                 # leading whitespace = $2
+                       ('.$marker_any_re.'                             # list marker and space = $3
+                               (?:[ ]+|(?=\n)) # space only required if item is not empty
+                       )
+                       ((?s:.*?))                                              # list item text   = $4
+                       (?:(\n+(?=\n))|\n)                              # tailing blank line = $5
+                       (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
+                       }xm',
+                       array(&$this, '_processListItems_callback'), $list_str);
+
+               $this->list_level--;
+               return $list_str;
+       }
+       function _processListItems_callback($matches) {
+               $item = $matches[4];
+               $leading_line =& $matches[1];
+               $leading_space =& $matches[2];
+               $marker_space = $matches[3];
+               $tailing_blank_line =& $matches[5];
+
+               if ($leading_line || $tailing_blank_line || 
+                       preg_match('/\n{2,}/', $item))
+               {
+                       # Replace marker with the appropriate whitespace indentation
+                       $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
+                       $item = $this->runBlockGamut($this->outdent($item)."\n");
+               }
+               else {
+                       # Recursion for sub-lists:
+                       $item = $this->doLists($this->outdent($item));
+                       $item = preg_replace('/\n+$/', '', $item);
+                       $item = $this->runSpanGamut($item);
+               }
+
+               return "<li>" . $item . "</li>\n";
+       }
+
+
+       function doCodeBlocks($text) {
+       #
+       #       Process Markdown `<pre><code>` blocks.
+       #
+               $text = preg_replace_callback('{
+                               (?:\n\n|\A\n?)
+                               (                   # $1 = the code block -- one or more lines, starting with a space/tab
+                                 (?>
+                                       [ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
+                                       .*\n+
+                                 )+
+                               )
+                               ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)      # Lookahead for non-space at line-start, or end of doc
+                       }xm',
+                       array(&$this, '_doCodeBlocks_callback'), $text);
+
+               return $text;
+       }
+       function _doCodeBlocks_callback($matches) {
+               $codeblock = $matches[1];
+
+               $codeblock = $this->outdent($codeblock);
+               $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+
+               # trim leading newlines and trailing newlines
+               $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
+
+               $codeblock = "<pre><code>$codeblock\n</code></pre>";
+               return "\n\n".$this->hashBlock($codeblock)."\n\n";
+       }
+
+
+       function makeCodeSpan($code) {
+       #
+       # Create a code span markup for $code. Called from handleSpanToken.
+       #
+               $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+               return $this->hashPart("<code>$code</code>");
+       }
+
+
+       var $em_relist = array(
+               ''  => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![.,:;]\s)',
+               '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
+               '_' => '(?<=\S|^)(?<!_)_(?!_)',
+               );
+       var $strong_relist = array(
+               ''   => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![.,:;]\s)',
+               '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
+               '__' => '(?<=\S|^)(?<!_)__(?!_)',
+               );
+       var $em_strong_relist = array(
+               ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![.,:;]\s)',
+               '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
+               '___' => '(?<=\S|^)(?<!_)___(?!_)',
+               );
+       var $em_strong_prepared_relist;
+       
+       function prepareItalicsAndBold() {
+       #
+       # Prepare regular expressions for searching emphasis tokens in any
+       # context.
+       #
+               foreach ($this->em_relist as $em => $em_re) {
+                       foreach ($this->strong_relist as $strong => $strong_re) {
+                               # Construct list of allowed token expressions.
+                               $token_relist = array();
+                               if (isset($this->em_strong_relist["$em$strong"])) {
+                                       $token_relist[] = $this->em_strong_relist["$em$strong"];
+                               }
+                               $token_relist[] = $em_re;
+                               $token_relist[] = $strong_re;
+                               
+                               # Construct master expression from list.
+                               $token_re = '{('. implode('|', $token_relist) .')}';
+                               $this->em_strong_prepared_relist["$em$strong"] = $token_re;
+                       }
+               }
+       }
+       
+       function doItalicsAndBold($text) {
+               $token_stack = array('');
+               $text_stack = array('');
+               $em = '';
+               $strong = '';
+               $tree_char_em = false;
+               
+               while (1) {
+                       #
+                       # Get prepared regular expression for seraching emphasis tokens
+                       # in current context.
+                       #
+                       $token_re = $this->em_strong_prepared_relist["$em$strong"];
+                       
+                       #
+                       # Each loop iteration search for the next emphasis token. 
+                       # Each token is then passed to handleSpanToken.
+                       #
+                       $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+                       $text_stack[0] .= $parts[0];
+                       $token =& $parts[1];
+                       $text =& $parts[2];
+                       
+                       if (empty($token)) {
+                               # Reached end of text span: empty stack without emitting.
+                               # any more emphasis.
+                               while ($token_stack[0]) {
+                                       $text_stack[1] .= array_shift($token_stack);
+                                       $text_stack[0] .= array_shift($text_stack);
+                               }
+                               break;
+                       }
+                       
+                       $token_len = strlen($token);
+                       if ($tree_char_em) {
+                               # Reached closing marker while inside a three-char emphasis.
+                               if ($token_len == 3) {
+                                       # Three-char closing marker, close em and strong.
+                                       array_shift($token_stack);
+                                       $span = array_shift($text_stack);
+                                       $span = $this->runSpanGamut($span);
+                                       $span = "<strong><em>$span</em></strong>";
+                                       $text_stack[0] .= $this->hashPart($span);
+                                       $em = '';
+                                       $strong = '';
+                               } else {
+                                       # Other closing marker: close one em or strong and
+                                       # change current token state to match the other
+                                       $token_stack[0] = str_repeat($token{0}, 3-$token_len);
+                                       $tag = $token_len == 2 ? "strong" : "em";
+                                       $span = $text_stack[0];
+                                       $span = $this->runSpanGamut($span);
+                                       $span = "<$tag>$span</$tag>";
+                                       $text_stack[0] = $this->hashPart($span);
+                                       $$tag = ''; # $$tag stands for $em or $strong
+                               }
+                               $tree_char_em = false;
+                       } else if ($token_len == 3) {
+                               if ($em) {
+                                       # Reached closing marker for both em and strong.
+                                       # Closing strong marker:
+                                       for ($i = 0; $i < 2; ++$i) {
+                                               $shifted_token = array_shift($token_stack);
+                                               $tag = strlen($shifted_token) == 2 ? "strong" : "em";
+                                               $span = array_shift($text_stack);
+                                               $span = $this->runSpanGamut($span);
+                                               $span = "<$tag>$span</$tag>";
+                                               $text_stack[0] .= $this->hashPart($span);
+                                               $$tag = ''; # $$tag stands for $em or $strong
+                                       }
+                               } else {
+                                       # Reached opening three-char emphasis marker. Push on token 
+                                       # stack; will be handled by the special condition above.
+                                       $em = $token{0};
+                                       $strong = "$em$em";
+                                       array_unshift($token_stack, $token);
+                                       array_unshift($text_stack, '');
+                                       $tree_char_em = true;
+                               }
+                       } else if ($token_len == 2) {
+                               if ($strong) {
+                                       # Unwind any dangling emphasis marker:
+                                       if (strlen($token_stack[0]) == 1) {
+                                               $text_stack[1] .= array_shift($token_stack);
+                                               $text_stack[0] .= array_shift($text_stack);
+                                       }
+                                       # Closing strong marker:
+                                       array_shift($token_stack);
+                                       $span = array_shift($text_stack);
+                                       $span = $this->runSpanGamut($span);
+                                       $span = "<strong>$span</strong>";
+                                       $text_stack[0] .= $this->hashPart($span);
+                                       $strong = '';
+                               } else {
+                                       array_unshift($token_stack, $token);
+                                       array_unshift($text_stack, '');
+                                       $strong = $token;
+                               }
+                       } else {
+                               # Here $token_len == 1
+                               if ($em) {
+                                       if (strlen($token_stack[0]) == 1) {
+                                               # Closing emphasis marker:
+                                               array_shift($token_stack);
+                                               $span = array_shift($text_stack);
+                                               $span = $this->runSpanGamut($span);
+                                               $span = "<em>$span</em>";
+                                               $text_stack[0] .= $this->hashPart($span);
+                                               $em = '';
+                                       } else {
+                                               $text_stack[0] .= $token;
+                                       }
+                               } else {
+                                       array_unshift($token_stack, $token);
+                                       array_unshift($text_stack, '');
+                                       $em = $token;
+                               }
+                       }
+               }
+               return $text_stack[0];
+       }
+
+
+       function doBlockQuotes($text) {
+               $text = preg_replace_callback('/
+                         (                                                             # Wrap whole match in $1
+                               (?>
+                                 ^[ ]*>[ ]?                 # ">" at the start of a line
+                                       .+\n                                    # rest of the first line
+                                 (.+\n)*                                       # subsequent consecutive lines
+                                 \n*                                           # blanks
+                               )+
+                         )
+                       /xm',
+                       array(&$this, '_doBlockQuotes_callback'), $text);
+
+               return $text;
+       }
+       function _doBlockQuotes_callback($matches) {
+               $bq = $matches[1];
+               # trim one level of quoting - trim whitespace-only lines
+               $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
+               $bq = $this->runBlockGamut($bq);             # recurse
+
+               $bq = preg_replace('/^/m', "  ", $bq);
+               # These leading spaces cause problem with <pre> content, 
+               # so we need to fix that:
+               $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx', 
+                       array(&$this, '_doBlockQuotes_callback2'), $bq);
+
+               return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
+       }
+       function _doBlockQuotes_callback2($matches) {
+               $pre = $matches[1];
+               $pre = preg_replace('/^  /m', '', $pre);
+               return $pre;
+       }
+
+
+       function formParagraphs($text) {
+       #
+       #       Params:
+       #               $text - string to process with html <p> tags
+       #
+               # Strip leading and trailing lines:
+               $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+               $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+               #
+               # Wrap <p> tags and unhashify HTML blocks
+               #
+               foreach ($grafs as $key => $value) {
+                       if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
+                               # Is a paragraph.
+                               $value = $this->runSpanGamut($value);
+                               $value = preg_replace('/^([ ]*)/', "<p>", $value);
+                               $value .= "</p>";
+                               $grafs[$key] = $this->unhash($value);
+                       }
+                       else {
+                               # Is a block.
+                               # Modify elements of @grafs in-place...
+                               $graf = $value;
+                               $block = $this->html_hashes[$graf];
+                               $graf = $block;
+//                             if (preg_match('{
+//                                     \A
+//                                     (                                                       # $1 = <div> tag
+//                                       <div  \s+
+//                                       [^>]*
+//                                       \b
+//                                       markdown\s*=\s*  ([\'"]) #       $2 = attr quote char
+//                                       1
+//                                       \2
+//                                       [^>]*
+//                                       >
+//                                     )
+//                                     (                                                       # $3 = contents
+//                                     .*
+//                                     )
+//                                     (</div>)                                  # $4 = closing tag
+//                                     \z
+//                                     }xs', $block, $matches))
+//                             {
+//                                     list(, $div_open, , $div_content, $div_close) = $matches;
+//
+//                                     # We can't call Markdown(), because that resets the hash;
+//                                     # that initialization code should be pulled into its own sub, though.
+//                                     $div_content = $this->hashHTMLBlocks($div_content);
+//                                     
+//                                     # Run document gamut methods on the content.
+//                                     foreach ($this->document_gamut as $method => $priority) {
+//                                             $div_content = $this->$method($div_content);
+//                                     }
+//
+//                                     $div_open = preg_replace(
+//                                             '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
+//
+//                                     $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
+//                             }
+                               $grafs[$key] = $graf;
+                       }
+               }
+
+               return implode("\n\n", $grafs);
+       }
+
+
+       function encodeAttribute($text) {
+       #
+       # Encode text for a double-quoted HTML attribute. This function
+       # is *not* suitable for attributes enclosed in single quotes.
+       #
+               $text = $this->encodeAmpsAndAngles($text);
+               $text = str_replace('"', '&quot;', $text);
+               return $text;
+       }
+       
+       
+       function encodeAmpsAndAngles($text) {
+       #
+       # Smart processing for ampersands and angle brackets that need to 
+       # be encoded. Valid character entities are left alone unless the
+       # no-entities mode is set.
+       #
+               if ($this->no_entities) {
+                       $text = str_replace('&', '&amp;', $text);
+               } else {
+                       # Ampersand-encoding based entirely on Nat Irons's Amputator
+                       # MT plugin: <http://bumppo.net/projects/amputator/>
+                       $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', 
+                                                               '&amp;', $text);;
+               }
+               # Encode remaining <'s
+               $text = str_replace('<', '&lt;', $text);
+
+               return $text;
+       }
+
+
+       function doAutoLinks($text) {
+               $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i', 
+                       array(&$this, '_doAutoLinks_url_callback'), $text);
+
+               # Email addresses: <address@domain.foo>
+               $text = preg_replace_callback('{
+                       <
+                       (?:mailto:)?
+                       (
+                               (?:
+                                       [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+
+                               |
+                                       ".*?"
+                               )
+                               \@
+                               (?:
+                                       [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
+                               |
+                                       \[[\d.a-fA-F:]+\]       # IPv4 & IPv6
+                               )
+                       )
+                       >
+                       }xi',
+                       array(&$this, '_doAutoLinks_email_callback'), $text);
+
+               return $text;
+       }
+       function _doAutoLinks_url_callback($matches) {
+               $url = $this->encodeAttribute($matches[1]);
+               $link = "<a href=\"$url\">$url</a>";
+               return $this->hashPart($link);
+       }
+       function _doAutoLinks_email_callback($matches) {
+               $address = $matches[1];
+               $link = $this->encodeEmailAddress($address);
+               return $this->hashPart($link);
+       }
+
+
+       function encodeEmailAddress($addr) {
+       #
+       #       Input: an email address, e.g. "foo@example.com"
+       #
+       #       Output: the email address as a mailto link, with each character
+       #               of the address encoded as either a decimal or hex entity, in
+       #               the hopes of foiling most address harvesting spam bots. E.g.:
+       #
+       #         <p><a href="&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
+       #        &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
+       #        &#x6d;">&#x66;o&#111;&#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;
+       #        &#101;&#46;&#x63;&#111;&#x6d;</a></p>
+       #
+       #       Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+       #   With some optimizations by Milian Wolff.
+       #
+               $addr = "mailto:" . $addr;
+               $chars = preg_split('/(?<!^)(?!$)/', $addr);
+               $seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
+               
+               foreach ($chars as $key => $char) {
+                       $ord = ord($char);
+                       # Ignore non-ascii chars.
+                       if ($ord < 128) {
+                               $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
+                               # roughly 10% raw, 45% hex, 45% dec
+                               # '@' *must* be encoded. I insist.
+                               if ($r > 90 && $char != '@') /* do nothing */;
+                               else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
+                               else              $chars[$key] = '&#'.$ord.';';
+                       }
+               }
+               
+               $addr = implode('', $chars);
+               $text = implode('', array_slice($chars, 7)); # text without `mailto:`
+               $addr = "<a href=\"$addr\">$text</a>";
+
+               return $addr;
+       }
+
+
+       function parseSpan($str) {
+       #
+       # Take the string $str and parse it into tokens, hashing embeded HTML,
+       # escaped characters and handling code spans.
+       #
+               $output = '';
+               
+               $span_re = '{
+                               (
+                                       \\\\'.$this->escape_chars_re.'
+                               |
+                                       (?<![`\\\\])
+                                       `+                                              # code span marker
+                       '.( $this->no_markup ? '' : '
+                               |
+                                       <!--    .*?     -->               # comment
+                               |
+                                       <\?.*?\?> | <%.*?%>         # processing instruction
+                               |
+                                       <[/!$]?[-a-zA-Z0-9:_]+       # regular tags
+                                       (?>
+                                               \s
+                                               (?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
+                                       )?
+                                       >
+                       ').'
+                               )
+                               }xs';
+
+               while (1) {
+                       #
+                       # Each loop iteration seach for either the next tag, the next 
+                       # openning code span marker, or the next escaped character. 
+                       # Each token is then passed to handleSpanToken.
+                       #
+                       $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
+                       
+                       # Create token from text preceding tag.
+                       if ($parts[0] != "") {
+                               $output .= $parts[0];
+                       }
+                       
+                       # Check if we reach the end.
+                       if (isset($parts[1])) {
+                               $output .= $this->handleSpanToken($parts[1], $parts[2]);
+                               $str = $parts[2];
+                       }
+                       else {
+                               break;
+                       }
+               }
+               
+               return $output;
+       }
+       
+       
+       function handleSpanToken($token, &$str) {
+       #
+       # Handle $token provided by parseSpan by determining its nature and 
+       # returning the corresponding value that should replace it.
+       #
+               switch ($token{0}) {
+                       case "\\":
+                               return $this->hashPart("&#". ord($token{1}). ";");
+                       case "`":
+                               # Search for end marker in remaining text.
+                               if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', 
+                                       $str, $matches))
+                               {
+                                       $str = $matches[2];
+                                       $codespan = $this->makeCodeSpan($matches[1]);
+                                       return $this->hashPart($codespan);
+                               }
+                               return $token; // return as text since no ending marker found.
+                       default:
+                               return $this->hashPart($token);
+               }
+       }
+
+
+       function outdent($text) {
+       #
+       # Remove one level of line-leading tabs or spaces
+       #
+               return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
+       }
+
+
+       # String length function for detab. `_initDetab` will create a function to 
+       # hanlde UTF-8 if the default function does not exist.
+       var $utf8_strlen = 'mb_strlen';
+       
+       function detab($text) {
+       #
+       # Replace tabs with the appropriate amount of space.
+       #
+               # For each line we separate the line in blocks delemited by
+               # tab characters. Then we reconstruct every line by adding the 
+               # appropriate number of space between each blocks.
+               
+               $text = preg_replace_callback('/^.*\t.*$/m',
+                       array(&$this, '_detab_callback'), $text);
+
+               return $text;
+       }
+       function _detab_callback($matches) {
+               $line = $matches[0];
+               $strlen = $this->utf8_strlen; # strlen function for UTF-8.
+               
+               # Split in blocks.
+               $blocks = explode("\t", $line);
+               # Add each blocks to the line.
+               $line = $blocks[0];
+               unset($blocks[0]); # Do not add first block twice.
+               foreach ($blocks as $block) {
+                       # Calculate amount of space, insert spaces, insert block.
+                       $amount = $this->tab_width - 
+                               $strlen($line, 'UTF-8') % $this->tab_width;
+                       $line .= str_repeat(" ", $amount) . $block;
+               }
+               return $line;
+       }
+       function _initDetab() {
+       #
+       # Check for the availability of the function in the `utf8_strlen` property
+       # (initially `mb_strlen`). If the function is not available, create a 
+       # function that will loosely count the number of UTF-8 characters with a
+       # regular expression.
+       #
+               if (function_exists($this->utf8_strlen)) return;
+               $this->utf8_strlen = create_function('$text', 'return preg_match_all(
+                       "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", 
+                       $text, $m);');
+       }
+
+
+       function unhash($text) {
+       #
+       # Swap back in all the tags hashed by _HashHTMLBlocks.
+       #
+               return preg_replace_callback('/(.)\x1A[0-9]+\1/', 
+                       array(&$this, '_unhash_callback'), $text);
+       }
+       function _unhash_callback($matches) {
+               return $this->html_hashes[$matches[0]];
+       }
+
+}
+
+
+#
+# Markdown Extra Parser Class
+#
+
+class MarkdownExtra_Parser extends Markdown_Parser {
+
+       # Prefix for footnote ids.
+       var $fn_id_prefix = "";
+       
+       # Optional title attribute for footnote links and backlinks.
+       var $fn_link_title = MARKDOWN_FN_LINK_TITLE;
+       var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE;
+       
+       # Optional class attribute for footnote links and backlinks.
+       var $fn_link_class = MARKDOWN_FN_LINK_CLASS;
+       var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS;
+       
+       # Predefined abbreviations.
+       var $predef_abbr = array();
+
+
+       function MarkdownExtra_Parser() {
+       #
+       # Constructor function. Initialize the parser object.
+       #
+               # Add extra escapable characters before parent constructor 
+               # initialize the table.
+               $this->escape_chars .= ':|';
+               
+               # Insert extra document, block, and span transformations. 
+               # Parent constructor will do the sorting.
+               $this->document_gamut += array(
+                       "doFencedCodeBlocks" => 5,
+                       "stripFootnotes"     => 15,
+                       "stripAbbreviations" => 25,
+                       "appendFootnotes"    => 50,
+                       );
+               $this->block_gamut += array(
+                       "doFencedCodeBlocks" => 5,
+                       "doTables"           => 15,
+                       "doDefLists"         => 45,
+                       );
+               $this->span_gamut += array(
+                       "doFootnotes"        => 5,
+                       "doAbbreviations"    => 70,
+                       );
+               
+               parent::Markdown_Parser();
+       }
+       
+       
+       # Extra variables used during extra transformations.
+       var $footnotes = array();
+       var $footnotes_ordered = array();
+       var $abbr_desciptions = array();
+       var $abbr_word_re = '';
+       
+       # Give the current footnote number.
+       var $footnote_counter = 1;
+       
+       
+       function setup() {
+       #
+       # Setting up Extra-specific variables.
+       #
+               parent::setup();
+               
+               $this->footnotes = array();
+               $this->footnotes_ordered = array();
+               $this->abbr_desciptions = array();
+               $this->abbr_word_re = '';
+               $this->footnote_counter = 1;
+               
+               foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
+                       if ($this->abbr_word_re)
+                               $this->abbr_word_re .= '|';
+                       $this->abbr_word_re .= preg_quote($abbr_word);
+                       $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+               }
+       }
+       
+       function teardown() {
+       #
+       # Clearing Extra-specific variables.
+       #
+               $this->footnotes = array();
+               $this->footnotes_ordered = array();
+               $this->abbr_desciptions = array();
+               $this->abbr_word_re = '';
+               
+               parent::teardown();
+       }
+       
+       
+       ### HTML Block Parser ###
+       
+       # Tags that are always treated as block tags:
+       var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend';
+       
+       # Tags treated as block tags only if the opening tag is alone on it's line:
+       var $context_block_tags_re = 'script|noscript|math|ins|del';
+       
+       # Tags where markdown="1" default to span mode:
+       var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
+       
+       # Tags which must not have their contents modified, no matter where 
+       # they appear:
+       var $clean_tags_re = 'script|math';
+       
+       # Tags that do not need to be closed.
+       var $auto_close_tags_re = 'hr|img';
+       
+
+       function hashHTMLBlocks($text) {
+       #
+       # Hashify HTML Blocks and "clean tags".
+       #
+       # We only want to do this for block-level HTML tags, such as headers,
+       # lists, and tables. That's because we still want to wrap <p>s around
+       # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+       # phrase emphasis, and spans. The list of tags we're looking for is
+       # hard-coded.
+       #
+       # This works by calling _HashHTMLBlocks_InMarkdown, which then calls
+       # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" 
+       # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back
+       #  _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
+       # These two functions are calling each other. It's recursive!
+       #
+               #
+               # Call the HTML-in-Markdown hasher.
+               #
+               list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
+               
+               return $text;
+       }
+       function _hashHTMLBlocks_inMarkdown($text, $indent = 0, 
+                                                                               $enclosing_tag_re = '', $span = false)
+       {
+       #
+       # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
+       #
+       # *   $indent is the number of space to be ignored when checking for code 
+       #     blocks. This is important because if we don't take the indent into 
+       #     account, something like this (which looks right) won't work as expected:
+       #
+       #     <div>
+       #         <div markdown="1">
+       #         Hello World.  <-- Is this a Markdown code block or text?
+       #         </div>  <-- Is this a Markdown code block or a real tag?
+       #     <div>
+       #
+       #     If you don't like this, just don't indent the tag on which
+       #     you apply the markdown="1" attribute.
+       #
+       # *   If $enclosing_tag_re is not empty, stops at the first unmatched closing 
+       #     tag with that name. Nested tags supported.
+       #
+       # *   If $span is true, text inside must treated as span. So any double 
+       #     newline will be replaced by a single newline so that it does not create 
+       #     paragraphs.
+       #
+       # Returns an array of that form: ( processed text , remaining text )
+       #
+               if ($text === '') return array('', '');
+
+               # Regex to check for the presense of newlines around a block tag.
+               $newline_before_re = '/(?:^\n?|\n\n)*$/';
+               $newline_after_re = 
+                       '{
+                               ^                                               # Start of text following the tag.
+                               (?>[ ]*<!--.*?-->)?            # Optional comment.
+                               [ ]*\n                                  # Must be followed by newline.
+                       }xs';
+               
+               # Regex to match any tag.
+               $block_tag_re =
+                       '{
+                               (                                       # $2: Capture hole tag.
+                                       </?                                  # Any opening or closing tag.
+                                               (?>                          # Tag name.
+                                                       '.$this->block_tags_re.'                     |
+                                                       '.$this->context_block_tags_re.'     |
+                                                       '.$this->clean_tags_re.'             |
+                                                       (?!\s)'.$enclosing_tag_re.'
+                                               )
+                                               (?:
+                                                       (?=[\s"\'/a-zA-Z0-9])      # Allowed characters after tag name.
+                                                       (?>
+                                                               ".*?"         |       # Double quotes (can contain `>`)
+                                                               \'.*?\'         |       # Single quotes (can contain `>`)
+                                                               .+?                             # Anything but quotes and `>`.
+                                                       )*?
+                                               )?
+                                       >                                    # End of tag.
+                               |
+                                       <!--    .*?     -->       # HTML Comment
+                               |
+                                       <\?.*?\?> | <%.*?%> # Processing instruction
+                               |
+                                       <!\[CDATA\[.*?\]\]>       # CData Block
+                               |
+                                       # Code span marker
+                                       `+
+                               '. ( !$span ? ' # If not in span.
+                               |
+                                       # Indented code block
+                                       (?: ^[ ]*\n | ^ | \n[ ]*\n )
+                                       [ ]{'.($indent+4).'}[^\n]* \n
+                                       (?>
+                                               (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n
+                                       )*
+                               |
+                                       # Fenced code block marker
+                                       (?> ^ | \n )
+                                       [ ]{'.($indent).'}~~~+[ ]*\n
+                               ' : '' ). ' # End (if not is span).
+                               )
+                       }xs';
+
+               
+               $depth = 0;             # Current depth inside the tag tree.
+               $parsed = ""; # Parsed text that will be returned.
+
+               #
+               # Loop through every tag until we find the closing tag of the parent
+               # or loop until reaching the end of text if no parent tag specified.
+               #
+               do {
+                       #
+                       # Split the text using the first $tag_match pattern found.
+                       # Text before  pattern will be first in the array, text after
+                       # pattern will be at the end, and between will be any catches made 
+                       # by the pattern.
+                       #
+                       $parts = preg_split($block_tag_re, $text, 2, 
+                                                               PREG_SPLIT_DELIM_CAPTURE);
+                       
+                       # If in Markdown span mode, add a empty-string span-level hash 
+                       # after each newline to prevent triggering any block element.
+                       if ($span) {
+                               $void = $this->hashPart("", ':');
+                               $newline = "$void\n";
+                               $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
+                       }
+                       
+                       $parsed .= $parts[0]; # Text before current tag.
+                       
+                       # If end of $text has been reached. Stop loop.
+                       if (count($parts) < 3) {
+                               $text = "";
+                               break;
+                       }
+                       
+                       $tag  = $parts[1]; # Tag to handle.
+                       $text = $parts[2]; # Remaining text after current tag.
+                       $tag_re = preg_quote($tag); # For use in a regular expression.
+                       
+                       #
+                       # Check for: Code span marker
+                       #
+                       if ($tag{0} == "`") {
+                               # Find corresponding end marker.
+                               $tag_re = preg_quote($tag);
+                               if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)'.$tag_re.'(?!`)}',
+                                       $text, $matches))
+                               {
+                                       # End marker found: pass text unchanged until marker.
+                                       $parsed .= $tag . $matches[0];
+                                       $text = substr($text, strlen($matches[0]));
+                               }
+                               else {
+                                       # Unmatched marker: just skip it.
+                                       $parsed .= $tag;
+                               }
+                       }
+                       #
+                       # Check for: Indented code block.
+                       #
+                       else if ($tag{0} == "\n" || $tag{0} == " ") {
+                               # Indented code block: pass it unchanged, will be handled 
+                               # later.
+                               $parsed .= $tag;
+                       }
+                       #
+                       # Check for: Fenced code block marker.
+                       #
+                       else if ($tag{0} == "~") {
+                               # Fenced code block marker: find matching end marker.
+                               $tag_re = preg_quote(trim($tag));
+                               if (preg_match('{^(?>.*\n)+?'.$tag_re.' *\n}', $text, 
+                                       $matches)) 
+                               {
+                                       # End marker found: pass text unchanged until marker.
+                                       $parsed .= $tag . $matches[0];
+                                       $text = substr($text, strlen($matches[0]));
+                               }
+                               else {
+                                       # No end marker: just skip it.
+                                       $parsed .= $tag;
+                               }
+                       }
+                       #
+                       # Check for: Opening Block level tag or
+                       #            Opening Context Block tag (like ins and del) 
+                       #               used as a block tag (tag is alone on it's line).
+                       #
+                       else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) ||
+                               (       preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) &&
+                                       preg_match($newline_before_re, $parsed) &&
+                                       preg_match($newline_after_re, $text)    )
+                               )
+                       {
+                               # Need to parse tag and following text using the HTML parser.
+                               list($block_text, $text) = 
+                                       $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
+                               
+                               # Make sure it stays outside of any paragraph by adding newlines.
+                               $parsed .= "\n\n$block_text\n\n";
+                       }
+                       #
+                       # Check for: Clean tag (like script, math)
+                       #            HTML Comments, processing instructions.
+                       #
+                       else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) ||
+                               $tag{1} == '!' || $tag{1} == '?')
+                       {
+                               # Need to parse tag and following text using the HTML parser.
+                               # (don't check for markdown attribute)
+                               list($block_text, $text) = 
+                                       $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
+                               
+                               $parsed .= $block_text;
+                       }
+                       #
+                       # Check for: Tag with same name as enclosing tag.
+                       #
+                       else if ($enclosing_tag_re !== '' &&
+                               # Same name as enclosing tag.
+                               preg_match('{^</?(?:'.$enclosing_tag_re.')\b}', $tag))
+                       {
+                               #
+                               # Increase/decrease nested tag count.
+                               #
+                               if ($tag{1} == '/')                                             $depth--;
+                               else if ($tag{strlen($tag)-2} != '/')   $depth++;
+
+                               if ($depth < 0) {
+                                       #
+                                       # Going out of parent element. Clean up and break so we
+                                       # return to the calling function.
+                                       #
+                                       $text = $tag . $text;
+                                       break;
+                               }
+                               
+                               $parsed .= $tag;
+                       }
+                       else {
+                               $parsed .= $tag;
+                       }
+               } while ($depth >= 0);
+               
+               return array($parsed, $text);
+       }
+       function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
+       #
+       # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
+       #
+       # *   Calls $hash_method to convert any blocks.
+       # *   Stops when the first opening tag closes.
+       # *   $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
+       #     (it is not inside clean tags)
+       #
+       # Returns an array of that form: ( processed text , remaining text )
+       #
+               if ($text === '') return array('', '');
+               
+               # Regex to match `markdown` attribute inside of a tag.
+               $markdown_attr_re = '
+                       {
+                               \s*                     # Eat whitespace before the `markdown` attribute
+                               markdown
+                               \s*=\s*
+                               (?>
+                                       (["\'])            # $1: quote delimiter           
+                                       (.*?)           # $2: attribute value
+                                       \1                      # matching delimiter    
+                               |
+                                       ([^\s>]*)    # $3: unquoted attribute value
+                               )
+                               ()                              # $4: make $3 always defined (avoid warnings)
+                       }xs';
+               
+               # Regex to match any tag.
+               $tag_re = '{
+                               (                                       # $2: Capture hole tag.
+                                       </?                                  # Any opening or closing tag.
+                                               [\w:$]+                 # Tag name.
+                                               (?:
+                                                       (?=[\s"\'/a-zA-Z0-9])      # Allowed characters after tag name.
+                                                       (?>
+                                                               ".*?"         |       # Double quotes (can contain `>`)
+                                                               \'.*?\'         |       # Single quotes (can contain `>`)
+                                                               .+?                             # Anything but quotes and `>`.
+                                                       )*?
+                                               )?
+                                       >                                    # End of tag.
+                               |
+                                       <!--    .*?     -->       # HTML Comment
+                               |
+                                       <\?.*?\?> | <%.*?%> # Processing instruction
+                               |
+                                       <!\[CDATA\[.*?\]\]>       # CData Block
+                               )
+                       }xs';
+               
+               $original_text = $text;         # Save original text in case of faliure.
+               
+               $depth          = 0;    # Current depth inside the tag tree.
+               $block_text     = ""; # Temporary text holder for current text.
+               $parsed         = ""; # Parsed text that will be returned.
+
+               #
+               # Get the name of the starting tag.
+               # (This pattern makes $base_tag_name_re safe without quoting.)
+               #
+               if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
+                       $base_tag_name_re = $matches[1];
+
+               #
+               # Loop through every tag until we find the corresponding closing tag.
+               #
+               do {
+                       #
+                       # Split the text using the first $tag_match pattern found.
+                       # Text before  pattern will be first in the array, text after
+                       # pattern will be at the end, and between will be any catches made 
+                       # by the pattern.
+                       #
+                       $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+                       
+                       if (count($parts) < 3) {
+                               #
+                               # End of $text reached with unbalenced tag(s).
+                               # In that case, we return original text unchanged and pass the
+                               # first character as filtered to prevent an infinite loop in the 
+                               # parent function.
+                               #
+                               return array($original_text{0}, substr($original_text, 1));
+                       }
+                       
+                       $block_text .= $parts[0]; # Text before current tag.
+                       $tag         = $parts[1]; # Tag to handle.
+                       $text        = $parts[2]; # Remaining text after current tag.
+                       
+                       #
+                       # Check for: Auto-close tag (like <hr/>)
+                       #                        Comments and Processing Instructions.
+                       #
+                       if (preg_match('{^</?(?:'.$this->auto_close_tags_re.')\b}', $tag) ||
+                               $tag{1} == '!' || $tag{1} == '?')
+                       {
+                               # Just add the tag to the block as if it was text.
+                               $block_text .= $tag;
+                       }
+                       else {
+                               #
+                               # Increase/decrease nested tag count. Only do so if
+                               # the tag's name match base tag's.
+                               #
+                               if (preg_match('{^</?'.$base_tag_name_re.'\b}', $tag)) {
+                                       if ($tag{1} == '/')                                             $depth--;
+                                       else if ($tag{strlen($tag)-2} != '/')   $depth++;
+                               }
+                               
+                               #
+                               # Check for `markdown="1"` attribute and handle it.
+                               #
+                               if ($md_attr && 
+                                       preg_match($markdown_attr_re, $tag, $attr_m) &&
+                                       preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
+                               {
+                                       # Remove `markdown` attribute from opening tag.
+                                       $tag = preg_replace($markdown_attr_re, '', $tag);
+                                       
+                                       # Check if text inside this tag must be parsed in span mode.
+                                       $this->mode = $attr_m[2] . $attr_m[3];
+                                       $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
+                                               preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag);
+                                       
+                                       # Calculate indent before tag.
+                                       if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
+                                               $strlen = $this->utf8_strlen;
+                                               $indent = $strlen($matches[1], 'UTF-8');
+                                       } else {
+                                               $indent = 0;
+                                       }
+                                       
+                                       # End preceding block with this tag.
+                                       $block_text .= $tag;
+                                       $parsed .= $this->$hash_method($block_text);
+                                       
+                                       # Get enclosing tag name for the ParseMarkdown function.
+                                       # (This pattern makes $tag_name_re safe without quoting.)
+                                       preg_match('/^<([\w:$]*)\b/', $tag, $matches);
+                                       $tag_name_re = $matches[1];
+                                       
+                                       # Parse the content using the HTML-in-Markdown parser.
+                                       list ($block_text, $text)
+                                               = $this->_hashHTMLBlocks_inMarkdown($text, $indent, 
+                                                       $tag_name_re, $span_mode);
+                                       
+                                       # Outdent markdown text.
+                                       if ($indent > 0) {
+                                               $block_text = preg_replace("/^[ ]{1,$indent}/m", "", 
+                                                                                                       $block_text);
+                                       }
+                                       
+                                       # Append tag content to parsed text.
+                                       if (!$span_mode)        $parsed .= "\n\n$block_text\n\n";
+                                       else                            $parsed .= "$block_text";
+                                       
+                                       # Start over a new block.
+                                       $block_text = "";
+                               }
+                               else $block_text .= $tag;
+                       }
+                       
+               } while ($depth > 0);
+               
+               #
+               # Hash last block text that wasn't processed inside the loop.
+               #
+               $parsed .= $this->$hash_method($block_text);
+               
+               return array($parsed, $text);
+       }
+
+
+       function hashClean($text) {
+       #
+       # Called whenever a tag must be hashed when a function insert a "clean" tag
+       # in $text, it pass through this function and is automaticaly escaped, 
+       # blocking invalid nested overlap.
+       #
+               return $this->hashPart($text, 'C');
+       }
+
+
+       function doHeaders($text) {
+       #
+       # Redefined to add id attribute support.
+       #
+               # Setext-style headers:
+               #         Header 1  {#header1}
+               #         ========
+               #  
+               #         Header 2  {#header2}
+               #         --------
+               #
+               $text = preg_replace_callback(
+                       '{
+                               (^.+?)                                                          # $1: Header text
+                               (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})?        # $2: Id attribute
+                               [ ]*\n(=+|-+)[ ]*\n+                            # $3: Header footer
+                       }mx',
+                       array(&$this, '_doHeaders_callback_setext'), $text);
+
+               # atx-style headers:
+               #       # Header 1        {#header1}
+               #       ## Header 2       {#header2}
+               #       ## Header 2 with closing hashes ##  {#header3}
+               #       ...
+               #       ###### Header 6   {#header2}
+               #
+               $text = preg_replace_callback('{
+                               ^(\#{1,6})      # $1 = string of #\'s
+                               [ ]*
+                               (.+?)           # $2 = Header text
+                               [ ]*
+                               \#*                     # optional closing #\'s (not counted)
+                               (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute
+                               [ ]*
+                               \n+
+                       }xm',
+                       array(&$this, '_doHeaders_callback_atx'), $text);
+
+               return $text;
+       }
+       function _doHeaders_attr($attr) {
+               if (empty($attr))  return "";
+               return " id=\"$attr\"";
+       }
+       function _doHeaders_callback_setext($matches) {
+               if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
+                       return $matches[0];
+               $level = $matches[3]{0} == '=' ? 1 : 2;
+               $attr  = $this->_doHeaders_attr($id =& $matches[2]);
+               $block = "<h$level$attr>".$this->runSpanGamut($matches[1])."</h$level>";
+               return "\n" . $this->hashBlock($block) . "\n\n";
+       }
+       function _doHeaders_callback_atx($matches) {
+               $level = strlen($matches[1]);
+               $attr  = $this->_doHeaders_attr($id =& $matches[3]);
+               $block = "<h$level$attr>".$this->runSpanGamut($matches[2])."</h$level>";
+               return "\n" . $this->hashBlock($block) . "\n\n";
+       }
+
+
+       function doTables($text) {
+       #
+       # Form HTML tables.
+       #
+               $less_than_tab = $this->tab_width - 1;
+               #
+               # Find tables with leading pipe.
+               #
+               #       | Header 1 | Header 2
+               #       | -------- | --------
+               #       | Cell 1   | Cell 2
+               #       | Cell 3   | Cell 4
+               #
+               $text = preg_replace_callback('
+                       {
+                               ^                                                       # Start of a line
+                               [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
+                               [|]                                                     # Optional leading pipe (present)
+                               (.+) \n                                         # $1: Header row (at least one pipe)
+                               
+                               [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
+                               [|] ([ ]*[-:]+[-| :]*) \n       # $2: Header underline
+                               
+                               (                                                       # $3: Cells
+                                       (?>
+                                               [ ]*                            # Allowed whitespace.
+                                               [|] .* \n                       # Row content.
+                                       )*
+                               )
+                               (?=\n|\Z)                                       # Stop at final double newline.
+                       }xm',
+                       array(&$this, '_doTable_leadingPipe_callback'), $text);
+               
+               #
+               # Find tables without leading pipe.
+               #
+               #       Header 1 | Header 2
+               #       -------- | --------
+               #       Cell 1   | Cell 2
+               #       Cell 3   | Cell 4
+               #
+               $text = preg_replace_callback('
+                       {
+                               ^                                                       # Start of a line
+                               [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
+                               (\S.*[|].*) \n                          # $1: Header row (at least one pipe)
+                               
+                               [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
+                               ([-:]+[ ]*[|][-| :]*) \n        # $2: Header underline
+                               
+                               (                                                       # $3: Cells
+                                       (?>
+                                               .* [|] .* \n            # Row content
+                                       )*
+                               )
+                               (?=\n|\Z)                                       # Stop at final double newline.
+                       }xm',
+                       array(&$this, '_DoTable_callback'), $text);
+
+               return $text;
+       }
+       function _doTable_leadingPipe_callback($matches) {
+               $head           = $matches[1];
+               $underline      = $matches[2];
+               $content        = $matches[3];
+               
+               # Remove leading pipe for each row.
+               $content        = preg_replace('/^ *[|]/m', '', $content);
+               
+               return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
+       }
+       function _doTable_callback($matches) {
+               $head           = $matches[1];
+               $underline      = $matches[2];
+               $content        = $matches[3];
+
+               # Remove any tailing pipes for each line.
+               $head           = preg_replace('/[|] *$/m', '', $head);
+               $underline      = preg_replace('/[|] *$/m', '', $underline);
+               $content        = preg_replace('/[|] *$/m', '', $content);
+               
+               # Reading alignement from header underline.
+               $separators     = preg_split('/ *[|] */', $underline);
+               foreach ($separators as $n => $s) {
+                       if (preg_match('/^ *-+: *$/', $s))              $attr[$n] = ' align="right"';
+                       else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"';
+                       else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"';
+                       else                                                                    $attr[$n] = '';
+               }
+               
+               # Parsing span elements, including code spans, character escapes, 
+               # and inline HTML tags, so that pipes inside those gets ignored.
+               $head           = $this->parseSpan($head);
+               $headers        = preg_split('/ *[|] */', $head);
+               $col_count      = count($headers);
+               
+               # Write column headers.
+               $text = "<table>\n";
+               $text .= "<thead>\n";
+               $text .= "<tr>\n";
+               foreach ($headers as $n => $header)
+                       $text .= "  <th$attr[$n]>".$this->runSpanGamut(trim($header))."</th>\n";
+               $text .= "</tr>\n";
+               $text .= "</thead>\n";
+               
+               # Split content by row.
+               $rows = explode("\n", trim($content, "\n"));
+               
+               $text .= "<tbody>\n";
+               foreach ($rows as $row) {
+                       # Parsing span elements, including code spans, character escapes, 
+                       # and inline HTML tags, so that pipes inside those gets ignored.
+                       $row = $this->parseSpan($row);
+                       
+                       # Split row by cell.
+                       $row_cells = preg_split('/ *[|] */', $row, $col_count);
+                       $row_cells = array_pad($row_cells, $col_count, '');
+                       
+                       $text .= "<tr>\n";
+                       foreach ($row_cells as $n => $cell)
+                               $text .= "  <td$attr[$n]>".$this->runSpanGamut(trim($cell))."</td>\n";
+                       $text .= "</tr>\n";
+               }
+               $text .= "</tbody>\n";
+               $text .= "</table>";
+               
+               return $this->hashBlock($text) . "\n";
+       }
+
+       
+       function doDefLists($text) {
+       #
+       # Form HTML definition lists.
+       #
+               $less_than_tab = $this->tab_width - 1;
+
+               # Re-usable pattern to match any entire dl list:
+               $whole_list_re = '(?>
+                       (                                                               # $1 = whole list
+                         (                                                             # $2
+                               [ ]{0,'.$less_than_tab.'}
+                               ((?>.*\S.*\n)+)                              # $3 = defined term
+                               \n?
+                               [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+                         )
+                         (?s:.+?)
+                         (                                                             # $4
+                                 \z
+                               |
+                                 \n{2,}
+                                 (?=\S)
+                                 (?!                                           # Negative lookahead for another term
+                                       [ ]{0,'.$less_than_tab.'}
+                                       (?: \S.*\n )+?                  # defined term
+                                       \n?
+                                       [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+                                 )
+                                 (?!                                           # Negative lookahead for another definition
+                                       [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+                                 )
+                         )
+                       )
+               )'; // mx
+
+               $text = preg_replace_callback('{
+                               (?>\A\n?|(?<=\n\n))
+                               '.$whole_list_re.'
+                       }mx',
+                       array(&$this, '_doDefLists_callback'), $text);
+
+               return $text;
+       }
+       function _doDefLists_callback($matches) {
+               # Re-usable patterns to match list item bullets and number markers:
+               $list = $matches[1];
+               
+               # Turn double returns into triple returns, so that we can make a
+               # paragraph for the last item in a list, if necessary:
+               $result = trim($this->processDefListItems($list));
+               $result = "<dl>\n" . $result . "\n</dl>";
+               return $this->hashBlock($result) . "\n\n";
+       }
+
+
+       function processDefListItems($list_str) {
+       #
+       #       Process the contents of a single definition list, splitting it
+       #       into individual term and definition list items.
+       #
+               $less_than_tab = $this->tab_width - 1;
+               
+               # trim trailing blank lines:
+               $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+               # Process definition terms.
+               $list_str = preg_replace_callback('{
+                       (?>\A\n?|\n\n+)                                      # leading line
+                       (                                                               # definition terms = $1
+                               [ ]{0,'.$less_than_tab.'}       # leading whitespace
+                               (?![:][ ]|[ ])                          # negative lookahead for a definition 
+                                                                                       #   mark (colon) or more whitespace.
+                               (?> \S.* \n)+?                               # actual term (not whitespace). 
+                       )                       
+                       (?=\n?[ ]{0,3}:[ ])                             # lookahead for following line feed 
+                                                                                       #   with a definition mark.
+                       }xm',
+                       array(&$this, '_processDefListItems_callback_dt'), $list_str);
+
+               # Process actual definitions.
+               $list_str = preg_replace_callback('{
+                       \n(\n+)?                                                # leading line = $1
+                       (                                                               # marker space = $2
+                               [ ]{0,'.$less_than_tab.'}       # whitespace before colon
+                               [:][ ]+                                         # definition mark (colon)
+                       )
+                       ((?s:.+?))                                              # definition text = $3
+                       (?= \n+                                                 # stop at next definition mark,
+                               (?:                                                     # next term or end of text
+                                       [ ]{0,'.$less_than_tab.'} [:][ ]        |
+                                       <dt> | \z
+                               )                                               
+                       )                                       
+                       }xm',
+                       array(&$this, '_processDefListItems_callback_dd'), $list_str);
+
+               return $list_str;
+       }
+       function _processDefListItems_callback_dt($matches) {
+               $terms = explode("\n", trim($matches[1]));
+               $text = '';
+               foreach ($terms as $term) {
+                       $term = $this->runSpanGamut(trim($term));
+                       $text .= "\n<dt>" . $term . "</dt>";
+               }
+               return $text . "\n";
+       }
+       function _processDefListItems_callback_dd($matches) {
+               $leading_line   = $matches[1];
+               $marker_space   = $matches[2];
+               $def                    = $matches[3];
+
+               if ($leading_line || preg_match('/\n{2,}/', $def)) {
+                       # Replace marker with the appropriate whitespace indentation
+                       $def = str_repeat(' ', strlen($marker_space)) . $def;
+                       $def = $this->runBlockGamut($this->outdent($def . "\n\n"));
+                       $def = "\n". $def ."\n";
+               }
+               else {
+                       $def = rtrim($def);
+                       $def = $this->runSpanGamut($this->outdent($def));
+               }
+
+               return "\n<dd>" . $def . "</dd>\n";
+       }
+
+
+       function doFencedCodeBlocks($text) {
+       #
+       # Adding the fenced code block syntax to regular Markdown:
+       #
+       # ~~~
+       # Code block
+       # ~~~
+       #
+               $less_than_tab = $this->tab_width;
+               
+               $text = preg_replace_callback('{
+                               (?:\n|\A)
+                               # 1: Opening marker
+                               (
+                                       ~{3,} # Marker: three tilde or more.
+                               )
+                               [ ]* \n # Whitespace and newline following marker.
+                               
+                               # 2: Content
+                               (
+                                       (?>
+                                               (?!\1 [ ]* \n)  # Not a closing marker.
+                                               .*\n+
+                                       )+
+                               )
+                               
+                               # Closing marker.
+                               \1 [ ]* \n
+                       }xm',
+                       array(&$this, '_doFencedCodeBlocks_callback'), $text);
+
+               return $text;
+       }
+       function _doFencedCodeBlocks_callback($matches) {
+               $codeblock = $matches[2];
+               $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+               $codeblock = preg_replace_callback('/^\n+/',
+                       array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock);
+               $codeblock = "<pre><code>$codeblock</code></pre>";
+               return "\n\n".$this->hashBlock($codeblock)."\n\n";
+       }
+       function _doFencedCodeBlocks_newlines($matches) {
+               return str_repeat("<br$this->empty_element_suffix", 
+                       strlen($matches[0]));
+       }
+
+
+       #
+       # Redefining emphasis markers so that emphasis by underscore does not
+       # work in the middle of a word.
+       #
+       var $em_relist = array(
+               ''  => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?=\S|$)(?![.,:;]\s)',
+               '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
+               '_' => '(?<=\S|^)(?<!_)_(?![a-zA-Z0-9_])',
+               );
+       var $strong_relist = array(
+               ''   => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?=\S|$)(?![.,:;]\s)',
+               '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
+               '__' => '(?<=\S|^)(?<!_)__(?![a-zA-Z0-9_])',
+               );
+       var $em_strong_relist = array(
+               ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?=\S|$)(?![.,:;]\s)',
+               '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
+               '___' => '(?<=\S|^)(?<!_)___(?![a-zA-Z0-9_])',
+               );
+
+
+       function formParagraphs($text) {
+       #
+       #       Params:
+       #               $text - string to process with html <p> tags
+       #
+               # Strip leading and trailing lines:
+               $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+               
+               $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+               #
+               # Wrap <p> tags and unhashify HTML blocks
+               #
+               foreach ($grafs as $key => $value) {
+                       $value = trim($this->runSpanGamut($value));
+                       
+                       # Check if this should be enclosed in a paragraph.
+                       # Clean tag hashes & block tag hashes are left alone.
+                       $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
+                       
+                       if ($is_p) {
+                               $value = "<p>$value</p>";
+                       }
+                       $grafs[$key] = $value;
+               }
+               
+               # Join grafs in one text, then unhash HTML tags. 
+               $text = implode("\n\n", $grafs);
+               
+               # Finish by removing any tag hashes still present in $text.
+               $text = $this->unhash($text);
+               
+               return $text;
+       }
+       
+       
+       ### Footnotes
+       
+       function stripFootnotes($text) {
+       #
+       # Strips link definitions from text, stores the URLs and titles in
+       # hash references.
+       #
+               $less_than_tab = $this->tab_width - 1;
+
+               # Link defs are in the form: [^id]: url "optional title"
+               $text = preg_replace_callback('{
+                       ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?:      # note_id = $1
+                         [ ]*
+                         \n?                                   # maybe *one* newline
+                       (                                               # text = $2 (no blank lines allowed)
+                               (?:                                     
+                                       .+                              # actual text
+                               |
+                                       \n                              # newlines but 
+                                       (?!\[\^.+?\]:\s)# negative lookahead for footnote marker.
+                                       (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed 
+                                                                       # by non-indented content
+                               )*
+                       )               
+                       }xm',
+                       array(&$this, '_stripFootnotes_callback'),
+                       $text);
+               return $text;
+       }
+       function _stripFootnotes_callback($matches) {
+               $note_id = $this->fn_id_prefix . $matches[1];
+               $this->footnotes[$note_id] = $this->outdent($matches[2]);
+               return ''; # String that will replace the block
+       }
+
+
+       function doFootnotes($text) {
+       #
+       # Replace footnote references in $text [^id] with a special text-token 
+       # which will be replaced by the actual footnote marker in appendFootnotes.
+       #
+               if (!$this->in_anchor) {
+                       $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
+               }
+               return $text;
+       }
+
+       
+       function appendFootnotes($text) {
+       #
+       # Append footnote list to text.
+       #
+               $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', 
+                       array(&$this, '_appendFootnotes_callback'), $text);
+       
+               if (!empty($this->footnotes_ordered)) {
+                       $text .= "\n\n";
+                       $text .= "<div class=\"footnotes\">\n";
+                       $text .= "<hr". $this->empty_element_suffix ."\n";
+                       $text .= "<ol>\n\n";
+                       
+                       $attr = " rev=\"footnote\"";
+                       if ($this->fn_backlink_class != "") {
+                               $class = $this->fn_backlink_class;
+                               $class = $this->encodeAttribute($class);
+                               $attr .= " class=\"$class\"";
+                       }
+                       if ($this->fn_backlink_title != "") {
+                               $title = $this->fn_backlink_title;
+                               $title = $this->encodeAttribute($title);
+                               $attr .= " title=\"$title\"";
+                       }
+                       $num = 0;
+                       
+                       while (!empty($this->footnotes_ordered)) {
+                               $footnote = reset($this->footnotes_ordered);
+                               $note_id = key($this->footnotes_ordered);
+                               unset($this->footnotes_ordered[$note_id]);
+                               
+                               $footnote .= "\n"; # Need to append newline before parsing.
+                               $footnote = $this->runBlockGamut("$footnote\n");                           
+                               $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', 
+                                       array(&$this, '_appendFootnotes_callback'), $footnote);
+                               
+                               $attr = str_replace("%%", ++$num, $attr);
+                               $note_id = $this->encodeAttribute($note_id);
+                               
+                               # Add backlink to last paragraph; create new paragraph if needed.
+                               $backlink = "<a href=\"#fnref:$note_id\"$attr>&#8617;</a>";
+                               if (preg_match('{</p>$}', $footnote)) {
+                                       $footnote = substr($footnote, 0, -4) . "&#160;$backlink</p>";
+                               } else {
+                                       $footnote .= "\n\n<p>$backlink</p>";
+                               }
+                               
+                               $text .= "<li id=\"fn:$note_id\">\n";
+                               $text .= $footnote . "\n";
+                               $text .= "</li>\n\n";
+                       }
+                       
+                       $text .= "</ol>\n";
+                       $text .= "</div>";
+               }
+               return $text;
+       }
+       function _appendFootnotes_callback($matches) {
+               $node_id = $this->fn_id_prefix . $matches[1];
+               
+               # Create footnote marker only if it has a corresponding footnote *and*
+               # the footnote hasn't been used by another marker.
+               if (isset($this->footnotes[$node_id])) {
+                       # Transfert footnote content to the ordered list.
+                       $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
+                       unset($this->footnotes[$node_id]);
+                       
+                       $num = $this->footnote_counter++;
+                       $attr = " rel=\"footnote\"";
+                       if ($this->fn_link_class != "") {
+                               $class = $this->fn_link_class;
+                               $class = $this->encodeAttribute($class);
+                               $attr .= " class=\"$class\"";
+                       }
+                       if ($this->fn_link_title != "") {
+                               $title = $this->fn_link_title;
+                               $title = $this->encodeAttribute($title);
+                               $attr .= " title=\"$title\"";
+                       }
+                       
+                       $attr = str_replace("%%", $num, $attr);
+                       $node_id = $this->encodeAttribute($node_id);
+                       
+                       return
+                               "<sup id=\"fnref:$node_id\">".
+                               "<a href=\"#fn:$node_id\"$attr>$num</a>".
+                               "</sup>";
+               }
+               
+               return "[^".$matches[1]."]";
+       }
+               
+       
+       ### Abbreviations ###
+       
+       function stripAbbreviations($text) {
+       #
+       # Strips abbreviations from text, stores titles in hash references.
+       #
+               $less_than_tab = $this->tab_width - 1;
+
+               # Link defs are in the form: [id]*: url "optional title"
+               $text = preg_replace_callback('{
+                       ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?:      # abbr_id = $1
+                       (.*)                                    # text = $2 (no blank lines allowed)    
+                       }xm',
+                       array(&$this, '_stripAbbreviations_callback'),
+                       $text);
+               return $text;
+       }
+       function _stripAbbreviations_callback($matches) {
+               $abbr_word = $matches[1];
+               $abbr_desc = $matches[2];
+               if ($this->abbr_word_re)
+                       $this->abbr_word_re .= '|';
+               $this->abbr_word_re .= preg_quote($abbr_word);
+               $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+               return ''; # String that will replace the block
+       }
+       
+       
+       function doAbbreviations($text) {
+       #
+       # Find defined abbreviations in text and wrap them in <abbr> elements.
+       #
+               if ($this->abbr_word_re) {
+                       // cannot use the /x modifier because abbr_word_re may 
+                       // contain significant spaces:
+                       $text = preg_replace_callback('{'.
+                               '(?<![\w\x1A])'.
+                               '(?:'.$this->abbr_word_re.')'.
+                               '(?![\w\x1A])'.
+                               '}', 
+                               array(&$this, '_doAbbreviations_callback'), $text);
+               }
+               return $text;
+       }
+       function _doAbbreviations_callback($matches) {
+               $abbr = $matches[0];
+               if (isset($this->abbr_desciptions[$abbr])) {
+                       $desc = $this->abbr_desciptions[$abbr];
+                       if (empty($desc)) {
+                               return $this->hashPart("<abbr>$abbr</abbr>");
+                       } else {
+                               $desc = $this->encodeAttribute($desc);
+                               return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
+                       }
+               } else {
+                       return $matches[0];
+               }
+       }
+
+}
+
+
+/*
+
+PHP Markdown Extra
+==================
+
+Description
+-----------
+
+This is a PHP port of the original Markdown formatter written in Perl 
+by John Gruber. This special "Extra" version of PHP Markdown features 
+further enhancements to the syntax for making additional constructs 
+such as tables and definition list.
+
+Markdown is a text-to-HTML filter; it translates an easy-to-read /
+easy-to-write structured text format into HTML. Markdown's text format
+is most similar to that of plain text email, and supports features such
+as headers, *emphasis*, code blocks, blockquotes, and links.
+
+Markdown's syntax is designed not as a generic markup language, but
+specifically to serve as a front-end to (X)HTML. You can use span-level
+HTML tags anywhere in a Markdown document, and you can use block level
+HTML tags (like <div> and <table> as well).
+
+For more information about Markdown's syntax, see:
+
+<http://daringfireball.net/projects/markdown/>
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+
+<michel.fortin@michelf.com>
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output Markdown actually produced.
+
+
+Version History
+--------------- 
+
+See the readme file for detailed release notes for this version.
+
+
+Copyright and License
+---------------------
+
+PHP Markdown & Extra  
+Copyright (c) 2004-2009 Michel Fortin  
+<http://michelf.com/>  
+All rights reserved.
+
+Based on Markdown  
+Copyright (c) 2003-2006 John Gruber   
+<http://daringfireball.net/>   
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+*      Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+
+*      Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+*      Neither the name "Markdown" nor the names of its contributors may
+       be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as
+is" and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed. In no event shall the copyright owner
+or contributors be liable for any direct, indirect, incidental, special,
+exemplary, or consequential damages (including, but not limited to,
+procurement of substitute goods or services; loss of use, data, or
+profits; or business interruption) however caused and on any theory of
+liability, whether in contract, strict liability, or tort (including
+negligence or otherwise) arising in any way out of the use of this
+software, even if advised of the possibility of such damage.
+
+*/
+?>
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/readme-parser/markdown.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsGruntfilejs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/Gruntfile.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/Gruntfile.js                            (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/Gruntfile.js      2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,89 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* jshint node:true */
+module.exports = function(grunt) {
+       var path = require('path');
+
+       // Load tasks.
+       require('matchdep').filterDev(['grunt-*']).forEach( grunt.loadNpmTasks );
+
+       // Project configuration.
+       grunt.initConfig({
+               rtlcss: {
+                       options: {
+                               // rtlcss options
+                               config: {
+                                       swapLeftRightInUrl: false,
+                                       swapLtrRtlInUrl: false,
+                                       autoRename: false,
+                                       preserveDirectives: true,
+                                       stringMap: [
+                                               {
+                                                       name: 'import-rtl-stylesheet',
+                                                       search: [ '.css' ],
+                                                       replace: [ '-rtl.css' ],
+                                                       options: {
+                                                               scope: 'url',
+                                                               ignoreCase: false
+                                                       }
+                                               }
+                                       ]
+                               },
+                               properties : [
+                                       {
+                                               name: 'swap-dashicons-left-right-arrows',
+                                               expr: /content/im,
+                                               action: function( prop, value ) {
+                                                       if ( value === '"\\f141"' ) { // dashicons-arrow-left
+                                                               value = '"\\f139"';
+                                                       } else if ( value === '"\\f340"' ) { // dashicons-arrow-left-alt
+                                                               value = '"\\f344"';
+                                                       } else if ( value === '"\\f341"' ) { // dashicons-arrow-left-alt2
+                                                               value = '"\\f345"';
+                                                       } else if ( value === '"\\f139"' ) { // dashicons-arrow-right
+                                                               value = '"\\f141"';
+                                                       } else if ( value === '"\\f344"' ) { // dashicons-arrow-right-alt
+                                                               value = '"\\f340"';
+                                                       } else if ( value === '"\\f345"' ) { // dashicons-arrow-right-alt2
+                                                               value = '"\\f341"';
+                                                       } else if ( value === '"\\2192"' ) { // Unicode rightwards arrow
+                                                               value = '"\\2190"';
+                                                       } else if ( value === '"\\2190"' ) { // Unicode leftwards arrow
+                                                               value = '"\\2192"';
+                                                       }
+                                                       return { prop: prop, value: value };
+                                               }
+                                       }
+                               ],
+                               saveUnmodified: false
+                       },
+                       theme: {
+                               expand: true,
+                               ext: '-rtl.css',
+                               src: [
+                                       'style.css',
+                               ]
+                       },
+               },
+               uglify: {
+                       options: {
+                               ASCIIOnly: true
+                       },
+                       js: {
+                               expand: true,
+                               ext: '.min.js',
+                               src: [ 'js/theme.js' ]
+                       }
+               }
+       });
+
+       // Register tasks.
+
+       grunt.registerTask( 'build', [
+               'rtlcss',
+               'uglify'
+       ] );
+
+       // Default task.
+       grunt.registerTask('default', ['build']);
+
+};
+
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsfilterbarphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/filter-bar.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/filter-bar.php                          (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/filter-bar.php    2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,25 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<div class="wrapper">
+       <div class="col-12 filter-bar">
+               <div class="wp-filter">
+                       <ul class="filter-links">
+                               <?php if ( get_query_var('s' ) ) { ?>
+                                       <li class="plugin-install-search"><a href="<?php echo esc_url( home_url( 'search/' . urlencode( get_query_var('s') ) . '/' ) ); ?>" class="current"><?php _ex( 'Search Results', 'tab', 'wporg-plugins' ); ?></a></li>
+                               <?php } ?>
+                               <li class="plugin-install-featured"><a href="<?php echo esc_url( home_url( 'browse/featured/' ) ); ?>" <?php if ( (is_front_page() && !get_query_var('browse') ) || 'featured' == get_query_var('browse') ) { echo 'class="current"'; } ?>><?php _ex( 'Featured', 'plugins', 'wporg-plugins' ); ?></a></li>
+                               <li class="plugin-install-popular"><a href="<?php echo esc_url( home_url( 'browse/popular/' ) ); ?>" <?php if ( 'popular' == get_query_var('browse') ) { echo 'class="current"'; } ?>><?php _ex( 'Popular', 'plugins', 'wporg-plugins' ); ?></a> </li>
+                               <?php if ( is_user_logged_in() ) { ?>
+                                       <li class="plugin-install-favorites"><a href="<?php echo esc_url( home_url( 'browse/favorites/' ) ); ?>" <?php if ( 'favorites' == get_query_var('browse') ) { echo 'class="current"'; } ?>><?php _ex( 'Favorites', 'plugins', 'wporg-plugins' ); ?></a></li>
+                               <?php } ?>
+                               <li class="plugin-install-beta"><a href="<?php echo esc_url( home_url( 'browse/beta/' ) ); ?>" <?php if ( 'beta' == get_query_var('browse') ) { echo 'class="current"'; } ?>><?php _ex( 'Beta Testing', 'plugins', 'wporg-plugins' ); ?></a></li>
+                               <li class="plugin-developer"><a href="<?php echo get_permalink( get_page_by_path( 'about' ) ); ?>" <?php if ( 'about' == get_query_var( 'pagename' ) ) { echo 'class="current"'; } ?>><?php _ex( 'Developers', 'plugins', 'wporg-plugins' ); ?></a></li>
+                       </ul>
+
+                       <form class="search-form search-plugins" method="get" action="<?php echo home_url('/'); ?>">
+                                       <label><span class="screen-reader-text"><?php _e( 'Search Plugins', 'wporg-plugins' ); ?></span>
+                                       <input type="search" name="s" value="<?php echo esc_attr( get_query_var('s') ); ?>" class="wp-filter-search" placeholder="<?php esc_attr_e( 'Search plugins...', 'wporg-plugins' ); ?>">
+                               </label>
+                               <input type="submit" name="" id="search-submit" class="button screen-reader-text" value="<?php esc_attr_e( 'Search Plugins', 'wporg-plugins' ); ?>">
+                       </form>
+               </div>
+       </div>
+</div>
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/filter-bar.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsfooterphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/footer.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/footer.php                              (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/footer.php        2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,10 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * The template for displaying the footer.
+ *
+ * @package wporg-plugins
+ */
+?>
+</div>
+
+<?php require WPORGPATH . 'footer.php';
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/footer.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsfunctionsphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/functions.php                           (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/functions.php     2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,53 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * WP.org Themes' functions and definitions.
+ *
+ * @package wporg-plugins
+ */
+
+function wporg_plugins_setup() {
+       global $themes_allowedtags;
+
+       load_theme_textdomain( 'wporg-plugins' );
+
+       include_once __DIR__ . '/template-tags.php';
+
+       add_theme_support( 'html5', array(
+               'search-form', 'comment-form', 'comment-list', 'gallery', 'caption'
+       ) );
+
+       // No need for canonical lookups
+       //remove_action( 'template_redirect', 'redirect_canonical' );
+       remove_action( 'template_redirect', 'wp_old_slug_redirect' );
+}
+add_action( 'after_setup_theme', 'wporg_plugins_setup' );
+
+/**
+ * Enqueue scripts and styles.
+ */
+function wporg_plugins_scripts() {
+       $script_debug = true || defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG;
+       $suffix       = $script_debug ? '' : '.min';
+
+       // Concatenates core scripts when possible.
+       if ( ! $script_debug ) {
+               $GLOBALS['concatenate_scripts'] = true;
+       }
+
+       $stylesheet = get_stylesheet_uri();
+       if ( is_rtl() ) {
+//             $stylesheet = str_replace( '.css', '-rtl.css', $stylesheet ); // TODO, not being generated yet
+       }
+       wp_enqueue_style( 'wporg-plugins', $stylesheet, array(), time() );
+
+       // No Jetpack styles needed.
+       add_filter( 'jetpack_implode_frontend_css', '__return_false' );
+}
+add_action( 'wp_enqueue_scripts', 'wporg_plugins_scripts' );
+
+function wporg_plugins_body_class( $classes ) {
+       $classes[] = 'plugins-directory';
+       return $classes;
+}
+add_filter( 'body_class', 'wporg_plugins_body_class' );
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/functions.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsheaderphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/header.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/header.php                              (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/header.php        2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,39 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * The header for our theme.
+ *
+ * @package wporg-plugins
+ */
+
+$GLOBALS['pagetitle'] = __( 'Plugin Directory &mdash; Free WordPress Plugins', 'wporg-plugins' );
+
+require WPORGPATH . 'header.php';
+?>
+
+<div id="headline">
+       <div class="wrapper">
+               <h2><a href="<?php echo home_url('/'); ?>"><?php _e( 'Plugin Directory', 'wporg-plugins' ); ?></a></h2>
+               <?php
+               $items = array();
+               if ( is_user_logged_in() ) {
+                       $items[] = sprintf(
+                               __( 'Welcome, %s', 'wporg-plugins' ),
+                               sprintf(
+                                       '<a href="https://profiles.wordpress.org/%s">%s</a>',
+                                       wp_get_current_user()->user_nicename,
+                                       wp_get_current_user()->display_name
+                               )
+                       );
+                       if ( true /* user_has_plugins */ ) {
+                               $items[] = '<a href="' . admin_url( 'edit.php?post_type=plugin' ) . '">' . __( 'Manage My Plugins', 'wporg-plugins' ) . '</a>';
+                       }
+                       $items[] = '<a href="https://login.wordpress.org/logout">' . __( 'Log Out', 'wporg-plugins' ) . '</a>';
+               } else {
+                       $items[] = '<a href="https://login.wordpress.org/?redirect_to=' . urlencode( wporg_plugins_self_link() ) . '">' . __( 'Log In', 'wporg-plugins' ) . '</a>';
+               }
+               echo '<p class="login">' . implode( ' | ', $items ) . '</p>';
+               ?>
+       </div>
+</div>
+
+<div id="pagebody">
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/header.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsindexphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/index.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/index.php                               (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/index.php 2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,29 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php get_header(); ?>
+
+<?php get_template_part( 'filter-bar' ); ?>
+
+<div class="wrapper">
+       <div class="col-12" itemscope itemtype="http://schema.org/SoftwareApplication">
+               <?php get_template_part( 'view-intro' ); ?>
+
+               <div class="plugin-group">
+               
+               <?php
+                       if ( have_posts() ) {
+                               while ( have_posts() ) {
+                                       the_post();
+                                       get_template_part( 'plugin-card' );
+                               }
+                       } else {
+                               echo '<p class="no-plugin-results">No plugins match your request.</p>';
+                       }
+               ?>
+
+               </div>
+
+       </div>
+</div>
+
+<br class="clear" />
+<?php
+get_footer();
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/index.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginspagephp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/page.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/page.php                                (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/page.php  2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,16 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php get_header(); ?>
+
+<?php the_post(); ?>
+
+<?php get_template_part( 'filter-bar' ); ?>
+
+<div class="wrapper">
+       <div class="col-12" itemscope itemtype="http://schema.org/SoftwareApplication">
+               <h2><?php the_title(); ?></h2>
+               <?php the_content(); ?>
+       </div>
+</div>
+
+<br class="clear" />
+<?php
+get_footer();
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/page.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsplugincardphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/plugin-card.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/plugin-card.php                         (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/plugin-card.php   2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,28 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<div class="plugin-card">
+        <div class="plugin-card-top">
+
+                <a href="<?php the_permalink(); ?>" class="plugin-icon"><style>#plugin-icon-<?php echo esc_attr( $post->post_name ); ?> { width:128px; height:128px; background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTEiIGhlaWdodD0iMTI5IiB2aWV3Ym94PSIwIDAgMTExIDEyOSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0icmdiKDI0MSwgMjQxLCAyNDEpIiAvPjxyZWN0IHg9Ii0xMS44MzMzMzMzMzMzMzMiIHk9Ii0xMS44MzMzMzMzMzMzMzMiIHdpZHRoPSIyMy42NjY2NjY2NjY2NjciIGhlaWdodD0iMjMuNjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDg5MzMzMzMzMzMzMzMzIiBzdHJva2Utd2lkdGg9IjEiIC8+PHJlY3QgeD0iMTAwLjE1ODUzNTc3OTEzIiB5PSItMTEuODMzMzMzMzMzMzMzIiB3aWR0aD0iMjMuNjY2NjY2NjY2NjY3IiBoZWlnaHQ9IjIzLjY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjA4OTMzMzMzMzMzMzMzMyIgc3
 Ryb2tlLXdpZHRoPSIxIiAvPjxyZWN0IHg9Ii0xMS44MzMzMzMzMzMzMzMiIHk9IjExNy40ODM3MzgyMjQ5MyIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wODkzMzMzMzMzMzMzMzMiIHN0cm9rZS13aWR0aD0iMSIgLz48cmVjdCB4PSIxMDAuMTU4NTM1Nzc5MTMiIHk9IjExNy40ODM3MzgyMjQ5MyIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wODkzMzMzMzMzMzMzMzMiIHN0cm9rZS13aWR0aD0iMSIgLz48cmVjdCB4PSI0NC4xNjI2MDEyMjI4OTgiIHk9IjIwLjQ5NTkzNDU1NjIzMiIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xMDY2NjY2NjY2NjY2NyIgc3Ryb2tlLXdpZHRoPSIxIiAvPjxyZWN0IHg9Ii0xMS44MzMzMzMzMzMzMzMiIHk9IjUyLjgyNTIwMjQ0NTc5NyIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZ
 pbGwtb3BhY2l0eT0iMC4xMDY2NjY2NjY2NjY2NyIgc3Ryb2tlLXdpZHRoPSIxIiAvPjxyZWN0IHg9IjEwMC4xNTg1MzU3NzkxMyIgeT0iNTIuODI1MjAyNDQ1Nzk3IiB3aWR0aD0iMjMuNjY2NjY2NjY2NjY3IiBoZWlnaHQ9IjIzLjY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjEwNjY2NjY2NjY2NjY3IiBzdHJva2Utd2lkdGg9IjEiIC8+PHJlY3QgeD0iNDQuMTYyNjAxMjIyODk4IiB5PSI4NS4xNTQ0NzAzMzUzNjIiIHdpZHRoPSIyMy42NjY2NjY2NjY2NjciIGhlaWdodD0iMjMuNjY2NjY2NjY2NjY3IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMTE1MzMzMzMzMzMzMzMiIHN0cm9rZS13aWR0aD0iMSIgLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCAyMC40OTU5MzQ1NTYyMzIsIDExLjgzMzMzMzMzMzMzMywgMCwgMjMuNjY2NjY2NjY2NjY3LCAwLCAwIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDcyIiBzdHJva2Utd2lkdGg9IjEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExLjgzMzMzMzMzMzMzMywgLTExLjgzMzMzMzMzMzMzMykgcm90YXRlKDAsIDExLjgzMzMzMzMzMzMzMywgMTAuMjQ3OTY3Mjc4MTE2KSIgLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCAyMC40OTU5MzQ1NTYy
 MzIsIDExLjgzMzMzMzMzMzMzMywgMCwgMjMuNjY2NjY2NjY2NjY3LCAwLCAwIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDcyIiBzdHJva2Utd2lkdGg9IjEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExLjgzMzMzMzMzMzMzMywgMTQxLjE1MDQwNDg5MTU5KSByb3RhdGUoMCwgMTEuODMzMzMzMzMzMzMzLCAxMC4yNDc5NjcyNzgxMTYpIHNjYWxlKDEsIC0xKSIgLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCAyMC40OTU5MzQ1NTYyMzIsIDExLjgzMzMzMzMzMzMzMywgMCwgMjMuNjY2NjY2NjY2NjY3LCAwLCAwIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZS13aWR0aD0iMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAwLjE1ODUzNTc3OTEzLCAtMTEuODMzMzMzMzMzMzMzKSByb3RhdGUoMCwgMTEuODMzMzMzMzMzMzMzLCAxMC4yNDc5NjcyNzgxMTYpIHNjYWxlKC0xLCAxKSIgLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCAyMC40OTU5MzQ1NTYyMzIsIDExLjgzMzMzMzMzMzMzMywgMCwgMjMuNjY2NjY2NjY2NjY3LCAwLCAwIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZS13aWR0aD0iMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAwLjE1ODUzNTc3OTEzLCAxNDEuMTUwN
 DA0ODkxNTkpIHJvdGF0ZSgwLCAxMS44MzMzMzMzMzMzMzMsIDEwLjI0Nzk2NzI3ODExNikgc2NhbGUoLTEsIC0xKSIgLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCAyMC40OTU5MzQ1NTYyMzIsIDExLjgzMzMzMzMzMzMzMywgMCwgMjMuNjY2NjY2NjY2NjY3LCAwLCAwIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiBmaWxsPSIjZGRkIiBmaWxsLW9wYWNpdHk9IjAuMDIiIHN0cm9rZS13aWR0aD0iMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjcuODI5MjY3ODg5NTY1LCAyMC40OTU5MzQ1NTYyMzIpIiAvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDIwLjQ5NTkzNDU1NjIzMiwgMTEuODMzMzMzMzMzMzMzLCAwLCAyMy42NjY2NjY2NjY2NjcsIDAsIDAiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xMDY2NjY2NjY2NjY2NyIgc3Ryb2tlLXdpZHRoPSIxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NC4xNjI2MDEyMjI4OTgsIDIwLjQ5NTkzNDU1NjIzMikgc2NhbGUoLTEsIDEpIiAvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDIwLjQ5NTkzNDU1NjIzMiwgMTEuODMzMzMzMzMzMzMzLCAwLCAyMy42NjY2NjY2NjY2NjcsIDAsIDAiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xMDY2NjY2NjY2NjY2NyIgc3Ryb2tlLXdpZHRoPSIxIiB0cmFuc2Zvcm09InRyYW5zbG
 F0ZSg2Ny44MjkyNjc4ODk1NjUsIDEwOC44MjExMzcwMDIwMykgc2NhbGUoMSwgLTEpIiAvPjxwb2x5bGluZSBwb2ludHM9IjAsIDAsIDIwLjQ5NTkzNDU1NjIzMiwgMTEuODMzMzMzMzMzMzMzLCAwLCAyMy42NjY2NjY2NjY2NjcsIDAsIDAiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4wNDYiIHN0cm9rZS13aWR0aD0iMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDQuMTYyNjAxMjIyODk4LCAxMDguODIxMTM3MDAyMDMpIHNjYWxlKC0xLCAtMSkiIC8+PHBvbHlsaW5lIHBvaW50cz0iMCwgMCwgMjAuNDk1OTM0NTU2MjMyLCAxMS44MzMzMzMzMzMzMzMsIDAsIDIzLjY2NjY2NjY2NjY2NywgMCwgMCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgZmlsbD0iI2RkZCIgZmlsbC1vcGFjaXR5PSIwLjE0MTMzMzMzMzMzMzMzIiBzdHJva2Utd2lkdGg9IjEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExLjgzMzMzMzMzMzMzMywgNTIuODI1MjAyNDQ1Nzk3KSIgLz48cG9seWxpbmUgcG9pbnRzPSIwLCAwLCAyMC40OTU5MzQ1NTYyMzIsIDExLjgzMzMzMzMzMzMzMywgMCwgMjMuNjY2NjY2NjY2NjY3LCAwLCAwIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1vcGFjaXR5PSIwLjAyIiBmaWxsPSIjMjIyIiBmaWxsLW9wYWNpdHk9IjAuMDQ2IiBzdHJva2Utd2lkdGg9IjEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwMC4xNTg1MzU3NzkxMywgNTIuODI
 1MjAyNDQ1Nzk3KSBzY2FsZSgtMSwgMSkiIC8+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xNDEzMzMzMzMzMzMzMyIgc3Ryb2tlLXdpZHRoPSIxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMS44MzMzMzMzMzMzMzMsIDExLjgzMzMzMzMzMzMzMykgcm90YXRlKC0zMCwgMCwgMCkiIC8+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4xNDEzMzMzMzMzMzMzMyIgc3Ryb2tlLXdpZHRoPSIxIiB0cmFuc2Zvcm09InNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTEwMC4xNTg1MzU3NzkxMywgMTEuODMzMzMzMzMzMzMzKSByb3RhdGUoLTMwLCAwLCAwKSIgLz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMjMuNjY2NjY2NjY2NjY3IiBoZWlnaHQ9IjIzLjY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjAyODY2NjY2NjY2NjY2NyIgc3Ryb2tlLXdpZHRoPSIxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMS44MzMzMzMzMzMzMzMsIDI5LjE1ODUzNTc3OTEzKSByb3RhdGUo
 MzAsIDAsIDIzLjY2NjY2NjY2NjY2NykiIC8+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wNTQ2NjY2NjY2NjY2NjciIHN0cm9rZS13aWR0aD0iMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSwgMSkgdHJhbnNsYXRlKC0xMDAuMTU4NTM1Nzc5MTMsIDI5LjE1ODUzNTc3OTEzKSByb3RhdGUoMzAsIDAsIDIzLjY2NjY2NjY2NjY2NykiIC8+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xMzI2NjY2NjY2NjY2NyIgc3Ryb2tlLXdpZHRoPSIxIiB0cmFuc2Zvcm09InNjYWxlKDEsIC0xKSB0cmFuc2xhdGUoMTEuODMzMzMzMzMzMzMzLCAtMTAwLjE1ODUzNTc3OTEzKSByb3RhdGUoMzAsIDAsIDIzLjY2NjY2NjY2NjY2NykiIC8+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiNkZGQiIGZpbGwtb3BhY2l0eT0iMC4wODkzMzMzMzMzMzMzMzMiIHN0cm9rZS13aWR0aD0iMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSwgL
 TEpIHRyYW5zbGF0ZSgtMTAwLjE1ODUzNTc3OTEzLCAtMTAwLjE1ODUzNTc3OTEzKSByb3RhdGUoMzAsIDAsIDIzLjY2NjY2NjY2NjY2NykiIC8+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjIzLjY2NjY2NjY2NjY2NyIgaGVpZ2h0PSIyMy42NjY2NjY2NjY2NjciIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuMDIiIGZpbGw9IiMyMjIiIGZpbGwtb3BhY2l0eT0iMC4xNSIgc3Ryb2tlLXdpZHRoPSIxIiB0cmFuc2Zvcm09InNjYWxlKDEsIC0xKSB0cmFuc2xhdGUoMTEuODMzMzMzMzMzMzMzLCAtMTE3LjQ4MzczODIyNDkzKSByb3RhdGUoLTMwLCAwLCAwKSIgLz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMjMuNjY2NjY2NjY2NjY3IiBoZWlnaHQ9IjIzLjY2NjY2NjY2NjY2NyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utb3BhY2l0eT0iMC4wMiIgZmlsbD0iIzIyMiIgZmlsbC1vcGFjaXR5PSIwLjA0NiIgc3Ryb2tlLXdpZHRoPSIxIiB0cmFuc2Zvcm09InNjYWxlKC0xLCAtMSkgdHJhbnNsYXRlKC0xMDAuMTU4NTM1Nzc5MTMsIC0xMTcuNDgzNzM4MjI0OTMpIHJvdGF0ZSgtMzAsIDAsIDApIiAvPjwvc3ZnPg==); background-size:128px 128px; }</style><div class='plugin-icon' id='plugin-icon-<?php echo esc_attr( $post->post_name ); ?>' style='float:left; margin: 3px 6px 6px 0px;'></div></a>
+                <div class="name column-name">
+                        <h4><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h4>
+                </div>
+               <div class="desc column-description">
+                       <p><?php the_excerpt(); ?></p>
+                       <p class="authors"><?php echo wporg_plugins_template_authors(); ?></p>
+               </div>
+       </div>
+
+       <div class="plugin-card-bottom">
+               <!-- <div class="vers column-rating">
+                       <div class='wporg-ratings' title='4 out of 5 stars' style='color:#ffb900;'><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-empty"></span></div><span class="num-ratings" title="Rating based on 813 reviews">(813)</span>
+               </div> -->
+               <div class="column-updated">
+                       <strong><?php _e( 'Last Updated:', 'wporg-plugins' ); ?></strong> <?php echo wporg_plugins_template_last_updated(); ?>
+               </div>
+               <div class="column-installs">
+                       <?php echo worg_plugins_template_active_installs( true ); ?>
+               </div>
+               <div class="column-compatibility">
+                       <strong><?php _e( 'Compatible up to:', 'wporg-plugins' ); ?></strong> <?php echo wporg_plugins_template_compatible_up_to(); ?>
+               </div>
+       </div>
+</div>
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/plugin-card.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginssinglepluginphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/single-plugin.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/single-plugin.php                               (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/single-plugin.php 2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,71 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php the_post(); ?>
+<?php get_header(); ?>
+
+<div class="wrapper">
+
+       <div style="width: 772px; margin: 0 auto;" itemscope itemtype="http://schema.org/SoftwareApplication">
+       
+               <div id="plugin-head" class="plugin-head-with-banner">
+               
+                       <div id="plugin-title" class="with-banner">
+                               <div class="vignette"></div>
+                               <style type="text/css">
+                               #plugin-title { width:772px; height:250px; background-size:772px 250px; background-image: url(//ps.w.org/debug-bar/assets/banner-772x250.png?rev=478338); }
+                               </style>
+
+                               <h2 itemprop="name"><?php the_title(); ?></h2>
+                       </div>
+
+                       <div id="plugin-description">
+                               <p itemprop="description" class="shortdesc"><?php the_excerpt(); ?></p>
+                               <div class="description-right">
+                                       <p class="button">
+                                               <a itemprop='downloadUrl' href='<?php echo esc_url( wporg_plugins_download_link() ); ?>'><?php printf( __( 'Download Version %s', 'wporg-plugins' ), wporg_plugins_the_version() ); ?></a>
+                                       </p>
+                                       <meta itemprop="softwareVersion" content="<?php echo esc_attr( wporg_plugins_the_version() ); ?>" />
+                                       <meta itemprop="fileFormat" content="application/zip" />
+                               </div>
+                       </div>
+
+                       <div style="width: 552px; float: left">
+                               <div id="plugin-info" class="block description">
+                                       <div class="head head-big">
+                                               <ul id="sections">
+                                                       <?php
+                                                       foreach ( Plugin_Directory_Template_Helpers::get_plugin_sections() as $section ) {
+                                                               $current = ( $section['slug'] == get_query_var( 'content_page' ) || ( 'description' == $section['slug'] && ! get_query_var( 'content_page' ) ) );
+                                                               printf(
+                                                                       '<li class="%s"><a itemprop="url" href="%s">%s</a></li>',
+                                                                       'section-' . $section['slug'] . ( $current ? ' current' : '' ),
+                                                                       $section['url'],
+                                                                       $section['title']
+                                                               );
+                                                       }
+                                                       ?>
+                                               </ul>
+                                       </div>
+
+                                       <div class="block-content">
+                                               <?php the_content(); ?>
+                                       </div>
+                               </div>
+                       </div>
+
+                       <div class="" style="width: 212px; float: right;">
+                               <p>
+                                       <strong>Requires:</strong> <?php printf( __('%s or higher', 'wporg-plugins' ), wporg_plugins_template_requires() ); ?><br />
+                                       <strong>Compatible up to:</strong> <?php echo wporg_plugins_template_compatible_up_to(); ?><br />
+                                       <strong>Last Updated: </strong> <?php echo wporg_plugins_template_last_updated(); ?><br />
+                                       <strong>Active Installs:</strong> <?php echo worg_plugins_template_active_installs( false ); ?><br />
+                                       <meta itemprop="dateModified" content="<?php the_time('Y-m-d'); ?>" />
+                               </p>
+                       </div>
+
+               </div>
+
+       </div>
+</div>
+
+<br class="clear" />
+<?php
+get_footer();
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/single-plugin.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsstylecss"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/style.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/style.css                               (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/style.css 2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,1444 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/*
+ * Theme Name: WordPress.org Plugins (Temporary theme)
+ * Theme URI: https://wordpress.org/plugins
+ * Author: wordpressdotorg
+ * Author URI: https://wordpress.org
+ * Description: Theme for the WordPress.org plugins directory
+ * Version: 0.1-alpha
+ * License: GNU General Public License v2 or later
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
+ * Template: wordpress-wordblog
+*/
+
+body {
+       font-family: "Open Sans", sans-serif;
+}
+
+.error {
+       background-color: #fdd;
+       border: 1px solid #c66;
+       padding: 8px;
+}
+
+.info-marker {
+       color: #555;
+}
+
+#wporg-footer, #footer, #doily {
+       clear: both;
+}
+
+.right {
+       float: right !important;
+
+}
+
+.left {
+       float: left !important;
+}
+
+h4.plugin-tags, ul.column-list { position: relative; }
+
+ul.column-list a.more { right: 3ex; }
+
+#content p a { border-bottom: none; }
+
+h3#count {
+       font: 1em/25px Georgia,"Bitstream Vera Serif","Times New Roman",serif;
+       letter-spacing: 1px;
+       text-transform: uppercase;
+       font-weight: normal;
+       color: #888;
+       float: left;
+}
+
+h3#count strong {
+       font-size: 1.4em;
+       font-weight: normal;
+       color: #000;
+}
+
+#plugins-search {
+       margin-top: 11px;
+}
+
+#plugins-search input.text {
+       width: 300px;
+       font-size: 12px;
+}
+
+#plugins-search label input {
+       margin: 0 .4em;
+       vertical-align: middle;
+}
+
+#side-search {
+       margin: -10px 0 22px;
+       width: 100%;
+       obackground-color: #eee;
+}
+
+#side-search div {
+       padding: 5px 0 0;
+}
+
+#side-search input.text {
+       font-size: 12px;
+       height: 2em;
+       width: 100%;
+       -moz-box-sizing: border-box;
+       -webkit-box-sizing: border-box;
+       box-sizing: border-box;
+       obackground-color: #fff;
+}
+
+#side-search input.button {
+       float: right;
+       margin-top: 5px;
+}
+
+#plugin-info pre {
+       overflow: auto;
+       max-width: 525px;
+       clear: both;
+}
+
+.unmarked-list, .unmarked-list li {
+       text-indent: 0;
+       list-style: none;
+       margin-left: 0;
+}
+
+body #plugin-info .unmarked-list { padding: 0 0 0 2ex; }
+
+#pagebody h2 {
+       font-size: 18px;
+       line-height: 1.2em;
+       color: #333;
+       font-weight: bold;
+       margin-bottom: 11px;
+}
+
+.block h3.head {
+       color: #444;
+       font-weight: bold;
+       height: 12px;
+       line-height: 1;
+       padding: 8px 12px;
+       font-size: 12px !important;
+       margin-bottom: 12px;
+}
+
+.column .head {
+       font-size: 18px;
+       line-height: 1;
+       margin: 1em 0 .5em;
+       padding: 0;
+}
+
+.chart object {
+       margin-left: -18px;
+}
+
+div.column h3.head a, div.column h3.head a:hover span {
+       color: #2D2D2D;
+}
+div.column h3.head a:hover {
+       color: #036;
+       text-decoration: underline;
+}
+div.column h3.head a span {
+       color: #036;
+       font-weight: bold;
+}
+
+/* Blocks */
+
+.block-content {
+       margin-bottom: 2em;
+}
+
+.block-content h4 {
+       border: none !important;
+       margin-bottom: 0;
+       padding-bottom: 0;
+       font-size: 14px;
+}
+
+.block-content .button {
+       font-weight: normal !important;
+       float: right;
+       margin-top: -17px;
+}
+
+.block-content .button a {
+       font-weight: normal !important;
+}
+
+/* Columns */
+
+ul.column-list {
+       list-style: square;
+       font-size: 12px;
+}
+
+/* Buttons */
+
+div.button-holder {
+       position: relative;
+       height: 28px;
+}
+
+div.button-holder-l {
+       height: 48px;
+}
+
+span.btn-s {
+       background: url("btn-s-r.gif") top right no-repeat;
+       width: 80px;
+       float: left;
+       margin-right: 4px;
+}
+
+span.btn-s a {
+       background: url("btn-s-l.gif") top left no-repeat;
+       height: 20px;
+       line-height: 19px;
+}
+
+span.btn-m {
+       background: url("btn-m-r.gif") top right no-repeat;
+}
+
+span.btn-m a {
+       background: url("btn-m-l.gif") top left no-repeat;
+       height: 28px;
+       line-height: 27px;
+}
+
+span.btn-l {
+       background: url("btn-l-r.gif") top right no-repeat;
+}
+
+span.btn-l a {
+       background: url("btn-l-l.gif") top left no-repeat;
+       height: 48px;
+       font-size: 14px;
+       line-height: 47px;
+}
+
+/* Featured */
+
+#featured {
+       background-color: #fffeeb;
+       border-top: 1px solid #d9d8c8;
+       border-bottom: 1px solid #d9d8c8;
+}
+
+#featured .head {
+       background-color: #f2f1df;
+}
+
+#featured h4, #featured h4 a {
+       font-size: 26px;
+       font-weight: normal;
+}
+
+/* Plugin Info */
+.col-10 .col-3 {
+       margin: 0 0 0 28px;
+}
+#plugin-title {
+       position: relative;
+       margin: 0;
+}
+#plugin-title.with-banner {
+       width: 772px;
+       height: 250px;
+}
+#plugin-title.with-banner div {
+       position: absolute;
+       left: 0;
+       right: 0;
+       bottom: 0;
+       padding: 20px 30px;
+       background: rgba( 0, 0, 0, 0.6 );
+}
+#plugin-title.with-banner .vignette {
+       top: 0;
+       background: transparent;
+       -webkit-box-shadow: inset 0 0 50px 4px rgba( 0, 0, 0, 0.2 ), inset 0 -1px 0 rgba( 0, 0, 0, 0.1 );
+       -moz-box-shadow: inset 0 0 50px 4px rgba( 0, 0, 0, 0.2 ), inset 0 -1px 0 rgba( 0, 0, 0, 0.1 );
+       box-shadow: inset 0 0 50px 4px rgba( 0, 0, 0, 0.2 ), inset 0 -1px 0 rgba( 0, 0, 0, 0.1 );
+}
+
+#plugin-title h2 {
+       font-family: "Helvetica Neue", sans-serif;
+       font-size: 24px;
+       font-weight: bold;
+}
+
+#plugin-title.with-banner h2 {
+       font-size: 30px;
+
+       max-width: 682px;
+       position: absolute;
+       left: 30px;
+       bottom: 20px;
+       padding: 8px 15px;
+       margin-bottom: 4px;
+
+       color: #fff;
+       background: rgba( 30, 30, 30, 0.9 );
+       text-shadow: 0 1px 3px rgba( 0, 0, 0, 0.4 );
+
+       -webkit-box-shadow: 0 0 30px rgba( 255, 255, 255, 0.1 );
+       -moz-box-shadow: 0 0 30px rgba( 255, 255, 255, 0.1 );
+       box-shadow: 0 0 30px rgba( 255, 255, 255, 0.1 );
+
+       -webkit-border-radius: 8px;
+       border-radius: 8px;
+}
+
+#plugin-description {
+       overflow: hidden;
+       padding: 30px 15px 55px 30px;
+       font-size: 16px;
+       line-height: 24px;
+       margin: 0 0 30px;
+       background: #eee;
+       border-top: 1px solid #fcfcfc;
+       text-shadow: 0 1px 1px #fff;
+       -webkit-box-shadow: inset 0 0px 42px 0px rgba( 100, 100, 100, 0.1 );
+       -moz-box-shadow: inset 0 0px 42px 0px rgba( 100, 100, 100, 0.1 );
+       box-shadow: inset 0 0px 42px 0px rgba( 100, 100, 100, 0.1 );
+}
+
+#plugin-description .shortdesc {
+       width: 480px;
+       float: left;
+       margin-bottom: 0;
+       font-family: Georgia,"Bitstream Vera Serif","Times New Roman",serif;
+}
+
+#plugin-description p.button,
+body.trac .description-right p,
+.col-3 p.button {
+       display: block;
+       text-align: center;
+       padding: 0 12px;
+       background: #d54e21;
+       color: #fff;
+       -moz-border-radius: 3px;
+       border-radius: 3px;
+       border: none;
+}
+
+#plugin-description p.button a,
+body.trac .description-right p a,
+.col-3 p.button a {
+       font-size: 15px;
+       color: #fff;
+       display: block;
+       text-shadow: rgba(0,0,0,0.5) 0 1px 0;
+}
+
+p.button a:hover {
+       color: #ffac90;
+       border: none;
+}
+
+body.trac #plugin-description p,
+#plugin-description p.button {
+       float: right;
+       min-width: 182px;
+       margin-top: -8px;
+       margin-bottom: 0;
+}
+
+#plugin-info {
+       margin-top: -70px;
+       margin-bottom: 25px;
+}
+
+#plugin-info .head-big {
+       overflow: hidden;
+       width: 743px;
+       height: 30px;
+       padding: 10px 0 0 29px;
+       margin-bottom: 29px;
+}
+
+#plugin-info.theme-info .head-big {
+       background-color: #eee;
+       height: 35px;
+       padding: 0 0 0 6px;
+       margin-bottom: 12px;
+       width: 100%;
+}
+
+#plugin-info.theme-info {
+       margin-top: 10px;
+       width: auto;
+}
+
+#plugin-info ul#sections {
+       margin: 0;
+       padding: 0;
+       list-style: none;
+       text-indent: 0;
+}
+
+#plugin-info.theme-info ul#sections {
+       margin: 5px 0 0;
+}
+
+#plugin-info ul#sections li {
+       font-size: 13px;
+       line-height: 1;
+       display: block;
+       float: left;
+       padding: 8px 8px 9px;
+       margin: 0;
+}
+
+#plugin-info ul#sections li.current {
+       padding-top: 7px;
+       background-color: #fff;
+
+       border-style: solid;
+       border-width: 1px 1px 0 1px;
+       border-color: #d7d7d7;
+
+       -webkit-box-shadow: 0 0 8px 0px rgba( 100, 100, 100, 0.12 );
+       -moz-box-shadow: 0 0 8px 0px rgba( 100, 100, 100, 0.12 );
+       box-shadow: 0 0 8px 0px rgba( 100, 100, 100, 0.12 );
+
+       -webkit-border-top-left-radius: 3px;
+       -webkit-border-top-right-radius: 3px;
+       border-top-left-radius: 3px;
+       border-top-right-radius: 3px;
+}
+
+#plugin-info h4, #plugin-info h3 {
+       color: #111;
+       font-weight: bold;
+       margin-top: 1.5em;
+}
+
+#plugin-info h4 {
+       font-size: 14px;
+       margin: 0;
+}
+
+#plugin-info h4.author {
+       margin: 0 0 12px;
+       border-bottom: none;
+}
+
+#plugin-info.frequently-asked-questions h4, #plugin-info h3 {
+       font-size: 16px;
+}
+
+#plugin-info .block-content, #plugin-info .block-content p {
+       clear: left;
+       font-size: 13px;
+}
+
+#plugin-tags,
+#theme-languages {
+       font-size: 12px;
+       margin: 16px 0;
+}
+
+/* FYI */
+
+#fyi {
+       margin-bottom: 1em;
+}
+
+#fyi .head {
+       padding-left: 0;
+}
+
+#fyi .block-content {
+       font-size: 12px;
+       padding-top: 0;
+}
+
+#fyi ul {
+       list-style: none;
+       padding-bottom: 12px;
+}
+
+#fyi ul li {
+       text-indent: -16px;
+       font-size: 12px;
+       width: 175px;
+}
+
+#fyi ul li.plugin-avatars {
+       text-indent:0px;
+       margin:0 0 0 -9px;
+       padding:0;
+}
+
+.plugin-avatars a img {
+       padding: 0 3px;
+}
+
+.col-3 .postform h3 {
+       font-size: 12px;
+       padding-bottom: 5px;
+       margin-bottom: 10px;
+       border-bottom: 1px solid #dadada;
+}
+
+.col-3 .postform ol li {
+       line-height: 1.6em;
+       font-size: 12px;
+}
+
+.col-3 .postform p {
+       font-size: 10px;
+       line-height: 1.6em;
+       padding-bottom: 22px;
+}
+
+/* Tag and Author Pages */
+div.plugin-block {
+       margin: .5em 0 0;
+}
+
+div.plugin-block h3 {
+       margin-top: 1em;
+}
+
+div.plugin-block p {
+       padding: 0;
+       margin: 0 0 .5em;
+}
+
+div.plugin-block ul.plugin-meta {
+       list-style: none !important;
+       font-size: 12px;
+       line-height: 1;
+       color: #111;
+       margin: .4em 0 0 !important;
+       height: 19px;
+       padding: 0;
+}
+
+div.plugin-block ul.plugin-meta li {
+       float: left;
+       margin: 0 8px 0 0 !important;
+       text-indent: 0;
+       min-height: 19px;
+}
+
+div.plugin-block div.star-holder {
+       float: left;
+       margin: -3px 0 0 .5ex;
+}
+
+/* Tags Page */
+#hottags {
+       font-family: Georgia,"Bitstream Vera Serif","Times New Roman",serif;
+       margin: 2em 0 0;
+       text-align: justify;
+       line-height: 2em;
+}
+
+#hottags a {
+       font-weight: normal;
+}
+
+div#sidebar h3 {
+       position: relative;
+}
+div#sidebar h3 a {
+       font-weight: bold;
+}
+div#sidebar div ul {
+       border-bottom: none;
+}
+
+div#history {
+       width: 150px;
+       margin-left: 20px;
+       margin-bottom: 22px;
+}
+div#history table {
+       width: 150px;
+       border-collapse:collapse;
+       border-spacing:0;
+}
+div#history table * {
+       text-align: left;
+}
+div#history table tr {
+       border-bottom: 1px solid #ccc;
+}
+div#history table th {
+       font-size: 0.8em;
+       color: #666;
+       font-weight: normal;
+}
+div#history table td {
+       font-weight: bold;
+}
+div#history table th, div#history table td {
+       padding: 5px 0;
+}
+div#history table tr.last-child {
+       border-bottom: none;
+}
+#related {
+       clear: both;
+       border-top: 1em solid #fff;
+}
+#related ul {
+       font-size: 0.9em;
+       padding: 0 0 0 18px;
+}
+#related ul li {
+       margin: 0;
+}
+
+ol.screenshots {
+       clear: both;
+       list-style: none;
+       margin: 0 !important;
+       padding: 0;
+}
+ol.screenshots li {
+       padding-bottom: 35px;
+}
+ol.screenshots li img {
+       border: 1px solid #dadada;
+}
+ol.screenshots li p {
+       margin: 0 !important;
+       padding: 0;
+       font: italic 0.85em/1.4em "Lucida Sans", "Lucida Grande", Verdana, sans-serif !important;
+}
+
+#pagebody ul.translation-details {
+       margin-left: 0;
+}
+
+       .translation-details-row {
+               background-color: #f4f4f4;
+               list-style: none outside none;
+               padding: 15px 20px 12px 20px;
+       }
+
+               .translation-details-row-alternate {
+                       background-color: inherit;
+               }
+
+/* Get Hosted */
+
+div#get-hosted {
+       clear: both;
+       background-color: #EDEDFF;
+       border-top: 1.5em solid #fff;
+}
+
+div#get-hosted h3.head {
+       border-top: 1px solid #CACAD9;
+       background-color: #E1E1F2;
+}
+
+/* Change site-wide stuff */
+
+form .alt { background: #eee }
+
+#thread li.alt {
+       border-top: 1px solid #ccc;
+       border-bottom: 1px solid #ccc;
+}
+
+#thread { background-color: #fff; }
+
+#thread li { padding: 1em .8em }
+
+.threadauthor{
+       position: static;
+       width: auto;
+       overflow: visible;
+}
+
+
+/* About */
+
+#about h3 {
+       font-size: 22px;
+}
+
+#about code { background-color: transparent; color: #000; }
+
+#about th[scope=row] { text-align: left; }
+
+.prompt { color: green; }
+.comment { color: maroon; }
+.stdout { color: #222; }
+
+dl dt { color: #000; }
+dl dd { margin-bottom: 1em; }
+
+
+#admin {
+       background-color: #FFEBFE;
+       border-top: 1px solid #D9C8D8;
+}
+
+#admin h3.head {
+       background-color: #F2DFF1;
+}
+
+#admin-forums {
+       border-collapse: collapse;
+}
+
+#admin-forums .alt {
+       background-color: transparent;
+}
+
+#admin-forums .num {
+       text-align: right;
+}
+
+#admin-forums th, #admin-forums td {
+       padding: 0 12px;
+}
+
+div.has-plugins {
+       background-color: #FFC0CB;
+}
+
+div.alt.has-plugins {
+       background-color: #FFB6C1;
+}
+
+div.emailed-author {
+       background-color: #FFCC99;
+}
+div.alt.emailed-author {
+       background-color: #FFCC66;
+}
+
+div.pending textarea {
+       width: 529px;
+       margin: 0 8px 8px;
+}
+
+.video {
+       margin: 0 0 22px;
+       text-align: center;
+}
+
+.tc-warning, .tc-required, .tc-fail {
+       color:red;
+}
+
+.tc-recommended, .tc-pass {
+       color: green;
+}
+
+.tc-info {
+       color: blue;
+}
+
+@media screen and (max-width:960px) {
+    #sidebar {
+       display:none;
+    }
+       .col-10, .col-10 .col-3 {
+               -moz-box-sizing: border-box;
+               -webkit-box-sizing: border-box;
+               box-sizing: border-box;
+               width: 100%;
+               margin: 5px 0;
+               padding: 0 15px;
+       }
+       .col-7 {
+               width: 100%;
+       }
+       .plugin-head-with-banner {
+               background-color: #eee;
+       }
+       #plugin-title.with-banner {
+               margin: 0 auto;
+               width: 100%;
+               max-width: 772px;
+               background-size: 100%;
+               height: 0;
+               padding-bottom: 32%;
+               font-size: 20px;
+       }
+       #plugin-title.with-banner h2 {
+               font-size: 20px;
+               line-height: 1em;
+               bottom: 4%;
+               left: 3%;
+       }
+       #pagebody .col-2 > .submenu:nth-of-type(2) {
+               overflow: hidden;
+       }
+       #pagebody .col-2 .submenu:nth-of-type(2) li {
+               display: block;
+               width: 50%;
+               float: left;
+       }
+       .plugin-authors > div {
+               display: block;
+               float: left;
+               width: 50%;
+               margin-bottom: 8px;
+       }
+       #plugin-info .head-big {
+               overflow: hidden;
+               width: 100%;
+               height: auto;
+               padding: 10px 0 0;
+               margin-bottom: 29px;
+               background: #eee;
+               -webkit-box-shadow: inset 0px -20px 32px 0px rgba( 100, 100, 100, 0.1 );
+               -moz-box-shadow: inset 0px -20px 32px 0px rgba( 100, 100, 100, 0.1 );
+               box-shadow: inset 0px -20px 32px 0px rgba( 100, 100, 100, 0.1 );
+       }
+
+       #plugin-description .shortdesc {
+               width: 100%;
+       }
+
+       body.trac #plugin-description p, #plugin-description p.button {
+               margin-top:0;
+       }
+}
+
+@media screen and (min-width:810px) and (max-width:960px) {
+       #plugin-title.with-banner {
+               height: 250px;
+               padding-bottom: 0;
+       }
+}
+
+@media screen and (max-width:620px) {
+       #plugin-title.with-banner {
+               margin-bottom: 2em;
+       }
+       #plugin-title.with-banner h2 {
+               -moz-box-sizing: border-box;
+               -webkit-box-sizing: border-box;
+               box-sizing: border-box;
+               min-height: 2em;
+               width: 100%;
+               font-size: 20px;
+               bottom: -2em;
+               left: 0;
+               margin: 0;
+               -webkit-border-radius: 0;
+               border-radius: 0;
+       }
+}
+
+@media screen and (max-width:530px) {
+       .video iframe {
+               width:100%;
+       }
+}
+
+@media screen and (max-width:460px) {
+    #headline .login {
+       width: 91.35%;
+    }
+    #headline .login label {
+       padding:0 0 10px;
+    }
+}
+
+@media screen and (max-width:400px) {
+    #headline .login label {
+      display:block;
+    }
+}
+
+/* New theme styles. */
+
+body.plugins-directory {
+       background: #f1f1f1;
+}
+body.plugins-directory.topic-page, body.plugins-directory.page, body.plugins-directory.forum-page {
+       background: #fff;
+}
+body.plugins-directory #pagebody {
+       margin-top: 0;
+}
+
+.col-12 {
+       width: 940px;
+       margin: 0 10px;
+}
+#pagebody p.intro {
+       font-family: inherit;
+       text-align: center;
+}
+#sidebar h4 {
+       margin-top: 20px;
+}
+#sidebar h4:first-child {
+       margin-top: 0;
+}
+/* Hide visually but not from screen readers */
+.screen-reader-text,
+.screen-reader-text span {
+       position: absolute;
+       margin: -1px;
+       padding: 0;
+       height: 1px;
+       width: 1px;
+       overflow: hidden;
+       clip: rect(0 0 0 0);
+       border: 0;
+}
+
+/* Plugin card table view */
+.plugin-pagination {
+       text-align: right;
+}
+.plugin-pagination .plugin-pagination-showing {
+       float: left;
+       font-weight: bold;
+}
+.plugin-group {
+       overflow: hidden; /* clearfix */
+       width: 100%;
+       margin-top: 1.5em;
+       display: table;
+}
+
+.plugin-group h3 {
+       margin-top: 0;
+}
+#pagebody .plugin-card p {
+       margin: 0 0 10px 0;
+}
+.plugin-card {
+       float: left;
+       margin: 0 8px 16px;
+       width: 48.5%;
+       width: -webkit-calc( 50% - 8px );
+       width: calc( 50% - 8px );
+       background-color: #fff;
+       border: 1px solid #dedede;
+       -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+       box-sizing: border-box;
+       display: table-row;
+}
+.plugin-card:nth-child(odd) {
+       clear: both;
+       margin-left: 0;
+}
+
+.plugin-card:nth-child(even) {
+       margin-right: 0;
+}
+
+@media screen and ( max-width: 976px ) {
+       .col-12.filter-bar {
+               width: 100%;
+               margin: 0;
+       }
+
+       .col-12.filter-bar .wp-filter {
+               border-left: 0;
+               border-right: 0;
+               padding-left: 0;
+       }
+
+       #pagebody p {
+               padding-left: 9px;
+       }
+}
+@media screen and ( max-width: 940px ) {
+       .col-12 {
+               width: 100%;
+               margin: 0;
+       }
+}
+@media screen and ( max-width: 782px ) {
+       .plugin-card {
+               margin-left: 0;
+               margin-right: 0;
+               width: 100%;
+       }
+}
+
+.plugin-card-top {
+       position: relative;
+       padding: 20px 20px 10px;
+       min-height: 135px;
+}
+
+.plugin-card h4 {
+       font-weight: 600;
+       border: 0;
+       margin: 0 0 12px;
+       font-size: 18px;
+       line-height: 1.3;
+}
+.plugin-card a {
+       border: 0;
+}
+.plugin-card .name,
+.plugin-card .desc {
+       margin-left: 148px; /* icon + margin */
+       margin-right: 120px; /* action links */
+       margin-right: inherit;
+       word-break: break-word;
+}
+
+.plugin-card-bottom {
+       clear: both;
+       padding: 12px 20px;
+       background-color: #fafafa;
+       border-top: 1px solid #dedede;
+       overflow: hidden;
+}
+
+.plugin-card-bottom .wporg-ratings {
+       display: inline;
+}
+
+.plugin-card .column-rating {
+       line-height: 23px;
+}
+
+.plugin-card .column-rating,
+.plugin-card .column-updated {
+       margin-bottom: 4px;
+}
+
+.plugin-card .column-rating,
+.plugin-card .column-installs {
+       float: left;
+       clear: left;
+       max-width: 160px;
+}
+
+.plugin-card .column-updated,
+.plugin-card .column-compatibility {
+       text-align: right;
+       float: right;
+       clear: right;
+       width: 65%;
+       width: -webkit-calc( 100% - 160px );
+       width: calc( 100% - 160px );
+}
+.plugin-card .column-compatibility span:before {
+       font: normal 20px/.5 'dashicons';
+       speak: none;
+       display: inline-block;
+       padding: 0;
+       top: 4px;
+       left: -2px;
+       position: relative;
+       vertical-align: top;
+       -webkit-font-smoothing: antialiased;
+       -moz-osx-font-smoothing: grayscale;
+       text-decoration: none !important;
+       color: #444;
+}
+
+.plugin-card .compatibility-incompatible:before {
+       content: '\f158';
+}
+
+.plugin-card .compatibility-compatible:before {
+       content: '\f147';
+}
+
+.plugin-card .compatibility-untested strong {
+       font-weight: normal;
+}
+.plugin-icon {
+       position: absolute;
+       top: 20px;
+       left: 20px;
+       width: 128px;
+       height: 128px;
+       margin: 0 20px 20px 0;
+       top: 10px;
+       left: 10px;
+}
+
+.plugin-icon img {
+       width: 128px;
+       height: 128px;
+}
+
+.no-plugin-results {
+       color: #999;
+       font-size: 18px;
+       font-style: normal;
+       margin: 0;
+       padding: 30px 0 20px;
+       text-align: center;
+}
+@media screen and ( max-width: 1100px ) and ( min-width: 782px ), ( max-width: 480px ) {
+       .plugin-card .name,
+       .plugin-card .desc {
+               margin-right: 0;
+       }
+
+       .plugin-card .desc p:first-of-type {
+               margin-top: 0;
+       }
+}
+
+
+/* Filter bar */
+.wp-filter {
+       display: inline-block;
+       position: relative;
+       -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+       box-sizing: border-box;
+       margin: 12px 0 25px;
+       padding: 0 20px;
+       width: 100%;
+       -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
+       box-shadow: 0 1px 1px rgba(0,0,0,0.04);
+       border: 1px solid #e5e5e5;
+       background: #fff;
+       color: #555;
+       font-size: 13px;
+}
+
+.wp-filter a {
+       text-decoration: none;
+}
+
+.wp-filter .plugin-install-beta {
+       padding-right: 15px;
+       border-right: 1px solid #e5e5e5;
+       margin-right: 15px;
+}
+body.search-page .wp-filter .plugin-install-beta,
+body.tag-page .wp-filter .plugin-install-beta {
+       padding-right: 10px;
+       margin-right: 10px;
+}
+
+.filter-count {
+       display: inline-block;
+       vertical-align: middle;
+       min-width: 4em;
+}
+
+.title-count,
+.filter-count .count {
+       display: inline-block;
+       position: relative;
+       top: -1px;
+       padding: 4px 10px;
+       -webkit-border-radius: 30px;
+       border-radius: 30px;
+       background: #777;
+       color: #fff;
+       font-size: 14px;
+       font-weight: 600;
+}
+
+/* not a part of filter bar, but derived from it, so here for now */
+.title-count {
+       display: inline;
+       top: -3px;
+       margin-left: 5px;
+       margin-right: 20px;
+}
+
+#pagebody ul.filter-links {
+       display: inline-block;
+       margin: 0;
+}
+
+.filter-links li {
+       display: inline-block;
+       margin: 0;
+}
+
+.filter-links li > a {
+       display: inline-block;
+       margin: 0 10px;
+       padding: 15px 0;
+       border-bottom: 4px solid #fff;
+       color: #666;
+       cursor: pointer;
+}
+
+.filter-links .current {
+       -webkit-box-shadow: none;
+       box-shadow: none;
+       border-bottom: 4px solid #666;
+       color: #222;
+}
+
+.filter-links li > a:hover,
+.filter-links li > a:focus,
+.show-filters .filter-links a.current:hover,
+.show-filters .filter-links a.current:focus {
+       color: #2ea2cc;
+}
+
+.wp-filter .search-form {
+       float: right;
+       margin: 12px 0 11px;
+}
+
+.wp-filter .search-form input[type="search"] {
+       margin: 0;
+       padding: 3px 5px;
+       width: 280px;
+       font-size: 16px;
+       font-weight: 300;
+       line-height: 1.5;
+}
+body.search-page .wp-filter .search-form input[type="search"],
+body.tag-page .wp-filter .search-form input[type="search"] {
+       width: 240px;
+}
+
+.wp-filter .search-form select {
+       height: 33px;
+       vertical-align: top;
+
+       padding: 2px;
+       line-height: 28px;
+       font-size: 14px;
+       border-radius: 0;
+       border: 1px solid #ddd;
+       background-color: #fff;
+       color: #333;
+       outline: 0;
+       -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
+       box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
+       transition: .05s border-color ease-in-out;
+}
+
+.wp-filter .drawer-toggle {
+       display: inline-block;
+       margin: 0 10px;
+       padding: 4px 6px;
+       color: #666;
+       cursor: pointer;
+}
+
+.wp-filter .drawer-toggle:before {
+       display: inline-block;
+       vertical-align: top;
+       content: "\f111";
+       margin: 0 5px 0 0;
+       width: 16px;
+       height: 16px;
+       color: #777;
+       -webkit-transition: color .1s ease-in 0;
+       transition: color .1s ease-in 0;
+       font-family: "dashicons";
+       font-size: 16px;
+       line-height: 1;
+       text-align: center;
+       text-decoration: inherit;
+       font-weight: normal;
+       font-style: normal;
+       -webkit-font-smoothing: antialiased;
+}
+
+.wp-filter .drawer-toggle:hover,
+.wp-filter .drawer-toggle:hover:before {
+       color: #2ea2cc;
+}
+
+.wp-filter .drawer-toggle.current:before {
+       color: #fff;
+}
+
+.filter-drawer {
+       display: none;
+       margin: 0 -20px;
+       padding: 20px;
+       border-top: 1px solid #eee;
+       background: #fafafa;
+}
+
+.show-filters .filter-drawer {
+       display: block;
+       overflow: hidden;
+}
+
+.show-filters .wp-filter .drawer-toggle:hover,
+.show-filters .wp-filter .drawer-toggle:focus {
+       background: rgb(46, 162, 204);
+}
+
+.show-filters .filter-links a.current {
+       border-bottom: none;
+}
+
+.show-filters .wp-filter .drawer-toggle {
+       -webkit-border-radius: 2px;
+       border-radius: 2px;
+       border: none;
+       background: #777;
+       color: #fff;
+}
+
+.show-filters .wp-filter .drawer-toggle:before {
+       color: #fff;
+}
+
+.filter-group {
+       -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+       box-sizing: border-box;
+       float: left;
+       margin: 0 1% 0 0;
+       padding: 10px;
+       width: 19%;
+       background: #fff;
+       border: 1px solid #e5e5e5;
+       -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
+       box-shadow: 0 1px 1px rgba(0,0,0,0.04);
+}
+
+.filter-group.wide {
+       width: 38%;
+}
+
+.filter-group h4 {
+       position: relative;
+       margin: 0;
+}
+
+.filter-drawer ol {
+       margin: 20px 0 0;
+       list-style-type: none;
+       font-size: 12px;
+}
+
+.filter-drawer li {
+       display: inline-block;
+       vertical-align: top;
+       margin: 5px 0;
+       padding-right: 25px;
+       width: 160px;
+       list-style-type: none;
+}
+
+.filter-drawer .buttons {
+       margin-bottom: 20px;
+}
+
+.filter-drawer .buttons .button span {
+       display: inline-block;
+       opacity: 0.8;
+       font-size: 12px;
+       text-indent: 10px;
+}
+
+.wp-filter .button.clear-filters {
+       display: none;
+       margin: 0 0 20px 10px;
+}
+
+.filtered-by {
+       display: none;
+       margin: 0;
+}
+
+.filtered-by > span {
+       font-weight: 600;
+}
+
+.filtered-by a {
+       margin-left: 10px;
+}
+
+.filtered-by .tags {
+       display: inline;
+}
+
+.filtered-by .tag {
+       margin: 0 5px;
+       padding: 4px 8px;
+       border: 1px solid #e5e5e5;
+       -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
+       box-shadow: 0 1px 1px rgba(0,0,0,0.04);
+       background: #fff;
+       font-size: 11px;
+}
+
+.filters-applied .filter-group,
+.filters-applied .filter-drawer .buttons,
+.filters-applied .filter-drawer br {
+       display: none !important;
+}
+
+.filters-applied .filtered-by {
+       display: block;
+}
+
+.filters-applied .filter-drawer {
+       padding: 20px;
+}
+
+.show-filters .content-filterable,
+.show-filters.filters-applied.loading-content .content-filterable,
+.loading-content .content-filterable,
+.error .content-filterable {
+       display: none;
+}
+
+.show-filters.filters-applied .content-filterable {
+       display: block;
+}
+
+
+/* ------- */
+.wp-filter .actions {
+       display: inline-block;
+       vertical-align: middle;
+}
+.wp-filter .view-switch {
+       display: inline-block;
+       vertical-align: middle;
+       padding: 14px 0;
+       margin: 0 20px 0 0;
+}
+
+input[type=search] {
+       border: 1px solid #ddd;
+       -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
+       box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
+       background-color: #fff;
+       color: #333;
+       outline: 0;
+       -webkit-transition: .05s border-color ease-in-out;
+       transition: .05s border-color ease-in-out;
+       -webkit-appearance: textfield;
+}
+
+.nav.top {
+       text-align: right;
+}
+.nav.bottom {
+       margin: 10px 0 22px;
+       text-align: right;
+}
+
+.dots, .next, .prev {
+       background-color: inherit;
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/style.css
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginstemplatetagsphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/template-tags.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/template-tags.php                               (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/template-tags.php 2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,73 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+// Various Template tags
+
+// Returns an absolute url to the current url, no matter what that actually is.
+function wporg_plugins_self_link() {
+       $site_path = preg_replace( '!^' . preg_quote( parse_url( home_url(), PHP_URL_PATH ), '!' ) . '!', '', $_SERVER['REQUEST_URI'] );
+       return home_url( $site_path );
+}
+
+function wporg_plugins_template_last_updated() {
+       return '<span title="' . get_the_time('Y-m-d') . '">' . sprintf( _x( '%s ago', 'wporg-plugins' ), human_time_diff( get_the_time( 'U' ), current_time( 'timestamp' ) ) ) . '</span>';
+}
+
+function wporg_plugins_template_compatible_up_to() {
+       $tested = get_post_meta( get_the_id(), 'tested', true ) ;
+       if ( ! $tested ) {
+               $tested = _x( 'unknown', 'unknown version', 'wporg-plugins' );
+       }
+       return esc_html( $tested );
+}
+
+function wporg_plugins_template_requires() {
+       return esc_html( get_post_meta( get_the_id(), 'requires', true ) );
+}
+
+function wporg_plugins_the_version() {
+       return esc_html( get_post_meta( get_the_id(), 'version', true ) );
+}
+
+function wporg_plugins_download_link() {
+       $filename = sprintf( "%s.%s.zip", get_post()->post_name, wporg_plugins_the_version() );
+       return esc_url( "https://downloads.wordpress.org/plugin/{$filename}" );
+}
+
+function worg_plugins_template_active_installs( $full = true ) {
+       $count = Plugin_Directory_Template_Helpers::get_active_installs_count( get_post()->post_name );
+
+       if ( ! $count ) {
+               $text = __( 'Less than 10', 'wporg-plugins' );
+       } elseif ( $count >= 1000000 ) {
+               $text = __( '1+ million', 'wporg-plugins' );
+       } else {
+               $text = number_format_i18n( $count ) . '+';
+       }
+       return $full ? sprintf( __( '%s active installs', 'wporg-plugins' ), $text ) : $text;
+}
+
+function wporg_plugins_template_authors() {
+       $authors = get_post_meta( get_the_id(), 'contributors', true );
+
+       $author_links = array();
+       $and_more = false;
+       foreach ( $authors as $author ) {
+               $user = get_user_by( 'login', $author );
+               if ( ! $user ) {
+                       continue;
+               }
+               $author_links[] = sprintf( '<a href="%s">%s</a>', 'https://profiles.wordpress.org/' . $user->user_nicename . '/', $user->display_name );
+               if ( count( $author_links ) > 5 ) {
+                       $and_more = true;
+                       break;
+               }
+       }
+
+       if ( $and_more ) {
+               return sprintf( '<cite> By: %s, and others.</cite>', implode(', ', $author_links ) );
+       } else {
+               return sprintf( '<cite> By: %s</cite>', implode(', ', $author_links ) );
+       }
+}
+
+
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/template-tags.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpluginsviewintrophp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/view-intro.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/view-intro.php                          (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/view-intro.php    2016-02-13 03:38:51 UTC (rev 2499)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,19 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+if ( is_front_page() && ( ! get_query_var( 'browse' ) || 'featured' == get_query_var( 'browse' ) ) ) {
+               printf(
+                       /* translators: 1: Plugins count 2: Download count */
+                       '<p class="intro">' . __( 'Plugins extend and expand the functionality of WordPress. %1$s plugins with %2$s total downloads are at your fingertips.', 'wporg-plugins' ) . '</p>',
+                       '<strong>' . number_format_i18n( wp_count_posts( 'plugin' )->publish ) . '</strong>',
+                       '<strong>' . number_format_i18n( Plugin_Directory_Template_Helpers::get_total_downloads() ) . '</strong>'
+       );
+}
+
+if ( 'beta' == get_query_var( 'browse' ) ) {
+       echo '<p class="intro">' . __( 'The plugins listed here are proposed for a future version of WordPress. They are under active development.<br />You can try them out, provide feedback, or join one of the development teams.', 'wporg-plugins' ) . '</p>';
+} elseif ( 'favorites' == get_query_var( 'browse' ) ) {
+       echo '<p class="intro">' . sprintf(
+               __( 'Your favorite plugins are listed here. They also appear on <a href="%s">your profile</a>.', 'wporg-plugins' ),
+               'https://profiles.wordpress.org/' . wp_get_current_user()->user_nicename
+       ) . '</p>';
+}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-plugins/view-intro.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span></div>

</body>
</html>